Python to Detect Align Faces with Full Source Code For Beginners

This algorithm can detect the faces from pictures and then align them.

Requirements:

  • dlib==19.22.1
  • numpy==1.21.2
  • opencv-python==4.5.3.56

Run the Script:

python3 main.py [pic1, pic2...]
Code language: CSS (css)
  • After the script is finished, you will get some faces picture in the same directory.

Source Code:

dectect_faces.py

import numpy as np import os.path as osp import sys import cv2 import dlib OUT_SIZE = (224, 224) LEFT_EYE_RANGE = (36, 42) RIGHT_EYE_RABGE = (42, 48) LEFT_EYE_POS = (0.35, 0.3815) DAT_PATH = "./dat/shape_predictor_68_face_landmarks.dat" def main(files): detector = dlib.get_frontal_face_detector() sp = dlib.shape_predictor(DAT_PATH) for file in files: img = cv2.imread(file, cv2.IMREAD_ANYCOLOR) img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) faces = detect_align_faces(detector, sp, img) for (idx, face) in enumerate(faces): face = cv2.cvtColor(face, cv2.COLOR_RGB2BGR) filename, ext = osp.splitext(file) filename += '_face_{:03}'.format(idx) + ext cv2.imwrite(filename, face) def detect_align_faces(detector, sp, img): faces = detector(img, 1) res = [] for face in faces: shape = sp(img, face) left, right = shape_to_pos(shape) left_center = np.mean(left, axis=0) right_center = np.mean(right, axis=0) dx = right_center[0] - left_center[0] dy = right_center[1] - left_center[1] angle = np.degrees(np.arctan2(dy, dx)) dist = np.sqrt(dy ** 2 + dx ** 2) out_dist = OUT_SIZE[0] * (1 - 2 * LEFT_EYE_POS[0]) scale = out_dist / dist center = ((left_center + right_center) // 2).tolist() mat = cv2.getRotationMatrix2D(center, angle, scale) mat[0, 2] += (0.5 * OUT_SIZE[0] - center[0]) mat[1, 2] += (LEFT_EYE_POS[1] * OUT_SIZE[1] - center[1]) res_face = cv2.warpAffine(img, mat, OUT_SIZE, flags=cv2.INTER_CUBIC) res.append(res_face) return res def shape_to_pos(shape): parts = [] for p in shape.parts(): parts.append((p.x, p.y)) left = parts[LEFT_EYE_RANGE[0]: LEFT_EYE_RANGE[-1]] right = parts[RIGHT_EYE_RABGE[0]: RIGHT_EYE_RABGE[-1]] return (np.array(left), np.array(right)) if __name__ == '__main__': main(sys.argv[1:])
Code language: JavaScript (javascript)

Leave a Comment