| | |
| | |
| | |
| | |
| | |
| |
|
| | import numpy as np |
| | import cv2 as cv |
| |
|
| | class SFace: |
| | def __init__(self, modelPath, disType=0, backendId=0, targetId=0): |
| | self._modelPath = modelPath |
| | self._backendId = backendId |
| | self._targetId = targetId |
| | self._model = cv.FaceRecognizerSF.create( |
| | model=self._modelPath, |
| | config="", |
| | backend_id=self._backendId, |
| | target_id=self._targetId) |
| |
|
| | self._disType = disType |
| | assert self._disType in [0, 1], "0: Cosine similarity, 1: norm-L2 distance, others: invalid" |
| |
|
| | self._threshold_cosine = 0.363 |
| | self._threshold_norml2 = 1.128 |
| |
|
| | @property |
| | def name(self): |
| | return self.__class__.__name__ |
| |
|
| | def setBackendAndTarget(self, backendId, targetId): |
| | self._backendId = backendId |
| | self._targetId = targetId |
| | self._model = cv.FaceRecognizerSF.create( |
| | model=self._modelPath, |
| | config="", |
| | backend_id=self._backendId, |
| | target_id=self._targetId) |
| |
|
| | def _preprocess(self, image, bbox): |
| | if bbox is None: |
| | return image |
| | else: |
| | return self._model.alignCrop(image, bbox) |
| |
|
| | def infer(self, image, bbox=None): |
| | |
| | inputBlob = self._preprocess(image, bbox) |
| |
|
| | |
| | features = self._model.feature(inputBlob) |
| | return features |
| |
|
| | def match(self, image1, face1, image2, face2): |
| | feature1 = self.infer(image1, face1) |
| | feature2 = self.infer(image2, face2) |
| |
|
| | if self._disType == 0: |
| | cosine_score = self._model.match(feature1, feature2, self._disType) |
| | return cosine_score, 1 if cosine_score >= self._threshold_cosine else 0 |
| | else: |
| | norml2_distance = self._model.match(feature1, feature2, self._disType) |
| | return norml2_distance, 1 if norml2_distance <= self._threshold_norml2 else 0 |
| |
|