12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970 |
- import cv2
- import dlib
- import numpy as np
- ## Face detection
- def face_detection(img,upsample_times=1):
- # Ask the detector to find the bounding boxes of each face. The 1 in the
- # second argument indicates that we should upsample the image 1 time. This
- # will make everything bigger and allow us to detect more faces.
- detector = dlib.get_frontal_face_detector()
- faces = detector(img, upsample_times)
- return faces
- PREDICTOR_PATH = 'FaceSwap/models/shape_predictor_68_face_landmarks.dat'
- predictor = dlib.shape_predictor(PREDICTOR_PATH)
- ## Face and points detection
- def face_points_detection(img, bbox:dlib.rectangle):
- # Get the landmarks/parts for the face in box d.
- shape = predictor(img, bbox)
- # loop over the 68 facial landmarks and convert them
- # to a 2-tuple of (x, y)-coordinates
- coords = np.asarray(list([p.x, p.y] for p in shape.parts()), dtype=np.int)
- # return the array of (x, y)-coordinates
- return coords
- def select_face(im, r=10, choose=True):
- faces = face_detection(im)
- if len(faces) == 0:
- return None, None, None
- if len(faces) == 1 or not choose:
- idx = np.argmax([(face.right() - face.left()) * (face.bottom() - face.top()) for face in faces])
- bbox = faces[idx]
- else:
- bbox = []
- def click_on_face(event, x, y, flags, params):
- if event != cv2.EVENT_LBUTTONDOWN:
- return
- for face in faces:
- if face.left() < x < face.right() and face.top() < y < face.bottom():
- bbox.append(face)
- break
- im_copy = im.copy()
- for face in faces:
- # draw the face bounding box
- cv2.rectangle(im_copy, (face.left(), face.top()), (face.right(), face.bottom()), (0, 0, 255), 1)
- cv2.imshow('Click the Face:', im_copy)
- cv2.setMouseCallback('Click the Face:', click_on_face)
- while len(bbox) == 0:
- cv2.waitKey(1)
- cv2.destroyAllWindows()
- bbox = bbox[0]
- points = np.asarray(face_points_detection(im, bbox))
- im_w, im_h = im.shape[:2]
- left, top = np.min(points, 0)
- right, bottom = np.max(points, 0)
- x, y = max(0, left - r), max(0, top - r)
- w, h = min(right + r, im_h) - x, min(bottom + r, im_w) - y
- return points - np.asarray([[x, y]]), (x, y, w, h), im[y:y + h, x:x + w]
|