DamoFD人脸关键点检测教程关键点旋转角度计算头部姿态估计入门1. 引言从人脸检测到姿态理解人脸检测技术已经相当成熟但很多时候仅仅知道“图片里有人脸”是远远不够的。比如在开发一个需要判断用户是否在看屏幕的应用程序时或者在一个需要分析驾驶员疲劳状态的系统中我们不仅需要知道人脸在哪里更需要知道头部的朝向——是正对镜头还是向左看、向右看甚至是抬头或低头。这就是头部姿态估计要解决的问题。而实现这一功能的基础正是精准的人脸关键点检测。今天我们就以达摩院开源的DamoFD-0.5G模型为起点带你从零开始一步步实现人脸关键点的检测并在此基础上亲手计算出人脸的旋转角度完成一个简单的头部姿态估计项目。通过本教程你将学到如何快速部署并使用 DamoFD 模型检测出人脸上的五个关键点双眼、鼻尖、嘴角。理解头部姿态估计的基本原理特别是如何从二维图像的关键点推算出三维空间的旋转角度。动手编写代码利用五个关键点计算人脸的偏航角Yaw左右转头、俯仰角Pitch点头抬头和翻滚角Roll头部倾斜。获得一个可以直接运行、可视化的完整示例看到你的算法如何“读懂”人脸的朝向。无论你是计算机视觉的初学者还是希望为现有项目添加姿态分析功能的开发者这篇教程都将提供一条清晰、可落地的实践路径。我们避开复杂的数学推导专注于工程实现让你快速看到效果。2. 环境准备与 DamoFD 快速上手在开始计算角度之前我们首先需要让模型“看到”人脸并找到关键点。我们将使用 CSDN 星图镜像广场提供的预置环境这能省去大量配置时间。2.1 启动与配置工作空间当你从镜像广场启动 DamoFD 镜像后系统已经为你准备好了所有依赖。为了便于我们后续修改和添加代码建议先将工作目录切换到数据盘。打开终端执行以下命令复制项目文件到工作空间cp -r /root/DamoFD /root/workspace/进入工作目录cd /root/workspace/DamoFD激活预置的 Python 环境conda activate damofd完成这三步你的环境就准备好了。项目里已经包含了基础的推理脚本DamoFD.py和一个 Jupyter Notebook 文件。2.2 运行你的第一次人脸关键点检测我们先通过最简单的方式验证模型是否能正常工作。你可以选择两种方式运行方式一使用 Python 脚本用文本编辑器打开DamoFD.py文件找到img_path这一行img_path https://modelscope.oss-cn-beijing.aliyuncs.com/test/images/mog_face_detection.jpg将单引号内的网址替换成你自己的图片路径例如/root/workspace/your_photo.jpg。然后运行python DamoFD.py运行成功后会在当前目录生成一个带检测框和关键点的结果图片。方式二使用 Jupyter Notebook推荐对于学习和调试Notebook 更加直观。在文件浏览器中进入/root/workspace/DamoFD/。双击打开DamoFD-0.5G.ipynb。关键步骤确保页面右上角的内核Kernel选择的是damofd。在 Notebook 中找到设置img_path的代码单元格修改为你的图片路径。点击菜单栏的“运行” - “运行所有单元格”。运行后你会在 Notebook 中直接看到原图和检测结果的可视化对比非常清晰。你应该能看到人脸被框出并且脸上标记了五个彩色的点这就是我们后续计算所需的五个关键点。3. 核心原理从五个点估算头部姿态现在我们拿到了五个关键点的像素坐标。如何把它们变成表示头部旋转的三个角度呢这里我们需要一点几何知识但别担心我们会用最直观的方式来理解。3.1 关键点与三维模型的对应头部姿态估计的一个经典思路是“解决一个透视投影问题”PnP Problem。简单来说就是我们有一个通用的、标准的三维人脸模型包含一些预设的3D点如眼角、鼻尖、嘴角等的位置。我们在二维图片上检测到了这些人脸特征点对应的2D像素坐标。通过数学方法找到一个最佳的3D旋转和平移变换使得这个3D模型在投影到2D图像平面时其投影点与我们检测到的2D点尽可能重合。找到的这个变换就包含了我们想要的旋转角度Roll, Pitch, Yaw和平移量。对于 DamoFD 提供的五个关键点左眼、右眼、鼻尖、左嘴角、右嘴角我们可以对应到一个简单的3D人脸模型上。虽然五点模型比更复杂的68点或106点模型信息量少但对于估算大致的头部朝向已经足够有效。3.2 旋转角度的直观理解在开始计算前我们先建立直观感受偏航角Yaw表示头部左右转动。当你向左或向右看时这个角度会变化。正对镜头时约为0度。俯仰角Pitch表示头部上下摆动。当你点头或抬头时这个角度会变化。平视时约为0度。翻滚角Roll表示头部侧向倾斜。当你把头歪向一侧肩膀时这个角度会变化。头部端正时约为0度。我们的目标就是通过五个2D关键点计算出这组[pitch, yaw, roll]角度值。4. 动手实践编写头部姿态估计代码理论说完了我们来点实际的。我们将在原有的DamoFD.py脚本基础上进行扩展添加姿态估计功能。4.1 准备3D模型点和相机参数首先我们需要定义与五个2D关键点对应的3D模型点坐标。这些坐标是基于一个假设的、正对镜头的标准人脸模型。同时我们还需要假设一个相机参数焦距、图像中心因为实际计算中需要它们。在你的DamoFD.py脚本中在导入库之后、主函数之前添加以下代码import cv2 import numpy as np # 定义3D人脸模型的标准点对应左眼、右眼、鼻尖、左嘴角、右嘴角 # 这些坐标是假设的基于一个标准化的3D人脸模型 model_points_3d np.array([ [-165.0, 170.0, -115.0], # 左眼 [165.0, 170.0, -115.0], # 右眼 [0.0, 0.0, 0.0], # 鼻尖 [-150.0, -150.0, -125.0], # 左嘴角 [150.0, -150.0, -125.0] # 右嘴角 ], dtypenp.float64) # 假设的相机内参矩阵 # 焦距(fx, fy) 这里假设与图像尺寸相关主点(cx, cy)设在图像中心 # 你可以根据你的图片实际尺寸微调但作为估算以下假设值通常可行 image_width 640 # 假设的图像宽度后续会根据实际图片更新 image_height 480 # 假设的图像高度 focal_length image_width center (image_width / 2, image_height / 2) camera_matrix np.array([ [focal_length, 0, center[0]], [0, focal_length, center[1]], [0, 0, 1] ], dtypenp.float64) # 假设没有镜头畸变 dist_coeffs np.zeros((4, 1), dtypenp.float64)4.2 修改推理代码提取关键点坐标接下来我们需要从 DamoFD 模型的输出中提取出五个关键点的像素坐标。找到原脚本中处理检测结果的部分通常是画框和画点之后修改或添加代码来保存这些坐标。假设原脚本中pred变量包含了检测结果并且关键点信息在其中。我们需要解析它构建一个2D点列表顺序要与上面定义的3D模型点一一对应。# 在原脚本可视化部分之前添加关键点坐标提取 # 假设 dets 是包含检测框和关键点的列表每个 det 的格式为 [x1, y1, x2, y2, score, kpts...] # 其中 kpts 是10个值分别代表5个点的x,y坐标 all_face_landmarks_2d [] # 用来存储所有检测到的人脸的关键点 for det in dets: # 遍历所有检测到的人脸 score det[4] if score 0.5: # 置信度阈值可调整 continue # 提取五个关键点的像素坐标 (x, y) # 注意根据DamoFD输出格式调整索引这里假设kpts从索引5开始 kpts det[5:15].reshape(5, 2) # 重塑为5行2列 landmarks_2d [] for (x, y) in kpts: landmarks_2d.append([x, y]) all_face_landmarks_2d.append(np.array(landmarks_2d, dtypenp.float64)) # 原有的画框和画关键点代码保留... # cv2.rectangle(...) # for (x, y) in kpts: cv2.circle(...)4.3 计算旋转角度并可视化现在我们有了2D图像点列表all_face_landmarks_2d和预设的3D模型点model_points_3d。对每一张人脸我们可以使用 OpenCV 的solvePnP函数来计算旋转和平移向量。在遍历人脸的循环内部提取出landmarks_2d后添加姿态计算代码# --- 头部姿态估计计算 --- if len(landmarks_2d) 5: # 确保有5个点 # 使用 solvePnP 求解旋转和平移向量 success, rotation_vector, translation_vector cv2.solvePnP( model_points_3d, landmarks_2d, camera_matrix, dist_coeffs, flagscv2.SOLVEPNP_ITERATIVE # 使用迭代法对五点模型较稳定 ) if success: # 将旋转向量转换为旋转矩阵再转换为欧拉角Pitch, Yaw, Roll rotation_matrix, _ cv2.Rodrigues(rotation_vector) # 从旋转矩阵中提取欧拉角具体转换方法有多种这里是一种常用方式 # 注意欧拉角存在万向锁问题且不同坐标系定义顺序会导致角度正负不同。 # 以下转换得到的角度单位是弧度需要转换为角度并且可能需要根据你的坐标系调整正负。 sy np.sqrt(rotation_matrix[0,0] * rotation_matrix[0,0] rotation_matrix[1,0] * rotation_matrix[1,0]) singular sy 1e-6 if not singular: x np.arctan2(rotation_matrix[2,1], rotation_matrix[2,2]) y np.arctan2(-rotation_matrix[2,0], sy) z np.arctan2(rotation_matrix[1,0], rotation_matrix[0,0]) else: x np.arctan2(-rotation_matrix[1,2], rotation_matrix[1,1]) y np.arctan2(-rotation_matrix[2,0], sy) z 0 # 将弧度转换为角度 pitch x * 180. / np.pi yaw y * 180. / np.pi roll z * 180. / np.pi # 打印结果到控制台 print(f检测到人脸姿态角度 Pitch俯仰: {pitch:.2f}°, Yaw偏航: {yaw:.2f}°, Roll翻滚: {roll:.2f}°) # --- 在图像上绘制姿态指示 --- # 可以绘制一个简单的3D坐标轴来直观显示头部朝向 axis_length 100.0 axis_points_3d np.float32([[axis_length, 0, 0], # X轴 (红色) [0, axis_length, 0], # Y轴 (绿色) [0, 0, axis_length]]) # Z轴 (蓝色指向屏幕外) # 将3D轴点投影到2D图像平面 axis_points_2d, _ cv2.projectPoints(axis_points_3d, rotation_vector, translation_vector, camera_matrix, dist_coeffs) axis_points_2d np.int32(axis_points_2d).reshape(-1, 2) # 获取鼻尖的2D坐标作为轴的原点 nose_point_2d landmarks_2d[2] # 鼻尖是第3个点索引2 origin tuple(np.int32(nose_point_2d)) # 在图像上画出坐标轴 img cv2.line(img, origin, tuple(axis_points_2d[0]), (0, 0, 255), 3) # X轴 - 红色 img cv2.line(img, origin, tuple(axis_points_2d[1]), (0, 255, 0), 3) # Y轴 - 绿色 img cv2.line(img, origin, tuple(axis_points_2d[2]), (255, 0, 0), 3) # Z轴 - 蓝色 # 在图像上添加角度文本 text fP:{pitch:.1f}, Y:{yaw:.1f}, R:{roll:.1f} cv2.putText(img, text, (int(det[0]), int(det[1])-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 0), 2)4.4 运行完整的姿态估计脚本将以上所有代码片段整合到你的DamoFD.py脚本中。确保你修改了img_path指向一张包含清晰人脸的图片。然后运行脚本python DamoFD.py如果一切顺利你不仅会看到带有关键点标记的人脸还会看到从鼻尖延伸出的红、绿、蓝三条坐标轴以及显示在脸上的三个角度值。红色轴X通常对应左右转向Yaw。头向右转红轴指向右。绿色轴Y通常对应上下点头Pitch。头向上抬绿轴指向上。蓝色轴Z通常对应侧倾Roll。头向右肩歪蓝轴方向会变化。通过观察坐标轴的方向和角度数值你就可以判断图片中人物的头部朝向。5. 效果展示与调优建议运行代码后你可能会得到类似下图的效果。人脸被检测出来五个关键点被标记并且从鼻尖画出了一个3D坐标轴来直观展示头部姿态。此处应为效果图描述一张图片左侧是原图右侧是处理后的图。处理后的图上人脸有检测框五个关键点被彩色圆点标出从鼻尖处延伸出红、绿、蓝三条短线组成的坐标轴旁边标注着Pitch: -5.2, Yaw: 15.3, Roll: 1.8之类的角度值。可能遇到的问题与调优建议角度值不准确或跳动检查关键点精度姿态估计的精度极度依赖关键点检测的精度。如果 DamoFD 在某些侧脸或遮挡情况下关键点不准结果就会偏差。可以尝试调整检测阈值score 0.5中的 0.5或使用更精准的关键点模型。校准相机参数我们代码中使用的camera_matrix是假设的。如果你的图片来自已知摄像头使用真实的内参会大幅提升精度。对于网络图片可以尝试根据图片宽度调整focal_length。3D模型点适配model_points_3d的坐标是基于一个平均人脸模型。如果结果有系统性偏差可以尝试微调这些3D点的坐标。solvePnP 求解失败确保landmarks_2d是包含5个点的np.array且数据类型是np.float64。确保model_points_3d和landmarks_2d的点顺序严格对应。欧拉角正负方向与预期不符欧拉角的定义旋转顺序、正方向有多种约定。上述代码给出的是一种常见转换。如果你发现“抬头”导致 Pitch 角减小而非增加可能需要调整公式中对应轴的正负号。理解rotation_matrix的含义有助于调整。提升方向更多关键点DamoFD-0.5G 只有5个点。升级到更多关键点的模型如 68 点、98 点或 106 点并使用对应的3D人脸模型能显著提升姿态估计的稳定性和精度。集成成熟库可以考虑使用像face_alignment或OpenFace这样的库它们集成了更鲁棒的关键点检测和姿态估计算法。滤波对于视频流可以对连续帧计算出的角度值进行卡尔曼滤波或简单移动平均使输出更平滑。6. 总结通过这篇教程我们完成了一个从人脸检测关键点到估算头部姿态的完整流程。我们利用DamoFD这个轻量级模型快速获取了人脸的五点坐标然后运用计算机视觉中的 PnP 问题求解方法结合 OpenCV计算出了表示头部旋转的三个欧拉角。这个项目虽然基础但它清晰地揭示了头部姿态估计的核心流程2D关键点检测 - 与3D模型匹配 - 求解几何变换 - 解析出角度。它为你打开了通往更高级应用的大门例如驾驶员状态监控通过分析 Yaw 和 Pitch 角判断司机是否在专注驾驶。交互式应用用头部转动来控制游戏或软件界面。视频会议辅助提示用户调整姿势正对摄像头。人脸图像标准化在送入人脸识别系统前先将人脸“摆正”。希望这个动手实践的过程能帮助你理解概念并激发你探索更多计算机视觉有趣应用的兴趣。代码已就绪现在就去找张照片试试看算法是如何“读懂”人脸朝向的吧获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。
DamoFD人脸关键点检测教程:关键点旋转角度计算+头部姿态估计入门
DamoFD人脸关键点检测教程关键点旋转角度计算头部姿态估计入门1. 引言从人脸检测到姿态理解人脸检测技术已经相当成熟但很多时候仅仅知道“图片里有人脸”是远远不够的。比如在开发一个需要判断用户是否在看屏幕的应用程序时或者在一个需要分析驾驶员疲劳状态的系统中我们不仅需要知道人脸在哪里更需要知道头部的朝向——是正对镜头还是向左看、向右看甚至是抬头或低头。这就是头部姿态估计要解决的问题。而实现这一功能的基础正是精准的人脸关键点检测。今天我们就以达摩院开源的DamoFD-0.5G模型为起点带你从零开始一步步实现人脸关键点的检测并在此基础上亲手计算出人脸的旋转角度完成一个简单的头部姿态估计项目。通过本教程你将学到如何快速部署并使用 DamoFD 模型检测出人脸上的五个关键点双眼、鼻尖、嘴角。理解头部姿态估计的基本原理特别是如何从二维图像的关键点推算出三维空间的旋转角度。动手编写代码利用五个关键点计算人脸的偏航角Yaw左右转头、俯仰角Pitch点头抬头和翻滚角Roll头部倾斜。获得一个可以直接运行、可视化的完整示例看到你的算法如何“读懂”人脸的朝向。无论你是计算机视觉的初学者还是希望为现有项目添加姿态分析功能的开发者这篇教程都将提供一条清晰、可落地的实践路径。我们避开复杂的数学推导专注于工程实现让你快速看到效果。2. 环境准备与 DamoFD 快速上手在开始计算角度之前我们首先需要让模型“看到”人脸并找到关键点。我们将使用 CSDN 星图镜像广场提供的预置环境这能省去大量配置时间。2.1 启动与配置工作空间当你从镜像广场启动 DamoFD 镜像后系统已经为你准备好了所有依赖。为了便于我们后续修改和添加代码建议先将工作目录切换到数据盘。打开终端执行以下命令复制项目文件到工作空间cp -r /root/DamoFD /root/workspace/进入工作目录cd /root/workspace/DamoFD激活预置的 Python 环境conda activate damofd完成这三步你的环境就准备好了。项目里已经包含了基础的推理脚本DamoFD.py和一个 Jupyter Notebook 文件。2.2 运行你的第一次人脸关键点检测我们先通过最简单的方式验证模型是否能正常工作。你可以选择两种方式运行方式一使用 Python 脚本用文本编辑器打开DamoFD.py文件找到img_path这一行img_path https://modelscope.oss-cn-beijing.aliyuncs.com/test/images/mog_face_detection.jpg将单引号内的网址替换成你自己的图片路径例如/root/workspace/your_photo.jpg。然后运行python DamoFD.py运行成功后会在当前目录生成一个带检测框和关键点的结果图片。方式二使用 Jupyter Notebook推荐对于学习和调试Notebook 更加直观。在文件浏览器中进入/root/workspace/DamoFD/。双击打开DamoFD-0.5G.ipynb。关键步骤确保页面右上角的内核Kernel选择的是damofd。在 Notebook 中找到设置img_path的代码单元格修改为你的图片路径。点击菜单栏的“运行” - “运行所有单元格”。运行后你会在 Notebook 中直接看到原图和检测结果的可视化对比非常清晰。你应该能看到人脸被框出并且脸上标记了五个彩色的点这就是我们后续计算所需的五个关键点。3. 核心原理从五个点估算头部姿态现在我们拿到了五个关键点的像素坐标。如何把它们变成表示头部旋转的三个角度呢这里我们需要一点几何知识但别担心我们会用最直观的方式来理解。3.1 关键点与三维模型的对应头部姿态估计的一个经典思路是“解决一个透视投影问题”PnP Problem。简单来说就是我们有一个通用的、标准的三维人脸模型包含一些预设的3D点如眼角、鼻尖、嘴角等的位置。我们在二维图片上检测到了这些人脸特征点对应的2D像素坐标。通过数学方法找到一个最佳的3D旋转和平移变换使得这个3D模型在投影到2D图像平面时其投影点与我们检测到的2D点尽可能重合。找到的这个变换就包含了我们想要的旋转角度Roll, Pitch, Yaw和平移量。对于 DamoFD 提供的五个关键点左眼、右眼、鼻尖、左嘴角、右嘴角我们可以对应到一个简单的3D人脸模型上。虽然五点模型比更复杂的68点或106点模型信息量少但对于估算大致的头部朝向已经足够有效。3.2 旋转角度的直观理解在开始计算前我们先建立直观感受偏航角Yaw表示头部左右转动。当你向左或向右看时这个角度会变化。正对镜头时约为0度。俯仰角Pitch表示头部上下摆动。当你点头或抬头时这个角度会变化。平视时约为0度。翻滚角Roll表示头部侧向倾斜。当你把头歪向一侧肩膀时这个角度会变化。头部端正时约为0度。我们的目标就是通过五个2D关键点计算出这组[pitch, yaw, roll]角度值。4. 动手实践编写头部姿态估计代码理论说完了我们来点实际的。我们将在原有的DamoFD.py脚本基础上进行扩展添加姿态估计功能。4.1 准备3D模型点和相机参数首先我们需要定义与五个2D关键点对应的3D模型点坐标。这些坐标是基于一个假设的、正对镜头的标准人脸模型。同时我们还需要假设一个相机参数焦距、图像中心因为实际计算中需要它们。在你的DamoFD.py脚本中在导入库之后、主函数之前添加以下代码import cv2 import numpy as np # 定义3D人脸模型的标准点对应左眼、右眼、鼻尖、左嘴角、右嘴角 # 这些坐标是假设的基于一个标准化的3D人脸模型 model_points_3d np.array([ [-165.0, 170.0, -115.0], # 左眼 [165.0, 170.0, -115.0], # 右眼 [0.0, 0.0, 0.0], # 鼻尖 [-150.0, -150.0, -125.0], # 左嘴角 [150.0, -150.0, -125.0] # 右嘴角 ], dtypenp.float64) # 假设的相机内参矩阵 # 焦距(fx, fy) 这里假设与图像尺寸相关主点(cx, cy)设在图像中心 # 你可以根据你的图片实际尺寸微调但作为估算以下假设值通常可行 image_width 640 # 假设的图像宽度后续会根据实际图片更新 image_height 480 # 假设的图像高度 focal_length image_width center (image_width / 2, image_height / 2) camera_matrix np.array([ [focal_length, 0, center[0]], [0, focal_length, center[1]], [0, 0, 1] ], dtypenp.float64) # 假设没有镜头畸变 dist_coeffs np.zeros((4, 1), dtypenp.float64)4.2 修改推理代码提取关键点坐标接下来我们需要从 DamoFD 模型的输出中提取出五个关键点的像素坐标。找到原脚本中处理检测结果的部分通常是画框和画点之后修改或添加代码来保存这些坐标。假设原脚本中pred变量包含了检测结果并且关键点信息在其中。我们需要解析它构建一个2D点列表顺序要与上面定义的3D模型点一一对应。# 在原脚本可视化部分之前添加关键点坐标提取 # 假设 dets 是包含检测框和关键点的列表每个 det 的格式为 [x1, y1, x2, y2, score, kpts...] # 其中 kpts 是10个值分别代表5个点的x,y坐标 all_face_landmarks_2d [] # 用来存储所有检测到的人脸的关键点 for det in dets: # 遍历所有检测到的人脸 score det[4] if score 0.5: # 置信度阈值可调整 continue # 提取五个关键点的像素坐标 (x, y) # 注意根据DamoFD输出格式调整索引这里假设kpts从索引5开始 kpts det[5:15].reshape(5, 2) # 重塑为5行2列 landmarks_2d [] for (x, y) in kpts: landmarks_2d.append([x, y]) all_face_landmarks_2d.append(np.array(landmarks_2d, dtypenp.float64)) # 原有的画框和画关键点代码保留... # cv2.rectangle(...) # for (x, y) in kpts: cv2.circle(...)4.3 计算旋转角度并可视化现在我们有了2D图像点列表all_face_landmarks_2d和预设的3D模型点model_points_3d。对每一张人脸我们可以使用 OpenCV 的solvePnP函数来计算旋转和平移向量。在遍历人脸的循环内部提取出landmarks_2d后添加姿态计算代码# --- 头部姿态估计计算 --- if len(landmarks_2d) 5: # 确保有5个点 # 使用 solvePnP 求解旋转和平移向量 success, rotation_vector, translation_vector cv2.solvePnP( model_points_3d, landmarks_2d, camera_matrix, dist_coeffs, flagscv2.SOLVEPNP_ITERATIVE # 使用迭代法对五点模型较稳定 ) if success: # 将旋转向量转换为旋转矩阵再转换为欧拉角Pitch, Yaw, Roll rotation_matrix, _ cv2.Rodrigues(rotation_vector) # 从旋转矩阵中提取欧拉角具体转换方法有多种这里是一种常用方式 # 注意欧拉角存在万向锁问题且不同坐标系定义顺序会导致角度正负不同。 # 以下转换得到的角度单位是弧度需要转换为角度并且可能需要根据你的坐标系调整正负。 sy np.sqrt(rotation_matrix[0,0] * rotation_matrix[0,0] rotation_matrix[1,0] * rotation_matrix[1,0]) singular sy 1e-6 if not singular: x np.arctan2(rotation_matrix[2,1], rotation_matrix[2,2]) y np.arctan2(-rotation_matrix[2,0], sy) z np.arctan2(rotation_matrix[1,0], rotation_matrix[0,0]) else: x np.arctan2(-rotation_matrix[1,2], rotation_matrix[1,1]) y np.arctan2(-rotation_matrix[2,0], sy) z 0 # 将弧度转换为角度 pitch x * 180. / np.pi yaw y * 180. / np.pi roll z * 180. / np.pi # 打印结果到控制台 print(f检测到人脸姿态角度 Pitch俯仰: {pitch:.2f}°, Yaw偏航: {yaw:.2f}°, Roll翻滚: {roll:.2f}°) # --- 在图像上绘制姿态指示 --- # 可以绘制一个简单的3D坐标轴来直观显示头部朝向 axis_length 100.0 axis_points_3d np.float32([[axis_length, 0, 0], # X轴 (红色) [0, axis_length, 0], # Y轴 (绿色) [0, 0, axis_length]]) # Z轴 (蓝色指向屏幕外) # 将3D轴点投影到2D图像平面 axis_points_2d, _ cv2.projectPoints(axis_points_3d, rotation_vector, translation_vector, camera_matrix, dist_coeffs) axis_points_2d np.int32(axis_points_2d).reshape(-1, 2) # 获取鼻尖的2D坐标作为轴的原点 nose_point_2d landmarks_2d[2] # 鼻尖是第3个点索引2 origin tuple(np.int32(nose_point_2d)) # 在图像上画出坐标轴 img cv2.line(img, origin, tuple(axis_points_2d[0]), (0, 0, 255), 3) # X轴 - 红色 img cv2.line(img, origin, tuple(axis_points_2d[1]), (0, 255, 0), 3) # Y轴 - 绿色 img cv2.line(img, origin, tuple(axis_points_2d[2]), (255, 0, 0), 3) # Z轴 - 蓝色 # 在图像上添加角度文本 text fP:{pitch:.1f}, Y:{yaw:.1f}, R:{roll:.1f} cv2.putText(img, text, (int(det[0]), int(det[1])-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 0), 2)4.4 运行完整的姿态估计脚本将以上所有代码片段整合到你的DamoFD.py脚本中。确保你修改了img_path指向一张包含清晰人脸的图片。然后运行脚本python DamoFD.py如果一切顺利你不仅会看到带有关键点标记的人脸还会看到从鼻尖延伸出的红、绿、蓝三条坐标轴以及显示在脸上的三个角度值。红色轴X通常对应左右转向Yaw。头向右转红轴指向右。绿色轴Y通常对应上下点头Pitch。头向上抬绿轴指向上。蓝色轴Z通常对应侧倾Roll。头向右肩歪蓝轴方向会变化。通过观察坐标轴的方向和角度数值你就可以判断图片中人物的头部朝向。5. 效果展示与调优建议运行代码后你可能会得到类似下图的效果。人脸被检测出来五个关键点被标记并且从鼻尖画出了一个3D坐标轴来直观展示头部姿态。此处应为效果图描述一张图片左侧是原图右侧是处理后的图。处理后的图上人脸有检测框五个关键点被彩色圆点标出从鼻尖处延伸出红、绿、蓝三条短线组成的坐标轴旁边标注着Pitch: -5.2, Yaw: 15.3, Roll: 1.8之类的角度值。可能遇到的问题与调优建议角度值不准确或跳动检查关键点精度姿态估计的精度极度依赖关键点检测的精度。如果 DamoFD 在某些侧脸或遮挡情况下关键点不准结果就会偏差。可以尝试调整检测阈值score 0.5中的 0.5或使用更精准的关键点模型。校准相机参数我们代码中使用的camera_matrix是假设的。如果你的图片来自已知摄像头使用真实的内参会大幅提升精度。对于网络图片可以尝试根据图片宽度调整focal_length。3D模型点适配model_points_3d的坐标是基于一个平均人脸模型。如果结果有系统性偏差可以尝试微调这些3D点的坐标。solvePnP 求解失败确保landmarks_2d是包含5个点的np.array且数据类型是np.float64。确保model_points_3d和landmarks_2d的点顺序严格对应。欧拉角正负方向与预期不符欧拉角的定义旋转顺序、正方向有多种约定。上述代码给出的是一种常见转换。如果你发现“抬头”导致 Pitch 角减小而非增加可能需要调整公式中对应轴的正负号。理解rotation_matrix的含义有助于调整。提升方向更多关键点DamoFD-0.5G 只有5个点。升级到更多关键点的模型如 68 点、98 点或 106 点并使用对应的3D人脸模型能显著提升姿态估计的稳定性和精度。集成成熟库可以考虑使用像face_alignment或OpenFace这样的库它们集成了更鲁棒的关键点检测和姿态估计算法。滤波对于视频流可以对连续帧计算出的角度值进行卡尔曼滤波或简单移动平均使输出更平滑。6. 总结通过这篇教程我们完成了一个从人脸检测关键点到估算头部姿态的完整流程。我们利用DamoFD这个轻量级模型快速获取了人脸的五点坐标然后运用计算机视觉中的 PnP 问题求解方法结合 OpenCV计算出了表示头部旋转的三个欧拉角。这个项目虽然基础但它清晰地揭示了头部姿态估计的核心流程2D关键点检测 - 与3D模型匹配 - 求解几何变换 - 解析出角度。它为你打开了通往更高级应用的大门例如驾驶员状态监控通过分析 Yaw 和 Pitch 角判断司机是否在专注驾驶。交互式应用用头部转动来控制游戏或软件界面。视频会议辅助提示用户调整姿势正对摄像头。人脸图像标准化在送入人脸识别系统前先将人脸“摆正”。希望这个动手实践的过程能帮助你理解概念并激发你探索更多计算机视觉有趣应用的兴趣。代码已就绪现在就去找张照片试试看算法是如何“读懂”人脸朝向的吧获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。