cv2最强仿射变换(支持n点对齐,可进行人脸对齐)

人脸识别过程中,人脸对齐往往是最重要的一步,对齐的结果往往影响之后提取人脸特征的准确率,opencv内置的仿射变换仅仅需要三个点,而需对齐的人脸关键点一般是5个、68个、128个,本文提供一种n点对齐的放射变换点,以5个关键点的对齐为例:
归一化的五点坐标为:

[(0.31556875000000000, 0.4615741071428571),
 (0.68262291666666670, 0.4615741071428571),
 (0.50026249999999990, 0.6405053571428571),
 (0.34947187500000004, 0.8246919642857142),
 (0.65343645833333330, 0.8246919642857142)]

假如要裁剪的face大小为(112, 96),即:(height, width),则face的最终location点为:(xwidth, yheight)

[(30.2946, 51.6963),
 (65.5318, 51.6963),
 (48.0252, 71.7366),
 (33.5493, 92.3655),
 (62.7299, 92.3655)]

代码参考来源:https://matthewearl.github.io/2015/07/28/switching-eds-with-python/

#coding=utf-8
import os,cv2,numpy
import logging
logging.basicConfig(
	level=logging.DEBUG,
	format='%(asctime)s %(levelname)s: %(message)s',
	datefmt='%Y-%m-%d %H:%M:%S'
)
logger = logging.getLogger(__name__)

imgSize = [112, 96];
coord5point = [[30.2946, 51.6963],
               [65.5318, 51.6963],
               [48.0252, 71.7366],
               [33.5493, 92.3655],
               [62.7299, 92.3655]]

face_landmarks = [[259, 137],
                  [319, 150],
                  [284, 177],
                  [253, 206],
                  [297, 216]]

def transformation_from_points(points1, points2):
    points1 = points1.astype(numpy.float64)
    points2 = points2.astype(numpy.float64)
    c1 = numpy.mean(points1, axis=0)
    c2 = numpy.mean(points2, axis=0)
    points1 -= c1
    points2 -= c2
    s1 = numpy.std(points1)
    s2 = numpy.std(points2)
    points1 /= s1
    points2 /= s2
    U, S, Vt = numpy.linalg.svd(points1.T * points2)
    R = (U * Vt).T
    return numpy.vstack([numpy.hstack(((s2 / s1) * R,c2.T - (s2 / s1) * R * c1.T)),numpy.matrix([0., 0., 1.])])

def warp_im(img_im, orgi_landmarks,tar_landmarks):
    pts1 = numpy.float64(numpy.matrix([[point[0], point[1]] for point in orgi_landmarks]))
    pts2 = numpy.float64(numpy.matrix([[point[0], point[1]] for point in tar_landmarks]))
    M = transformation_from_points(pts1, pts2)
    dst = cv2.warpAffine(img_im, M[:2], (img_im.shape[1], img_im.shape[0]))
    return dst

def main():
    pic_path = r'D:\20171117190537959.jpg'
    img_im = cv2.imread(pic_path)
    cv2.imshow('affine_img_im', img_im)
    dst = warp_im(img_im, face_landmarks, coord5point)
    cv2.imshow('affine', dst)
    crop_im = dst[0:imgSize[0], 0:imgSize[1]]
    cv2.imshow('affine_crop_im', crop_im)

if __name__=='__main__':
    main()
    cv2.waitKey()
    pass

这里写图片描述
这里写图片描述
这里写图片描述

  • 11
    点赞
  • 58
    收藏
    觉得还不错? 一键收藏
  • 29
    评论
以下是一个基于Python和OpenCV的输入人脸三个数据点进行旋转对齐的程序: ```python import cv2 import numpy as np # 定义函数,输入人脸图像和三个关键点坐标,输出旋转后的图像 def align_face(img, left_eye, right_eye, nose_tip): # 计算两个眼睛的中心点坐标,并计算眼睛之间的距离 eye_center = ((left_eye[0] + right_eye[0]) // 2, (left_eye[1] + right_eye[1]) // 2) eye_distance = np.sqrt((right_eye[0] - left_eye[0])**2 + (right_eye[1] - left_eye[1])**2) # 计算旋转角度 angle = np.degrees(np.arctan2(right_eye[1] - left_eye[1], right_eye[0] - left_eye[0])) # 计算仿变换矩阵 M = cv2.getRotationMatrix2D(eye_center, angle, scale=1) # 将关键点坐标转换为二维矩阵 points = np.array([left_eye, right_eye, nose_tip]) points = np.concatenate((points, np.ones((3, 1))), axis=1) points = points.dot(M.T) # 对图像进行仿变换 aligned_img = cv2.warpAffine(img, M, (img.shape[1], img.shape[0]), flags=cv2.INTER_CUBIC) return aligned_img, points[:, :2] # 读取人脸图像和关键点坐标 img = cv2.imread('face.jpg') left_eye = (100, 200) right_eye = (300, 200) nose_tip = (200, 300) # 进行旋转对齐 aligned_img, aligned_points = align_face(img, left_eye, right_eye, nose_tip) # 在图像上绘制关键点 cv2.circle(img, left_eye, 2, (0, 255, 0), 2) cv2.circle(img, right_eye, 2, (0, 255, 0), 2) cv2.circle(img, nose_tip, 2, (0, 255, 0), 2) cv2.imshow('Original Image', img) # 在旋转后的图像上绘制关键点 cv2.circle(aligned_img, (int(aligned_points[0][0]), int(aligned_points[0][1])), 2, (0, 255, 0), 2) cv2.circle(aligned_img, (int(aligned_points[1][0]), int(aligned_points[1][1])), 2, (0, 255, 0), 2) cv2.circle(aligned_img, (int(aligned_points[2][0]), int(aligned_points[2][1])), 2, (0, 255, 0), 2) cv2.imshow('Aligned Image', aligned_img) cv2.waitKey(0) cv2.destroyAllWindows() ``` 这个程序可以读取一张人脸图像和三个关键点坐标,然后使用这些坐标计算旋转角度,并对图像进行旋转对齐。最后,程序会在原始图像和旋转后的图像上绘制关键点,以便比较两者之间的差异。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值