Python代码人脸校正:根据检测到的人脸朝向,将人脸图像校正为正面、上下对称的标准头像。具体实现方法可以采用基于仿射变换的图像校正算法,如Delaunay三角剖分算法。
时间: 2024-05-02 11:18:01 浏览: 199
以下是一个基于Delaunay三角剖分的人脸校正示例代码:
```python
import cv2
import numpy as np
import dlib
# 加载人脸检测器和预测器
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
# 定义Delaunay三角剖分函数
def apply_delaunay(points, img):
rect = (0, 0, img.shape[1], img.shape[0])
subdiv = cv2.Subdiv2D(rect)
for p in points:
subdiv.insert((int(p[0]), int(p[1])))
triangleList = subdiv.getTriangleList()
triangles = np.zeros((len(triangleList), 3), dtype=np.int32)
for i in range(len(triangleList)):
t = triangleList[i]
pt1 = (t[0], t[1])
pt2 = (t[2], t[3])
pt3 = (t[4], t[5])
tri = [np.where((points == pt1).all(axis=1))[0][0],
np.where((points == pt2).all(axis=1))[0][0],
np.where((points == pt3).all(axis=1))[0][0]]
triangles[i,:] = tri
return triangles
# 定义人脸校正函数
def align_face(img):
# 检测人脸
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = detector(gray, 1)
if len(faces) == 0:
return None
# 提取人脸关键点
shape = predictor(gray, faces[0])
landmarks = np.array([[p.x, p.y] for p in shape.parts()])
# 计算人脸朝向
vec_left = landmarks[36] - landmarks[45]
vec_right = landmarks[17] - landmarks[26]
angle = np.arctan2(vec_left[1]*vec_right[0]-vec_left[0]*vec_right[1], vec_left[0]*vec_right[0]+vec_left[1]*vec_right[1])/np.pi*180
# 计算仿射变换矩阵
center = (landmarks[36] + landmarks[45]) / 2
M = cv2.getRotationMatrix2D(tuple(center), angle, 1)
img_rotated = cv2.warpAffine(img, M, (img.shape[1], img.shape[0]))
# 校正人脸
landmarks_rotated = np.concatenate((landmarks, np.ones((68,1))), axis=1)
landmarks_rotated = landmarks_rotated.dot(M.T)
triangles = apply_delaunay(landmarks_rotated[:,:2], img_rotated)
img_aligned = np.zeros_like(img)
for i in range(len(triangles)):
tri = triangles[i,:]
pts1 = landmarks[tri,:]
pts2 = landmarks_rotated[tri,:]
affine = cv2.getAffineTransform(pts2[:3], pts1[:3])
mask = np.zeros_like(gray)
cv2.fillConvexPoly(mask, pts1.astype(np.int32), 1)
mask = cv2.warpAffine(mask, affine, (mask.shape[1], mask.shape[0]), flags=cv2.INTER_NEAREST)
img_aligned[:,:,0] += img_rotated[:,:,0]*mask
img_aligned[:,:,1] += img_rotated[:,:,1]*mask
img_aligned[:,:,2] += img_rotated[:,:,2]*mask
return img_aligned
# 加载测试图像
img = cv2.imread("test.jpg")
# 校正人脸
img_aligned = align_face(img)
# 显示结果
cv2.imshow("Original Image", img)
cv2.imshow("Aligned Image", img_aligned)
cv2.waitKey(0)
```
在该示例代码中,我们首先使用dlib的人脸检测器和预测器检测和提取人脸关键点,然后根据关键点计算人脸朝向和仿射变换矩阵,最后使用Delaunay三角剖分算法对人脸图像进行校正。根据测试图像的不同,可能需要对人脸检测器和预测器的参数进行调整,以获取更好的校正效果。
阅读全文