|
import time |
|
import face_alignment |
|
import numpy as np |
|
import cv2 |
|
|
|
from DDFA_V2.FaceBoxes.FaceBoxes_ONNX import FaceBoxes_ONNX |
|
|
|
|
|
class FaceBoxEstimator: |
|
def __init__(self, device): |
|
device_idx = int(device.split(':')[-1]) |
|
providers = [ |
|
('CUDAExecutionProvider', { |
|
'device_id': device_idx, |
|
}), |
|
'CPUExecutionProvider', |
|
] |
|
self.face_boxes = FaceBoxes_ONNX(providers=providers) |
|
self.bboxes = [] |
|
|
|
def add_box(self, box): |
|
self.bboxes.append(box) |
|
|
|
if len(self.bboxes) > 5: |
|
self.bboxes.pop(0) |
|
|
|
def clear_history(self): |
|
self.bboxes = [] |
|
|
|
def get_current_box(self): |
|
return np.mean(self.bboxes, axis=0) |
|
|
|
def __call__(self, img): |
|
boxes = self.face_boxes(img) |
|
|
|
if len(boxes) == 0: |
|
return boxes |
|
|
|
self.add_box(boxes[0]) |
|
return [self.get_current_box()] |
|
|
|
|
|
class FaceDetector: |
|
def __init__(self, device): |
|
self.facebox_detector = FaceBoxEstimator(device) |
|
self.fa = face_alignment.FaceAlignment( |
|
face_alignment.LandmarksType.TWO_D, flip_input=False, device=device |
|
) |
|
|
|
self.keypoints = [] |
|
|
|
def add(self, kps): |
|
self.keypoints.append(kps) |
|
|
|
if len(self.keypoints) > 5: |
|
self.keypoints.pop(0) |
|
|
|
def clear_history(self): |
|
self.bboxes = [] |
|
|
|
def get_current_keypoints(self): |
|
return np.mean(self.keypoints, axis=0) |
|
|
|
def __call__(self, img): |
|
img = np.array(img) |
|
scale_factor = 512 / max(img.shape[0], img.shape[1]) |
|
img = cv2.resize(img, (0, 0), fx=scale_factor, fy=scale_factor) |
|
|
|
bbox = self.facebox_detector(img) |
|
landmarks = self.fa.get_landmarks(img, detected_faces=bbox) |
|
|
|
if landmarks is None: |
|
return None, None |
|
|
|
landmarks = np.array(landmarks)[0] / scale_factor |
|
bbox = np.array(bbox)[0] / scale_factor |
|
|
|
self.add(landmarks) |
|
landmarks = self.get_current_keypoints() |
|
|
|
return landmarks, bbox |
|
|
|
|
|
if __name__ == '__main__': |
|
from PIL import Image |
|
detector = FaceDetector() |
|
|
|
img = Image.open('00000/00008.png') |
|
lm, bbox = detector(img) |
|
bbox = bbox.astype(int) |
|
|
|
print('Score:', bbox[-1]) |
|
img = np.array(img) |
|
cv2.rectangle(img, bbox[:2], bbox[2:4], (255, 0, 0), thickness=5) |
|
img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR) |
|
img = cv2.resize(img, (0, 0), fx=0.2, fy=0.2) |
|
cv2.imshow('debug', img) |
|
cv2.waitKey(-1) |
|
|