2D人脸关键点转3D人脸关键点的映射~头部姿态笔记

这篇具有很好参考价值的文章主要介绍了2D人脸关键点转3D人脸关键点的映射~头部姿态笔记。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文主要内容

对通过相机参数计算图像上的二维坐标到三维坐标的映射进行简单探讨。

参考资料:

        学习的话直接看他们的就好,我仅是拾人牙慧,拿GPT写给自己看的,图也是直接搬运的别人画的,以下链接有很完善的理论研究和代码提供。

https://medium.com/@susanne.thierfelder/head-pose-estimation-with-mediapipe-and-opencv-in-javascript-c87980df3acbhttps://medium.com/@susanne.thierfelder/head-pose-estimation-with-mediapipe-and-opencv-in-javascript-c87980df3acbGitHub - itsvaibhav01/3D-Viewing-Angle-from-Face-Mesh: Monitor viewing angle using Mediapipe Face meshMonitor viewing angle using Mediapipe Face mesh. Contribute to itsvaibhav01/3D-Viewing-Angle-from-Face-Mesh development by creating an account on GitHub.https://github.com/itsvaibhav01/3D-Viewing-Angle-from-Face-Meshhttps://github.com/niconielsen32/ComputerVision/blob/master/headPoseEstimation.pyhttps://github.com/niconielsen32/ComputerVision/blob/master/headPoseEstimation.pyhttps://github.com/niconielsen32/ComputerVision/blob/master/headPoseEstimation.pyhttps://github.com/niconielsen32/ComputerVision/blob/master/headPoseEstimation.pyتخمین وضعیت سر با استفاده از Mediapipe - ویرگولدر این مطلب به تعریف مساله تخمین وضعیت سر می‌پردازیم و سپس کد آن را در زبان برنامه‌نویسی پایتون پیاده‌سازی خواهیم کرد.https://virgool.io/@shenasa/%D8%AA%D8%AE%D9%85%DB%8C%D9%86-%D9%88%D8%B6%D8%B9%DB%8C%D8%AA-%D8%B3%D8%B1-%D8%A8%D8%A7-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-mediapipe-jiwmpml2mxag

正文

概念介绍

The camera matrix

        在计算机视觉中,相机矩阵(Camera Matrix)是一个重要的参数,它描述了相机的内部参数。相机矩阵通常用于将三维空间中的点投影到二维图像平面上。它定义了图像坐标系和相机坐标系之间的转换关系。

[ fx   0  cx ]
[  0  fy  cy ]
[  0   0   1 ]
  • fxfy 是焦距(focal length)在图像坐标系中的缩放因子。它们表示相机在X和Y轴上的焦距,通常以像素为单位。
  • cxcy 是主点(principal point)在图像坐标系中的坐标。主点是图像平面上的光学中心,它通常是图像的中心点,也以像素为单位。

        相机矩阵的具体值与相机硬件相关,并且可以通过相机校准(Camera Calibration)来获得。相机校准是一个重要的过程,它通过拍摄特定的校准板图案,并结合一些几何和优化算法,来确定相机矩阵和畸变参数,从而提供准确的相机参数,以便进行准确的图像测量和姿态估计等任务。

        在给定了相机矩阵后,可以使用它进行图像点到相机坐标系点的转换,或者相机坐标系点到图像点的投影。这在计算机视觉和计算机图形学中都是常见的操作。

相机矩阵与三维坐标

        通过使用线性代数并将该矩阵乘以物体的三维坐标,就可以在图像中找到它们的坐标。

2d关键点到3d关键点,深度学习,笔记

2d关键点到3d关键点,深度学习,笔记

图像来自最后一个链接:تخمین وضعیت سر با استفاده از Mediapipe - ویرگول。

三维坐标的空间变换:旋转矩阵和平移矩阵

        三维空间中的任何点都可以通过三分量向量移动,或者绕三个坐标轴旋转三个角度。为此,使用变换矩阵。将变换矩阵乘以点的初始坐标,即可得到变换后的坐标。

2d关键点到3d关键点,深度学习,笔记

         例如绕X轴平移或旋转的变换矩阵如下:

2d关键点到3d关键点,深度学习,笔记

         这两个矩阵分别是平移矩阵(Translation Matrix)和旋转矩阵(Rotation Matrix),它们一起描述了相机相对于某个参考坐标系的位置和方向。

  1. 平移矩阵(Translation Matrix): 平移矩阵是一个3x1的矩阵,用来描述相机坐标系的原点在参考坐标系(如现实世界坐标系)中的位置。平移矩阵通常用 t 或 T 表示,其中 t = [tx, ty, tz],表示相机坐标系原点相对于参考坐标系原点在X、Y、Z轴方向上的平移量。

  2. 旋转矩阵(Rotation Matrix): 旋转矩阵是一个3x3的正交矩阵,用来描述相机坐标系相对于参考坐标系的旋转变换。旋转矩阵通常用 R 表示,它将相机坐标系中的向量映射到参考坐标系中的向量。旋转矩阵有以下几个重要性质:

    • 它的行和列是单位向量,表示相机坐标系的三个轴在参考坐标系中的方向。
    • 它的行和列是正交的,即彼此之间互相垂直。
    • 它的行和列的模长都为1,因为它表示了旋转变换而不改变向量的长度。

        可以通过矩阵乘法同时执行绕所有三个轴的平移和旋转操作,如下所示:

