【问题标题】:face alignment algorithm on images图像上的人脸对齐算法
【发布时间】:2012-08-16 07:16:04
【问题描述】:

假设我有嘴和眼睛的位置/坐标,我如何在二维图像上进行基本的人脸对齐。

我可以实施任何算法来纠正图像上的人脸对齐吗?

【问题讨论】:

  • 一个想法是在眼睛和嘴巴的位置与对齐偏差之间建立关系。然后使用此关系通过填充图像矩阵来校正位置,并通过调用 cv::resize 函数来调整比例并计算比例差异。

标签: objective-c opencv computer-vision face-detection biometrics


【解决方案1】:

人脸(或图像)对齐是指将一张图像(或在您的情况下为人脸)与另一张图像(或参考图像/人脸)对齐。它也称为图像配准。您可以使用外观(基于强度的配准)或关键点位置(基于特征的配准)来做到这一点。第二类源于图像运动模型,其中一个图像被认为是另一个图像的位移版本。

在您的案例中,地标位置(眼睛和鼻子 3 个点?)为直接基于特征的注册提供了很好的参考集。假设您在两个 2D 图像 x_1x_2 中都有一组点的位置,您可以估计 相似变换(旋转、平移、缩放),即平面 2D 变换Sx_1 映射到 x_2。您还可以为此添加反射,但对于面部而言,这很可能是不必要的。

可以通过形成正规方程并使用线性回归解决x_1 = Sx_2 系统的线性最小二乘 (LS) 问题来完成估计。对于 5 个未知参数(2 个旋转、2 个平移、1 个缩放),您需要 3 个点(准确地说是 2.5)来求解 5 个方程。可以通过直接线性变换(例如通过应用 SVD 或矩阵伪逆)获得上述 LS 的解决方案。对于足够多的参考点(即自动检测)的情况,用于点过滤和不确定性消除的 RANSAC 类型的方法(尽管这不是您的情况)。

估计S 后,对第二张图像应用图像变形以获得整个image 2 的变换网格(像素)坐标。变换将改变像素位置,但不会改变它们的外观。不可避免地,image 2 的某些转换区域将位于image 1 的网格之外,您可以决定这些空位置的值(例如 0、NaN 等)。

更多详情:R. Szeliski,“Image Alignment and Stitching: A Tutorial”(第 4.3 节“几何配准”)

在 OpenCV 中参见:Geometric Image Transformations,例如cv::getRotationMatrix2D cv::getAffineTransformcv::warpAffine. 请注意,您应该估计并应用相似变换(仿射的特殊情况)以保留角度和形状。

【讨论】:

    【解决方案2】:

    OpenCV 的人脸识别指南中有一节对齐人脸图像

    脚本在眼睛处对齐给定的图像。它是用 Python 编写的,但应该很容易翻译成其他语言。我知道 Sorin Miron 的 C# 实现:

    【讨论】:

      【解决方案3】:

      对于人脸,特征点有很多可变性。因此,仅通过仿射变换不可能完美拟合所有特征点。完美对齐所有点的唯一方法是在给定点的情况下扭曲图像。基本上,您可以在给定点的情况下对图像进行三角剖分,并对每个三角形进行仿射扭曲,以获得所有点都对齐的扭曲图像。

      【讨论】:

        【解决方案4】:

        可以根据眼睛的位置来处理人脸检测。

        在此,OpenCV、Dlib 和 MTCNN 提供了检测面部和眼睛的功能。此外,它是一个基于 python 的框架,但 deepface 封装了这些方法并提供了开箱即用的检测和对齐功能。

        detectFace 函数分别在后台应用检测和对齐。

        #!pip install deepface
        from deepface import DeepFace
        backends = ['opencv', 'ssd', 'dlib', 'mtcnn']
        DeepFace.detectFace("img.jpg", detector_backend = backends[0])
        

        此外,您可以手动应用检测和对齐。

        from deepface.commons import functions
        img = functions.load_image("img.jpg")
        backends = ['opencv', 'ssd', 'dlib', 'mtcnn']
        
        detected_face = functions.detect_face(img = img, detector_backend = backends[3])
        plt.imshow(detected_face)
        
        aligned_face = functions.align_face(img = img, detector_backend = backends[3])
        plt.imshow(aligned_face)
        
        processed_img = functions.detect_face(img = aligned_face, detector_backend = backends[3])
        plt.imshow(processed_img)
        

        【讨论】:

          猜你喜欢
          • 2016-10-27
          • 2019-06-11
          • 1970-01-01
          • 2019-02-10
          • 2015-10-13
          • 2011-09-14
          • 2014-02-18
          • 2022-07-02
          • 2020-03-06
          相关资源
          最近更新 更多