opencv pseudo batching

This commit is contained in:
galthran-wq 2025-02-12 15:49:35 +00:00
parent 737ee793dc
commit b2d6178bed

View File

@ -1,6 +1,6 @@
# built-in dependencies # built-in dependencies
import os import os
from typing import Any, List from typing import Any, List, Union
# 3rd party dependencies # 3rd party dependencies
import cv2 import cv2
@ -29,55 +29,56 @@ class OpenCvClient(Detector):
detector["eye_detector"] = self.__build_cascade("haarcascade_eye") detector["eye_detector"] = self.__build_cascade("haarcascade_eye")
return detector return detector
def detect_faces(self, img: np.ndarray) -> List[FacialAreaRegion]: def detect_faces(self, imgs: Union[np.ndarray, List[np.ndarray]]) -> Union[List[FacialAreaRegion], List[List[FacialAreaRegion]]]:
""" """
Detect and align face with opencv Detect and align face with opencv
Args: Args:
img (np.ndarray): pre-loaded image as numpy array imgs (Union[np.ndarray, List[np.ndarray]]): pre-loaded image as numpy array or a list of those
Returns: Returns:
results (List[FacialAreaRegion]): A list of FacialAreaRegion objects results (Union[List[FacialAreaRegion], List[List[FacialAreaRegion]]]): A list or a list of lists of FacialAreaRegion objects
""" """
resp = [] if isinstance(imgs, np.ndarray):
imgs = [imgs]
detected_face = None batch_results = []
faces = [] for img in imgs:
try: resp = []
# faces = detector["face_detector"].detectMultiScale(img, 1.3, 5) detected_face = None
faces = []
# note that, by design, opencv's haarcascade scores are >0 but not capped at 1 try:
faces, _, scores = self.model["face_detector"].detectMultiScale3( faces, _, scores = self.model["face_detector"].detectMultiScale3(
img, 1.1, 10, outputRejectLevels=True img, 1.1, 10, outputRejectLevels=True
)
except:
pass
if len(faces) > 0:
for (x, y, w, h), confidence in zip(faces, scores):
detected_face = img[int(y) : int(y + h), int(x) : int(x + w)]
left_eye, right_eye = self.find_eyes(img=detected_face)
# eyes found in the detected face instead image itself
# detected face's coordinates should be added
if left_eye is not None:
left_eye = (int(x + left_eye[0]), int(y + left_eye[1]))
if right_eye is not None:
right_eye = (int(x + right_eye[0]), int(y + right_eye[1]))
facial_area = FacialAreaRegion(
x=x,
y=y,
w=w,
h=h,
left_eye=left_eye,
right_eye=right_eye,
confidence=(100 - confidence) / 100,
) )
resp.append(facial_area) except:
pass
return resp if len(faces) > 0:
for (x, y, w, h), confidence in zip(faces, scores):
detected_face = img[int(y):int(y + h), int(x):int(x + w)]
left_eye, right_eye = self.find_eyes(img=detected_face)
if left_eye is not None:
left_eye = (int(x + left_eye[0]), int(y + left_eye[1]))
if right_eye is not None:
right_eye = (int(x + right_eye[0]), int(y + right_eye[1]))
facial_area = FacialAreaRegion(
x=x,
y=y,
w=w,
h=h,
left_eye=left_eye,
right_eye=right_eye,
confidence=(100 - confidence) / 100,
)
resp.append(facial_area)
batch_results.append(resp)
return batch_results if len(batch_results) > 1 else batch_results[0]
def find_eyes(self, img: np.ndarray) -> tuple: def find_eyes(self, img: np.ndarray) -> tuple:
""" """