2d关键点到3d关键点,深度学习,笔记

 计算的实现:opencv库
success, rotation_vec, translation_vec = cv2.solvePnP( 
face_coordination_in_real_world, 
face_coordination_in_image, 
cam_matrix, dist_matrix)
        显而易见,完成这一套计算最重要的就是得到这些参数,参数的获取方式将在下面讲述。

头部姿态估计问题

        头部姿态问题涉及的是对多个坐标系之间映射的处理问题,这些坐标系分别是:

  1. 现实世界坐标系:由 U、V 和 W 轴构成,代表现实世界中的物体坐标。这是物体在现实世界的真实坐标,可以是任意单位,例如米(m)。

  2. 相机坐标系:由 X、Y 和 Z 轴构成,代表相机的坐标系。相机坐标系是相对于相机本身的坐标系,其中 X 轴指向右侧,Y 轴指向下方,Z 轴指向相机的观察方向。这个坐标系通常用于描述相机内部的几何属性,如焦距、畸变等。点 P 在相机坐标系中的坐标可以用来描述物体相对于相机的位置。

  3. 二维图像坐标系:由 x 轴和 y 轴构成,代表相机拍摄到的二维图像坐标。二维图像坐标是将三维空间中的点投影到相机成像平面上得到的,通常以像素为单位。

2d关键点到3d关键点,深度学习,笔记

将图像中的 3D 坐标转换为 2D 坐标的公式:

2d关键点到3d关键点,深度学习,笔记

        我们的目标是找到现实世界中头部的角度或方向。我们知道,当我们将头转向两侧时,实际上相机处于固定位置和方向,头部会改变位置;但我们可以假设头部是固定的,变化的是相机相对于头部的位置和方向。在这种情况下,我们的目标变为寻找旋转矩阵 R。

参数获取

        如果我们想要估计现实世界中头部的位置,可以使用一个假设的人脸模型,并将一些关键点的坐标作为现实世界中的参考点。这些关键点的坐标需要在所有三个坐标轴上都有变化,以确保估计的准确性。

        实现方法所需要使用的点以及他们分别对应的mediapipe mesh坐标,这也是2D世界坐标。

  1. 鼻尖
  2. 右眼外角
  3. 左眼外角
  4. 眉间
  5. 右唇角
  6. 左唇角
            head = [landmark[1], landmark[9], landmark[57],
                    landmark[130], landmark[287], landmark[359]]

相机参数矩阵和失真系数

相机参数矩阵与焦距

        相机参数通常是与相机类型和相机规格相关的,并且可以通过相机校准来获得。但是,如果没有提供准确的相机参数,我们可以利用图像的长度和宽度作为焦距值,并将图像中心的坐标作为光学焦点的值,来进行一个简单的估计,当然,这是不够严谨的,仅仅是为了表达思想。

# Approximate focal length as half of the image width or height
focal_length = (w + h) / 2

# Approximate optical center as the center of the image
optical_center = (w / 2, h / 2)

# Construct an approximate camera matrix
cam_matrix = np.array([[focal_length, 0, optical_center[0]],
                       [0, focal_length, optical_center[1]],
                       [0, 0, 1]])
            focal_length = 1 * w
            cam_matrix = np.array([[focal_length, 0, w / 2],
                                   [0, focal_length, h / 2],
                                   [0, 0, 1]])

        以上提供了两种估计方法,在第一种估计中,假设相机的焦距在水平和垂直方向上相等,可以使用图像的宽度(w)和高度(h)的一半来估计焦距(focal_length)。这个假设的焦距值可以用于构造一个近似的相机矩阵(Camera Matrix),第二种则使用图像宽度的一倍作为焦距。

