使用人脸关键点进行人脸对齐与矫正

1. 前言

人脸对齐的本质很简单——通过旋转、平移与缩放将目标人脸区域放置在图像特定位置。这是人脸识别系统中的一种标准操作。这样做可以减小需要处理的人脸图像在空间分布上的差异。说白了就是降低难度。其是人脸特征提取,人脸识别等任务种非常重要的一步,其常作为人脸数据预处理的一部分。

2. 当前关键点检测逻辑

目前我们的关键点检测模型,是在检测到图像中人脸后直接进行预测的,尽管模型对小中幅度人脸倾斜场景鲁棒,但当人脸出现大幅度倾斜时,其预测结果误差较大。而在TNN 优图关键点检测中,就使用到了多个关键点对图像做仿射变换,从而更利于关键点检测。

3. 使用OpenCV API 多点仿射变换

人脸对齐可以通过仿射变换来实现。变换的核心为仿射变换矩阵,它描述了变换过程的具体参数。仿射变换矩阵可以通过比较图像中特定像素在变换前后的位置差异来实现。对于人脸对齐来说,五官的分布就是一个绝佳的天然参考因素。只需在原始图像中检测面部五官位置,然后规定目标图像中五官应该出现的位置,便可得出变换矩阵。如果使用OpenCV的话,可以使用 cv2.estimateAffinePartial2D 函数计算出变换矩阵。

3.1 算法思路

  1. 使用MTCNN检测得到人脸五官关键关键点(图中绿点所示)
  2. 自行标定合适的仿射变换后的关键带你坐标(图中红点所示)
  3. 使用OpenCV cv2.estimateAffinePartial2D() API根据前后关键点计算仿射变换矩阵
  4. 使用cv2.warpAffine()对原图进行仿射变换,得到人脸对齐后的图像

人脸对齐前后结果:

3.2 示例代码

import numpy as np
import cv2

# 读取图像
image = cv2.imread("te4.png")

# 变换前的五官坐标
marks = np.array([
    173, 149,
    222, 125,
    205, 172,
    185, 192,
    226, 186
]).reshape([-1, 2])
for i in range(marks.shape[0]):
    x, y = marks[i]
    cv2.circle(image, (x, y), 3, (0, 255, 0), thickness=-1)

# 变换后的五官坐标
key_marks = np.array([65, 65, 130, 65, 96, 96, 75, 130, 117, 130]).reshape([-1, 2])


# 获取变换矩阵
M, _ = cv2.estimateAffinePartial2D(marks, key_marks)

# 执行变换操作
transformed = cv2.warpAffine(image, M, (192, 192), borderValue=0.0)
for i in range(key_marks.shape[0]):
    x, y = key_marks[i]
    cv2.circle(transformed, (x, y), 3, (0, 0, 255), thickness=-1)

# 展示结果
cv2.imshow("image", image)
cv2.imshow("image_rot", transformed)
cv2.waitKey()

4. TNN优图做法及使用SVD分解做仿射变换

4.1 TNN 优图逻辑

使用历史帧得到关键点,结合标准关人脸关键点计算仿射变换矩阵。
测试效果:

4.2 算法思路

  1. 关键点归一化
  2. SVD奇异值分解
  3. 获取特征向量
  4. 计算仿射变换矩阵
  5. 对原图进行仿射变换

具体细节可查看源码:
TNN/youtu_face_align.cc at master · Tencent/TNN · GitHub 255行 AlignN()函数
insightface/recognition at master · deepinsight/insightface · GitHubtools/cpp_align/face_align.h
采用mtcnn输出的特征点做人脸对齐C++代码_cv::mat m = alignmentkprocess::similartransform(ds_xiexiecn的博客-CSDN博客
https://cumtchw.blog.csdn.net/article/details/123800493

参考

根据人脸关键点做人脸对齐face alignment----C++实现_人脸对齐代码_陈 洪 伟的博客-CSDN博客
https://cumtchw.blog.csdn.net/article/details/123627357
https://www.cnblogs.com/cv-pr/p/5438351.html
采用mtcnn输出的特征点做人脸对齐C++代码_cv::mat m = alignmentkprocess::similartransform(ds_xiexiecn的博客-CSDN博客
人脸检测与对齐python实现
人脸对齐
opencv4.2.0中estimateAffine2D和estimateAffinePartial2D的区别_wish you forever的博客-CSDN博客

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值