起因:在树莓派人脸识别项目中MTCNN人脸对齐帧率过低,大约1s一次对齐,还不算人脸识别时间,
现状:现在整个过程在4s一次,如果有合适的方式欢迎讨论,同时过程中会用到cvzone的人脸mesh网格来判断仰角左右人脸倾角,所以通过mesh网格获得的眼睛坐标完成人脸对齐,方便进一步的人脸识别。需要cvzone==1.5.6 mediapipe库
下面是代码:
import cv2
import numpy as np
from cvzone.FaceMeshModule import FaceMeshDetector
from cvzone.FaceDetectionModule import FaceDetector
detector = FaceMeshDetector(maxFaces=1)
face_detector = FaceDetector()
def align_face(img):
_, faces = face_detector.findFaces(img, draw=False)
if faces:
max_area = 0
max_index = -1
for index, face in enumerate(faces):
x, y, w, h = face["bbox"]
area = w * h
if area > max_area:
max_area = area
max_index = index
x, y, w, h = faces[max_index]["bbox"]
w1, h1 = int(w * 2), int(h * 2)
x1, y1 = int(x - (w1 - w) / 2), int(y - (h1 - h) / 2)
center = (int(x1 + w1 / 2), int(0.9 * (y1 + h1 / 2)))
cropped_image = cv2.getRectSubPix(img, (w1, h1), center)
img, facesMesh = detector.findFaceMesh(cropped_image, draw=False)
if facesMesh:
face = facesMesh[0]
pointLeft = tuple(face[158])
pointRight = tuple(face[385])
angle = np.arctan2(pointRight[1] - pointLeft[1], pointRight[0] - pointLeft[0]) * 180 / np.pi
center_x = (pointLeft[0] + pointRight[0]) / 2
center_y = (pointLeft[1] + pointRight[1]) / 2
M = cv2.getRotationMatrix2D(center=(center_x, center_y), angle=angle, scale=1)
rotated_image = cv2.warpAffine(cropped_image, M, (cropped_image.shape[0], cropped_image.shape[1]))
img2, facesMesh2 = detector.findFaceMesh(rotated_image, draw=False)
if facesMesh2:
face2 = facesMesh2[0]
pointLeft2 = tuple(face2[158])
pointRight2 = tuple(face2[385])
center_x2 = (pointLeft2[0] + pointRight2[0]) / 2
center_y2 = (pointLeft2[1] + pointRight2[1]) / 2
img_height, img_width2 = rotated_image.shape[:2]
eye_vector2, _ = detector.findDistance(pointRight2, pointLeft2)
eye_spacing_rate2 = 10
eye_spacing2 = eye_vector2 * eye_spacing_rate2
img_change_rate2 = float(eye_spacing2 / img_width2)
N = cv2.getRotationMatrix2D(center=(center_x2, center_y2), angle=0, scale=img_change_rate2)
rotated_image2 = cv2.warpAffine(rotated_image, N, (rotated_image.shape[0], rotated_image.shape[1]))
return rotated_image2
return None
if __name__ == '__main__':
# 读取图片
img = cv2.imread('arcface-pytorch-main/image3/18.jpg')
# 对齐人脸
aligned_img = align_face(img)
if aligned_img is not None:
cv2.imshow("Aligned Face", aligned_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
else:
print("No face detected.")
代码中是用一个地址中的图片来演示,可以修改成cv的摄像头更为直观