2024-06-25 01:40:52 -07:00
|
|
|
from mtcnn import MTCNN
|
|
|
|
from facenet_pytorch import MTCNN
|
|
|
|
import torch
|
|
|
|
import math
|
|
|
|
import cv2
|
|
|
|
import numpy as np
|
|
|
|
|
2024-06-27 01:08:10 -07:00
|
|
|
from Face_facial.face_detector import YoloDetector
|
|
|
|
|
2024-06-25 01:40:52 -07:00
|
|
|
K_MULTIPLIER = 1.2
|
|
|
|
|
|
|
|
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
|
|
|
|
detector = MTCNN(keep_all=True, device=device)
|
|
|
|
|
|
|
|
|
|
|
|
class FaceDetection:
|
2024-06-27 01:08:10 -07:00
|
|
|
def __init__(self):
|
|
|
|
self.model = YoloDetector(target_size=720, device="cuda:0", min_face=10)
|
2024-06-25 01:40:52 -07:00
|
|
|
|
|
|
|
def calculate_distance(self, p1, p2) -> float:
|
|
|
|
return math.sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2)
|
|
|
|
|
|
|
|
def calculate_dis_to_cp(self, cx, cy, face_cx, face_cy) -> float:
|
|
|
|
return math.sqrt((face_cx - cx) ** 2 + (face_cy - cy) ** 2)
|
|
|
|
|
2024-06-27 01:08:10 -07:00
|
|
|
def detect_face(self, frame, cx, cy):
|
|
|
|
boxes, landmarks = self.model.predict(frame)
|
|
|
|
|
|
|
|
if len(boxes) > 0:
|
|
|
|
|
|
|
|
for box, landmark in zip(boxes, landmarks):
|
|
|
|
# Draw bounding box
|
|
|
|
x1, y1, x2, y2 = map(int, box)
|
2024-06-25 01:40:52 -07:00
|
|
|
|
2024-06-27 01:08:10 -07:00
|
|
|
face_cx = int(x1 + (x2 - x1) / 2)
|
|
|
|
face_cy = int(y1 + (y2 - y1) / 2)
|
2024-06-25 01:40:52 -07:00
|
|
|
|
2024-06-27 01:08:10 -07:00
|
|
|
if len(landmark) >= 3:
|
|
|
|
nose = landmark[2]
|
|
|
|
left_eye = landmark[0]
|
|
|
|
right_eye = landmark[1]
|
2024-06-25 01:40:52 -07:00
|
|
|
|
2024-06-27 01:08:10 -07:00
|
|
|
# Calculate distances
|
|
|
|
distance_left = self.calculate_distance(nose, left_eye)
|
|
|
|
distance_right = self.calculate_distance(nose, right_eye)
|
2024-06-25 01:40:52 -07:00
|
|
|
|
2024-06-27 01:08:10 -07:00
|
|
|
# Check if distances exceed threshold
|
|
|
|
if not (distance_left > K_MULTIPLIER * distance_right or distance_right > K_MULTIPLIER * distance_left or
|
|
|
|
self.calculate_dis_to_cp(cx, cy, face_cx, face_cy) > 50):
|
|
|
|
return True, True, [x1 - 20, y1 - 20, x2 + 20, y2 + 20]
|
2024-06-25 01:40:52 -07:00
|
|
|
|
2024-06-27 01:08:10 -07:00
|
|
|
return True, False, []
|
2024-06-25 01:40:52 -07:00
|
|
|
|
2024-06-27 01:08:10 -07:00
|
|
|
return False, False
|