焦距估计的方法评价:
  1. 使用图像宽度的一倍作为焦距(focal_length = 1 * w):

    • 优点:这种方法简单快速,不需要额外的相机校准步骤,适用于快速原型或简单的应用场景。
    • 缺点:这种方法忽略了相机的真实参数和畸变,是一个近似值,可能导致估计的精度较低,尤其在复杂场景中。
  2. 使用相机校准得到的准确焦距值:

    • 优点:通过相机校准可以得到相机的准确内部参数和外部参数,提供了更精确的相机矩阵,估计结果更可靠和精确。
    • 缺点:相机校准过程可能相对复杂,需要拍摄特定的校准板图案,对于某些应用可能增加了额外的工作和成本。

        如果需要高精度的位姿估计,尤其在复杂场景或精密测量中,建议使用第二种方法,即使用相机校准得到的准确焦距值和相机参数。相机校准可以提供更准确的相机内部参数和外部参数,对于头部姿态估计等任务会有更可靠的结果。

        但如果只是进行简单的头部姿态估计、目标跟踪等应用,并且对于精度要求不是非常高,第一种方法即使用图像宽度的一倍作为焦距值可能足够满足需求,而且更加简便快捷。

失真系数(畸变系数)矩阵的估计
dist_matrix = np.zeros((4, 1), dtype=np.float64)

        畸变系数矩阵是一个4x1的矩阵,它包含相机的径向和切向畸变系数。在这里,畸变系数矩阵被初始化为零,表示没有考虑畸变。如果相机存在畸变,可以通过相机校准等方法来估计得到畸变系数。 

        这里矩阵的规格是根据之前的计算公式来确立的,也是追求了理想情况做了简化。

图像中的二维坐标矩阵

        为了给这个矩阵赋值,需要找到图像中的坐标,比如现实世界中的指定点。为此,我们可以使用mediapipe进行实现。

        通过指定上述所有矩阵的值,可以使用Lunberg-Marquardt优化找到R和t的最佳值。

真实世界坐标的设置

    face_coordination_in_real_world = np.array([
        [285, 528, 200],
        [285, 371, 152],
        [197, 574, 128],
        [173, 425, 108],
        [360, 574, 128],
        [391, 425, 108]
    ], dtype=np.float64)

        在 Mediapipe 库中,它返回的关键点坐标是相对于图像尺寸的归一化坐标(介于 0 和 1 之间),为了将这些归一化坐标转换为像素坐标,需要将它们乘以图像的长度和宽度。

def detect_face_landmarks(image):
    fps_time = time.time()
    results = face_mesh.process(image)
    now = time.time()
    process_time =  (now - fps_time)
    print('mesh_time:', process_time)
    face_landmarks = []
    if results.multi_face_landmarks:
        for face in results.multi_face_landmarks:
            landmarks = []
            for landmark in face.landmark:
                x = int(landmark.x * image.shape[1])
                y = int(landmark.y * image.shape[0])
                landmarks.append((x, y))
            face_landmarks.append(landmarks)

    return face_landmarks

而我们只做头部姿态则只需要这些点:这些也是面部图像中所需点的二维坐标。

            head = [landmark[1], landmark[9], landmark[57],
                    landmark[130], landmark[287], landmark[359]]

通过cv2计算旋转矩阵和平移矩阵

通过以上数据可以计算旋转矩阵和平移矩阵。

            for (landmark_x, landmark_y) in head:
                x, y = (x1 + landmark_x, y1 + landmark_y)
                face_coordination_in_image.append([x, y])
            face_coordination_in_image = np.array(face_coordination_in_image,
                                                  dtype=np.float64)
            success, rotation_vec, transition_vec = cv2.solvePnP(
                face_coordination_in_real_world, face_coordination_in_image,
                cam_matrix, dist_matrix)

cv2.solvePnP 是 OpenCV 库中的一个函数,用于解决透视投影问题。该函数可以用于估计相机的旋转向量和平移向量,从而得到相机在现实世界中的位姿信息。

retval, rotation_vec, translation_vec = cv2.solvePnP(object_points, image_points, camera_matrix, dist_coeffs[, rvec[, tvec[, useExtrinsicGuess[, flags]]]])文章来源地址https://www.toymoban.com/news/detail-766061.html

  • object_points: 真实世界中待估计物体的三维坐标矩阵,是一个 Nx3 的 NumPy 数组,其中 N 是点的数量,每一行包含一个点的 X、Y、Z 坐标。
  • image_points: 相机图像中检测到的物体特征点的二维像素坐标矩阵,是一个 Nx2 的 NumPy 数组,其中 N 是点的数量,每一行包含一个点的像素坐标 (x, y)。
  • camera_matrix: 相机矩阵,它是一个3x3的矩阵,包含了相机的内部参数,如焦距和光学中心。
  • dist_coeffs: 畸变系数矩阵,它是一个4x1的矩阵,包含了相机的径向和切向畸变系数。
  • rvec: 输出的旋转向量,是一个3x1的矩阵,表示相机坐标系相对于现实世界坐标系的旋转。
  • tvec: 输出的平移向量,是一个3x1的矩阵,表示相机坐标系原点相对于现实世界坐标系原点的平移。
  • useExtrinsicGuess: 布尔值,表示是否使用输入的 rvectvec 作为初始估计值,默认为 False。
  • flags: 用于指定求解 PnP 问题的标志,可以是 cv2.SOLVEPNP_ITERATIVEcv2.SOLVEPNP_EPNPcv2.SOLVEPNP_P3Pcv2.SOLVEPNP_DLScv2.SOLVEPNP_UPNP,具体选择哪个取决于问题的类型和需求。

