From e1702ea970cf184079cbbfb9ad9b18910449334b Mon Sep 17 00:00:00 2001 From: risotto Date: Thu, 24 Sep 2026 16:13:50 +0200 Subject: [PATCH] base function (face detetion + face recognition) --- src/__init__.py | 0 src/detector.py | 20 ++++++++++++++++++++ src/face_detection.py | 19 +++++++++++++++++++ src/face_recognition.py | 28 ++++++++++++++++++++++++++++ src/main.py | 5 +++++ src/recognizer.py | 16 ++++++++++++++++ src/utils.py | 3 +++ 7 files changed, 91 insertions(+) delete mode 100644 src/__init__.py create mode 100644 src/detector.py create mode 100644 src/face_detection.py create mode 100644 src/face_recognition.py create mode 100644 src/main.py create mode 100644 src/recognizer.py create mode 100644 src/utils.py diff --git a/src/__init__.py b/src/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/detector.py b/src/detector.py new file mode 100644 index 0000000..bd5cb8c --- /dev/null +++ b/src/detector.py @@ -0,0 +1,20 @@ +import cv2 + +class Detector(): + + detector = None + + @classmethod + def get(self): + + if self.detector is None: + self.detector = cv2.FaceDetectorYN.create( + "../models/face_detection_yunet_2026may.onnx", + "", + (320,320), + 0.85, + 0.3, + 5000 + ) + + return self.detector \ No newline at end of file diff --git a/src/face_detection.py b/src/face_detection.py new file mode 100644 index 0000000..31da5fe --- /dev/null +++ b/src/face_detection.py @@ -0,0 +1,19 @@ +import cv2 + +from detector import * + +def detect_in_image(image_path:str, scale = 1): + + img = cv2.imread(image_path) + + imgW = img1.shape[1] * scale + imgH = img1.shape[0] * scale + + img = cv2.resize(img, (imgH, imgW)) + + detector = Detector.get() + detector.setInputSize((imgH, imgW)) + + face = detector.detect(img) + + return face \ No newline at end of file diff --git a/src/face_recognition.py b/src/face_recognition.py new file mode 100644 index 0000000..bdffc70 --- /dev/null +++ b/src/face_recognition.py @@ -0,0 +1,28 @@ +import cv2 + +from recognizer import Recognizer + +def extract_faces(faces:list, img:list, filename:str): + + for i in faces: + face = faces[i] + croped_img = recognizer.alignCrop(img, face[1][0]) + cv2.imwrite(f"../data/extracted/{filename}_{i}.png") + + +def is_same_face( + face1_img:list, + face2_img:list, + cosine_similarity_threshold:float = 0.363, + l2_similarity_threshold:float = 1.128 +) -> bool: + + recognizer = Recognizer.get() + + faces1_features = recognizer.feature(face1_img) + faces2_features = recognizer.feature(face2_img) + + cosine_score = recognizer.match(faces1_features, faces2_features, cv2.FaceRecognizerSF_FR_COSINE) + l2_score = recognizer.match(faces1_features, faces2_features, cv2.FaceRecognizerSF_FR_NORM_L2) + + return cosine_score >= cosine_similarity_threshold and l2_score <= l2_similarity_threshold \ No newline at end of file diff --git a/src/main.py b/src/main.py new file mode 100644 index 0000000..6c08a72 --- /dev/null +++ b/src/main.py @@ -0,0 +1,5 @@ +import cv2 + +from face_detection import * +from face_recognition import * + diff --git a/src/recognizer.py b/src/recognizer.py new file mode 100644 index 0000000..b4bff79 --- /dev/null +++ b/src/recognizer.py @@ -0,0 +1,16 @@ +import cv2 + +class Recognizer(): + + recognizer = None + + @classmethod + def get(self): + + if self.recognizer is None: + recognizer = cv2.FaceRecognizerSF.create( + "../models/face_recognition_sface_2021dec_int8.onnx", + "" + ) + + return self.recognizer \ No newline at end of file diff --git a/src/utils.py b/src/utils.py new file mode 100644 index 0000000..e994258 --- /dev/null +++ b/src/utils.py @@ -0,0 +1,3 @@ + + +def load_image \ No newline at end of file