| |
| |
| |
| |
| |
|
|
| 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 |
|
|