到了这里,关于2D人脸关键点转3D人脸关键点的映射~头部姿态笔记的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • YOLOv5姿态估计:HRnet实时检测人体关键点

    前言: Hello大家好,我是Dream。 今天来学习一下 利用YOLOv5进行姿态估计,HRnet与SimDR检测图片、视频以及摄像头中的人体关键点 ,欢迎大家一起前来探讨学习~ 首先需要我们利用Pycharm直接克隆github中的姿态估计原工程文件,如果不知道怎样在本地克隆Pycharm,可以接着往下看,

    2024年01月17日
    浏览(68)
  • Python+OpenCV+OpenPose实现人体姿态估计(人体关键点检测)

    1、人体姿态估计简介 2、人体姿态估计数据集 3、OpenPose库 4、实现原理 5、实现神经网络 6、实现代码 人体姿态估计(Human Posture Estimation),是通过将图片中已检测到的人体关键点正确的联系起来,从而估计人体姿态。 人体关键点通常对应人体上有一定自由度的关节,比如颈、

    2024年02月04日
    浏览(46)
  • opencv-人脸关键点定位

    2024年02月12日
    浏览(53)
  • Mediapipe人脸关键点检测

    MediaPipe是由google制作的开源的、跨平台的机器学习框架,可以将一些模型部署到不同的平台和设备上使用的同时,也能保住检测速度。 从图中可以发现,能在Python上实现的功能包括人脸检测(Face Detection)、人脸关键点(Face Mesh),手部关键点(Hands)等。利用C++能实现更丰富

    2024年02月02日
    浏览(41)
  • OpenCV实现人脸关键点检测

    目录 实现过程 1,代码解读 1.1 导入工具包 1.2导入所需图像,以及训练好的人脸预测模型 1.3 将 dlib 的关键点对象转换为 NumPy 数组,以便后续处理 1.4图像上可视化面部关键点 1.5# 读取输入数据,预处理 1.6进行人脸检测 1.7遍历检测到的框 1.8遍历每个面部 2,所有代码 3,结果

    2024年04月23日
    浏览(59)
  • OpenCV中的人脸关键点检测和人脸特征提取如何实现?

    在OpenCV中,人脸关键点检测和人脸特征提取是常见的计算机视觉任务。OpenCV提供了一些用于实现这些任务的函数和算法。下面将介绍如何在OpenCV中实现人脸关键点检测和人脸特征提取。 1. 人脸关键点检测 人脸关键点检测是指识别和定位人脸上的关键点,如眼睛、鼻子、嘴巴

    2024年02月03日
    浏览(63)
  • YOLOv8 人体姿态估计(关键点检测) python推理 && ONNX RUNTIME C++部署

    目录   1、下载权重 ​编辑2、python 推理 3、转ONNX格式 4、ONNX RUNTIME C++ 部署 utils.h utils.cpp detect.h detect.cpp main.cpp CmakeList.txt 我这里之前在做实例分割的时候,项目已经下载到本地,环境也安装好了,只需要下载pose的权重就可以 输出:   用netron查看一下:  如上图所是,YOLO

    2024年02月07日
    浏览(48)
  • OpenCV 入门教程:人脸检测和关键点定位

    人脸检测和关键点定位是计算机视觉中的重要任务,用于在图像或视频中自动检测人脸并定位人脸关键点,如眼睛、鼻子、嘴巴等。这项技术在人脸识别、表情分析、姿态估计等领

    2024年02月15日
    浏览(38)
  • 人脸68、29、21、14、5关键点标注序号及对应关系

    最近需要用到solvePnP算法[1]通过人脸关键点求解人脸姿态,涉及到的数据集中关键点标注数量不统一,但网上使用solvePnP算法时人脸模型比较好找到的是68个关键点,因此需要找到模型的68个关键点中与其他几种数量关键点的对应关系。 目录 98关键点标注序号 68关键点标注序号

    2024年02月08日
    浏览(69)
  • 人脸与关键点检测:YOLO5Face实战

    Github:https://github.com/deepcam-cn/yolov5-face 导读:居然花了一天时间把该项目复现,主要是折腾在数据集格式上,作者居然在train2yolo中居然把Widerface训练集(12000+张图)重新一张一张保存,不这么还出bug,原因是无法读到数据缓存;在评估阶段,val2yolo也没用上。搬运工,一个字,

    2024年02月06日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包