4、人脸关键点定位:掌握68点/106点/468点关键点检测原理,以及如何用于头部姿态估计和眼部状态分析

人脸关键点定位是座舱DMS(Driver Monitoring System)感知链路中的核心环节。它解决的是“驾驶员面部各部件在哪里”的问题——不仅要找到眼睛、鼻子、嘴巴的粗略位置,还要精确到眼睑轮廓、瞳孔中心、眉脊线等亚像素级坐标。在DMS应用中,关键点定位的精度直接决定了疲劳检测(如PERCLOS)、分心检测(如视线方向)和头部姿态估计(Head Pose Estimation)的可靠性。本章将系统讲解68点、106点和468点三种主流关键点模型的原理差异、工程选型依据,以及如何基于关键点坐标计算头部姿态和眼部开合度。

DMS人脸关键点定位技术链路与核心应用 68点模型 轮廓17 + 眉10 + 眼12 鼻9 + 嘴20 经典方案 | 算力消耗低 适合嵌入式前视摄像头 106点模型 在68点基础上增加 眼周密集点 + 眉弓细节 国内车规方案主流 平衡精度与实时性 468点模型 MediaPipe密集网格 含眼球轮廓 + 唇部内沿 高精度 | 需NPU/GPU加速 适合高端座舱域控制器 统一输出:N×2关键点坐标 (x, y) + 置信度 经相似变换对齐后,送入下游任务模块 头部姿态估计 PnP求解旋转向量 输出Yaw/Pitch/Roll 用于分心/瞌睡判断 眼部状态分析 EAR眼纵横比计算 PERCLOS闭眼时长统计 疲劳等级判定 视线方向估计 瞳孔中心 + 眼球模型 结合头部姿态补偿 分心/注视区域判断 关键点定位质量直接影响下游所有DMS告警的准确率与延迟

上图展示了三种关键点模型到下游DMS任务的完整链路。在实际工程中,选择哪种模型并非越密越好,而是取决于芯片算力、摄像头安装位置、实时性要求以及算法鲁棒性。下面我们逐一深入剖析。

4.1 三种关键点模型的原理与工程选型

68点模型源自经典的dlib库和iBUG 300-W数据集,它将人脸划分为眉毛(5点×2)、眼睛(6点×2)、鼻子(9点)、嘴巴(20点)和脸部轮廓(17点)。其检测原理通常基于级联回归树(Ensemble of Regression Trees)或深度卷积网络(如Heatmap回归)。在DMS场景中,68点模型的优势在于计算量小,在ARM Cortex-A53级别的CPU上即可达到30fps以上。但其对眼部细节的刻画不足——每只眼睛只有6个点,当驾驶员佩戴墨镜或眼睛眯缝时,眼睑上下沿的拟合误差会显著增大。

106点模型是近年来国内车规级DMS方案(如地平线、芯驰、爱芯元智等平台)的主流选择。它在68点的基础上,将每只眼睛的点数增加到12个,额外补充了眉弓下沿和眼袋区域的采样点。106点模型通常采用轻量级HRNet或MobileFaceNet结构,通过Heatmap回归输出关键点坐标。相比68点,106点对眼部开合度的测量精度提升了约30%,且对侧脸姿态(Yaw角超过45°)的鲁棒性更好。其代价是模型参数量约为68点模型的1.8倍,但仍在车规级芯片的NPU算力范围内。

468点模型来自Google MediaPipe Face Mesh,它采用BlazeFace进行人脸检测,然后通过回归模型直接输出468个3D关键点(含深度信息)。该模型最大的特点是包含眼球轮廓(每只眼睛约16个点)和唇部内沿,能够精细刻画微表情。在DMS中,468点模型主要用于视线估计(Gaze Estimation)和微睡眠检测(Microsleep)。但需要注意,MediaPipe Face Mesh在PC和手机端表现优异,在车规级嵌入式平台上直接部署时,若没有GPU或NPU加速,很难达到实时性要求。此外,其3D关键点的深度信息在单目摄像头下存在尺度模糊问题,需要额外的标定补偿。

对比维度68点模型106点模型468点模型
关键点数量68106468(含3D深度)
眼部点数6点/眼12点/眼约16点/眼+眼球轮廓
典型算法级联回归/浅层CNNHRNet/轻量TransformerMediaPipe回归模型
计算量(MACs)约0.5G约1.2G约4.5G
车规级部署低端MCU即可需NPU或中端SoC需独立GPU/NPU
DMS适用性基础疲劳检测主流方案,精度/算力平衡高精度视线估计
选型建议:对于前装量产DMS,推荐以106点模型为基线。若芯片算力紧张(如仅有2 TOPS NPU),可降级到68点并配合图像金字塔提升眼部区域分辨率;若面向L3级自动驾驶的座舱域控制器(算力>10 TOPS),可考虑468点模型以获取更精准的视线方向。

