一般来说,使用 mtcnn
网络检测到人脸后,都需要进行矫正。而对于人脸矫正,最简单的可以通过使用仿射变换来实现。
思路:
- 通过 mtcnn 模型检测到人脸的 5 个特征点:左眼,右眼,鼻子,左嘴角,右嘴角;
bounding_boxes = { 'box': [int(bounding_box[0]), int(bounding_box[1]), int(bounding_box[2]), int(bounding_box[3])], 'confidence': bounding_box[-1], 'keypoints': { 'left_eye': (int(keypoints[0]), int(keypoints[5])), 'right_eye': (int(keypoints[1]), int(keypoints[6])), 'nose': (int(keypoints[2]), int(keypoints[7])), 'mouth_left': (int(keypoints[3]), int(keypoints[8])), 'mouth_right': (int(keypoints[4]), int(keypoints[9])), } }
bounding_box = bounding_boxes['box'] keypoints = bounding_boxes['keypoints']
|
- 计算双眼中心点的位置
eye_center
和双眼连线的倾斜角度 angle
;
- 通过
eye_center
和 angle
得到仿射变换矩阵 rot_matrix
;
- 将整张图片进行仿射变换得到
align_image
;
def align_face(image, keypoints, scale=1.0): eye_center = ( (keypoints['left_eye'][0] + keypoints['right_eye'][0]) * 0.5, (keypoints['left_eye'][1] + keypoints['right_eye'][1]) * 0.5, ) dx = keypoints['right_eye'][0] - keypoints['left_eye'][0] dy = keypoints['right_eye'][1] - keypoints['left_eye'][1]
angle = cv2.fastAtan2(dy, dx) rot_matrix = cv2.getRotationMatrix2D(eye_center, angle, scale=scale) rot_image = cv2.warpAffine(image, rot_matrix, dsize=(image.shape[1], image.shape[0])) return rot_image
align_image = align_face(image, keypoints)
|
- 根据从 原图检测的 2D 框从
align_image
图片中抠出人脸并保存。
xmin = bounding_box[0] ymin = bounding_box[1] xmax = bounding_box[2] ymax = bounding_box[3] crop_image = align_image[ymin:ymax, xmin:xmax, :] cv2.imwrite("align_face.jpg", crop_image)
|