Spaces:
Runtime error
Runtime error
| 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 = '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=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] | |
| def select_all_faces(im, r=10): | |
| faces = face_detection(im) | |
| if len(faces) == 0: | |
| return None | |
| faceBoxes = {k : {"points" : None, | |
| "shape" : None, | |
| "face" : None} for k in range(len(faces))} | |
| for i, bbox in enumerate(faces): | |
| 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 | |
| faceBoxes[i]["points"] = points - np.asarray([[x, y]]) | |
| faceBoxes[i]["shape"] = (x, y, w, h) | |
| faceBoxes[i]["face"] = im[y:y + h, x:x + w] | |
| return faceBoxes | |