4.2 基于关键点的头部姿态估计:PnP求解与工程实现

头部姿态估计的目标是计算驾驶员头部在三维空间中的旋转角度(Yaw偏航角、Pitch俯仰角、Roll滚转角)。其核心原理是透视n点投影(Perspective-n-Point, PnP):已知人脸关键点在图像中的2D坐标,以及对应的人脸标准3D模型坐标,通过求解相机外参(旋转矩阵R和平移向量t)来获得头部姿态。

具体操作流程如下:

  1. 建立3D人脸基准模型:选取鼻尖、下巴、左眼左角、右眼右角、嘴角左端、嘴角右端等6-8个关键点,赋予其在标准坐标系下的3D坐标(单位:毫米)。例如,鼻尖为(0,0,0),左眼左角为(-30,-20,10)等。
  2. 获取2D关键点坐标:从关键点检测网络输出中提取对应索引的2D像素坐标。
  3. 相机内参标定:使用座舱内摄像头的焦距(fx, fy)和主点(cx, cy)构建内参矩阵K。若无法精确标定,可使用近似值(如fx=fy=图像宽度,cx=宽度/2, cy=高度/2),但会引入约2-3°的姿态误差。
  4. 调用PnP求解器:使用OpenCV的cv2.solvePnP或cv2.solvePnPRansac函数,输入3D点、2D点、内参矩阵和畸变系数,输出旋转向量rvec和平移向量tvec。
  5. 转换旋转向量为欧拉角:通过Rodrigues变换将rvec转换为旋转矩阵R,再分解为Yaw、Pitch、Roll。
import cv2
import numpy as np

# 3D人脸基准点(单位:mm)
object_pts = np.float32([
    [0.0, 0.0, 0.0],      # 鼻尖
    [0.0, -30.0, -10.0],  # 下巴
    [-30.0, -20.0, 10.0], # 左眼左角
    [30.0, -20.0, 10.0],  # 右眼右角
    [-25.0, 10.0, 5.0],   # 嘴角左端
    [25.0, 10.0, 5.0]     # 嘴角右端
])

# 2D关键点(从检测网络获取)
image_pts = np.float32([
    [nose_x, nose_y],
    [chin_x, chin_y],
    [left_eye_x, left_eye_y],
    [right_eye_x, right_eye_y],
    [mouth_left_x, mouth_left_y],
    [mouth_right_x, mouth_right_y]
])

# 相机内参(需标定)
K = np.float64([[fx, 0, cx], [0, fy, cy], [0, 0, 1]])
dist_coeffs = np.float64([0, 0, 0, 0, 0])  # 假设无畸变

# 求解PnP
success, rvec, tvec = cv2.solvePnP(object_pts, image_pts, K, dist_coeffs)

# 旋转向量转旋转矩阵
R, _ = cv2.Rodrigues(rvec)

# 计算欧拉角(注意旋转顺序)
yaw = np.degrees(np.arctan2(R[1,0], R[0,0]))
pitch = np.degrees(np.arctan2(-R[2,0], np.sqrt(R[2,1]**2 + R[2,2]**2)))
roll = np.degrees(np.arctan2(R[2,1], R[2,2]))

在DMS工程中,头部姿态估计需要做时间序列平滑,因为单帧的PnP结果存在抖动。常用的方法包括卡尔曼滤波或滑动窗口平均。此外,当Yaw角值大于60°时,人脸关键点自遮挡严重,PnP求解会退化,此时应结合肩部检测或车辆转向信号进行综合判断。

风险提示:若驾驶员佩戴帽子或头发遮挡眉毛,关键点检测的置信度会下降,导致PnP求解的旋转向量跳变。建议在算法中增加关键点置信度加权,对低置信度的点降低其在PnP求解中的权重。

4.3 眼部状态分析:从EAR到PERCLOS的完整链路

眼部状态分析是疲劳驾驶告警的核心依据。最常用的指标是眼纵横比(Eye Aspect Ratio, EAR),它利用眼睛周围关键点的欧氏距离比值来量化眼睛的开合程度。对于106点模型,每只眼睛有12个关键点,我们选取其中6个关键点(眼睑上下沿各3个)来计算EAR。

EAR的计算公式如下:

EAR = (||P2 - P6|| + ||P3 - P5||) / (2 * ||P1 - P4||)
其中:
P1, P4 为眼睛左右眼角
P2, P3 为上眼睑关键点
P5, P6 为下眼睑关键点

当眼睛完全睁开时,EAR约为0.25-0.35;当眼睛闭合时,EAR趋近于0。通过设定阈值(通常为0.15-0.20),可以判断当前帧眼睛是否闭合。但单帧的EAR容易受光照和头部姿态影响,因此需要引入PERCLOS(Percentage of Eye Closure)指标——即单位时间内眼睛闭合帧数占总帧数的百分比。根据美国联邦公路管理局(FHWA)的研究,PERCLOS超过40%时,驾驶员处于严重疲劳状态。

工程实现中,还需要处理以下细节:

  • 眨眼区分:正常眨眼持续约100-150ms,若闭合时间超过500ms,则判定为微睡眠事件。
  • 姿态补偿:当驾驶员低头(Pitch角>20°)时,眼睛在图像中会变窄,EAR值会系统性偏低。此时需要根据头部姿态对EAR进行修正,或采用基于3D眼睑模型的方法。
  • 光照鲁棒性:夜间行车时,红外摄像头下眼睛区域可能出现反光或暗瞳效应,建议在关键点检测前增加红外图像增强预处理。
指标计算公式阈值参考DMS告警等级
EAR眼睑垂直距离/水平距离<0.18判定闭眼单帧状态
PERCLOS闭眼帧数/总帧数×100%>40%判定疲劳一级告警
闭眼时长连续闭眼帧数×帧周期>500ms判定微睡眠二级告警
眨眼频率每分钟眨眼次数<5次/分钟判定疲劳辅助指标
实战经验:在阳光直射或逆光场景下,建议在摄像头前增加偏振片,并在算法中启用自适应直方图均衡化(CLAHE)来增强眼睑边缘的对比度。同时,将EAR的计算区域限制在关键点置信度高于0.7的范围内,避免因检测漂移导致的误判。

4.4 案例拆解:某量产车型DMS眼部疲劳告警误报优化

背景与约束:某主机厂在量产车型上部署了基于106点关键点的DMS系统,摄像头安装于仪表盘上方,俯仰角约15°,分辨率为1280×720@30fps。系统上线后,收到大量用户投诉:在正常驾驶过程中,系统频繁触发“疲劳驾驶”告警,尤其在驾驶员佩戴太阳镜或行驶在颠簸路面时。

初始现象与数据采集:通过车载日志分析发现,误报集中在两类场景:一是驾驶员佩戴偏光太阳镜时,关键点检测置信度从0.85骤降至0.4以下,导致EAR值异常偏低;二是车辆经过减速带时,摄像头振动导致关键点坐标在垂直方向产生±3像素的抖动,使得EAR值在0.15-0.25之间剧烈波动。

分析判断过程:团队首先排除了算法本身的问题——在实验室静态场景下,PERCLOS准确率达到95%。进一步分析发现,太阳镜场景下,红外摄像头无法穿透镜片获取眼睑轮廓,关键点检测器将镜框边缘误识别为眼睑,导致EAR计算失真。而振动场景下,单帧EAR的噪声方差增大,但PERCLOS的统计窗口(30秒)内,闭眼帧占比并未真正超过40%,问题出在告警逻辑中使用了过短的滑动窗口(5秒)。

实际操作步骤:

  1. 增加关键点置信度门控:当眼睛周围12个关键点的平均置信度低于0.6时,不计算EAR,而是将上一有效帧的EAR值保持,并标记为“低置信度状态”。
  2. 引入振动检测与补偿:利用IMU(惯性测量单元)数据检测车辆振动频率,当振动幅度超过阈值时,将PERCLOS的统计窗口从5秒延长至15秒,并采用中值滤波替代均值滤波。
  3. 优化告警逻辑:将“疲劳告警”触发条件从“单次PERCLOS>40%”改为“连续3个统计周期(每个周期30秒)PERCLOS均>40%”,同时增加眨眼频率作为辅助确认条件。
  4. 增加太阳镜检测分支:在关键点检测网络前增加一个轻量级分类器,判断驾驶员是否佩戴墨镜。若佩戴,则切换至基于头部姿态和方向盘握力的间接疲劳判断策略。

结果对比:优化后,误报率从每百公里2.3次降至0.4次,召回率(真实疲劳事件的检出率)保持在92%以上。太阳镜场景下的误报率降低了87%,振动场景下的误报率降低了76%。

风险与代价:置信度门控可能导致在极端光照下(如夜间无红外补光)出现“检测盲区”,此时系统无法判断驾驶员状态。为此,团队增加了“状态未知”的告警提示,并联动车内灯光提醒驾驶员注意安全。此外,IMU数据的接入增加了系统集成的复杂度,需要与整车CAN总线进行通信。

复盘经验:DMS关键点定位的工程化不仅仅是模型精度问题,更需要结合传感器特性、车辆动力学和用户使用习惯进行系统性调优。建议在项目初期就建立包含太阳镜、口罩、帽子、极端光照、振动路面等典型场景的测试矩阵,避免在量产后期被动修复。

总结:人脸关键点定位是DMS感知层的“地基”。68点模型适合快速原型验证,106点模型是当前量产主流,468点模型则面向未来更高阶的座舱交互。在实际部署中,务必围绕关键点置信度、头部姿态补偿和时序平滑三个维度进行深度优化,才能实现“少误报、不漏报”的可靠告警。