def matchFacesFromImages(): """ Match faces from images. """ faceEngine = VLFaceEngine() detector = faceEngine.createFaceDetector(DetectorType.FACE_DET_V1) extractor = faceEngine.createFaceDescriptorEstimator() warper = faceEngine.createFaceWarper() matcher = faceEngine.createFaceMatcher() image1 = VLImage.load(filename=EXAMPLE_O) faceDetection1 = detector.detectOne(image1) warp1 = warper.warp(faceDetection1) descriptor1 = extractor.estimate(warp1.warpedImage) image2 = VLImage.load(filename=EXAMPLE_1) faceDetection2 = detector.detectOne(image2) warp2 = warper.warp(faceDetection2) descriptor2 = extractor.estimate(warp2.warpedImage) batch, _ = extractor.estimateDescriptorsBatch( [warp1.warpedImage, warp2.warpedImage]) print(matcher.match(descriptor1, descriptor2)) print(matcher.match(descriptor1, batch)) print(matcher.match(descriptor1, [descriptor2, descriptor1]))
def buildDescriptorIndex(): """ Build index and search. """ faceEngine = VLFaceEngine() detector = faceEngine.createFaceDetector(DetectorType.FACE_DET_V3) warper = faceEngine.createFaceWarper() extractor = faceEngine.createFaceDescriptorEstimator() descriptorsBatch = faceEngine.createFaceDescriptorFactory( ).generateDescriptorsBatch(2) for image in (EXAMPLE_O, EXAMPLE_1): vlImage = VLImage.load(filename=image) faceDetection = detector.detectOne(vlImage) warp = warper.warp(faceDetection) faceDescriptor = extractor.estimate(warp.warpedImage) descriptorsBatch.append(faceDescriptor) indexBuilder = faceEngine.createIndexBuilder() indexBuilder.appendBatch(descriptorsBatch) pprint.pprint(f"index buf size: {indexBuilder.bufSize}") index = indexBuilder.buildIndex() pprint.pprint(index[0]) result = index.search(faceDescriptor, 1) pprint.pprint(f"result: {result}")
async def asyncEstimateDescriptor(): """ Async estimate face descriptor. """ image = VLImage.load(filename=EXAMPLE_O) faceEngine = VLFaceEngine() detector = faceEngine.createFaceDetector(DetectorType.FACE_DET_V3) faceDetection = detector.detectOne(image) warper = faceEngine.createFaceWarper() warp = warper.warp(faceDetection) extractor = faceEngine.createFaceDescriptorEstimator() pprint.pprint(await extractor.estimateDescriptorsBatch( [warp.warpedImage, warp.warpedImage], asyncEstimate=True)) # run tasks and get results task1 = extractor.estimate(warp.warpedImage, asyncEstimate=True) task2 = extractor.estimate(warp.warpedImage, asyncEstimate=True) for task in (task1, task2): pprint.pprint(task.get().asDict())
def estimateDescriptor(): """ Estimate face descriptor. """ image = VLImage.load(filename=EXAMPLE_O) faceEngine = VLFaceEngine() detector = faceEngine.createFaceDetector(DetectorType.FACE_DET_V3) faceDetection = detector.detectOne(image) warper = faceEngine.createFaceWarper() warp = warper.warp(faceDetection) extractor = faceEngine.createFaceDescriptorEstimator() pprint.pprint(extractor.estimate(warp.warpedImage)) pprint.pprint( extractor.estimateDescriptorsBatch( [warp.warpedImage, warp.warpedImage])) batch, aggregateDescriptor = extractor.estimateDescriptorsBatch( [warp.warpedImage, warp.warpedImage], aggregate=True) pprint.pprint(batch) pprint.pprint(aggregateDescriptor)
class FaceEstimatorsCollection: """ Collection of lazy load face estimators. Attributes: _headPoseEstimator (Optional[HeadPoseEstimator]): lazy load head pose estimator _eyeEstimator (Optional[EyeEstimator]): lazy load eye estimator _gazeDirectionEstimator (Optional[GazeEstimator]): lazy load gaze direction estimator _mouthStateEstimator (Optional[MouthStateEstimator]): lazy load mouth state estimator _warpQualityEstimator (Optional[WarpQualityEstimator]): lazy load warp quality estimator _basicAttributesEstimator (Optional[BasicAttributesEstimator]): lazy load basic attributes estimator _emotionsEstimator (Optional[EmotionsEstimator]): lazy load emotions estimator _AGSEstimator (Optional[AGSEstimator]): lazy load ags estimator _descriptorEstimator (Optional[FaceDescriptorEstimator]): lazy load face descriptor estimator warper (Optional[Warper]): warper """ __slots__ = ( "_headPoseEstimator", "_eyeEstimator", "_gazeDirectionEstimator", "_mouthStateEstimator", "_warpQualityEstimator", "_basicAttributesEstimator", "_emotionsEstimator", "_faceEngine", "_AGSEstimator", "warper", "_descriptorEstimator", ) def __init__(self, startEstimators: Optional[List[FaceEstimator]] = None, faceEngine: Optional[VLFaceEngine] = None): """ Init. Args: startEstimators: list of estimators which will be initiate now faceEngine: faceengine, factory for estimators """ if faceEngine is None: self._faceEngine = VLFaceEngine() else: self._faceEngine = faceEngine self._basicAttributesEstimator = None self._eyeEstimator = None self._emotionsEstimator = None self._gazeDirectionEstimator = None self._mouthStateEstimator = None self._warpQualityEstimator = None self._headPoseEstimator = None self._AGSEstimator = None self._descriptorEstimator = None self.warper = self._faceEngine.createWarper() if startEstimators: for estimator in set(startEstimators): self.initEstimator(estimator) @staticmethod def _getEstimatorByAttributeName( estimatorAttributeName: str) -> FaceEstimator: """ Get face estimator by attribute name which corresponding to estimator Args: estimatorAttributeName: name Returns: corresponding face estimator Raises: ValueError("Bad attribute name"): if face estimator not found """ for estimator in FaceEstimator: if estimator.name.lower( ) == estimatorAttributeName[1:-len("Estimator")]: return estimator raise ValueError("Bad attribute name") def _getAttributeNameByEstimator(self, estimator: FaceEstimator) -> str: """ Get an estimator attribute name bya face estimator Args: estimator: face estimator Returns: corresponding attribute name Raises: ValueError("Bad estimator"): if attribute name not found """ for estimatorName in self.__slots__: if estimatorName == "_faceEngine": continue if estimator.name.lower() == estimatorName[1:-len("Estimator")]: return estimatorName raise ValueError("Bad estimator") def initEstimator(self, estimator: FaceEstimator) -> None: """ Create an estimator. Create new estimator with help self._faceengine Args: estimator: estimator for creating Raises: ValueError("Bad estimator type"): if estimator not found """ if estimator == FaceEstimator.BasicAttributes: self._basicAttributesEstimator = self._faceEngine.createBasicAttributesEstimator( ) elif estimator == FaceEstimator.Eye: self._eyeEstimator = self._faceEngine.createEyeEstimator() elif estimator == FaceEstimator.Emotions: self._emotionsEstimator = self._faceEngine.createEmotionEstimator() elif estimator == FaceEstimator.GazeDirection: self._gazeDirectionEstimator = self._faceEngine.createGazeEstimator( ) elif estimator == FaceEstimator.MouthState: self._mouthStateEstimator = self._faceEngine.createMouthEstimator() elif estimator == FaceEstimator.WarpQuality: self._warpQualityEstimator = self._faceEngine.createWarpQualityEstimator( ) elif estimator == FaceEstimator.HeadPose: self._headPoseEstimator = self._faceEngine.createHeadPoseEstimator( ) elif estimator == FaceEstimator.AGS: self._AGSEstimator = self._faceEngine.createAGSEstimator() elif estimator == FaceEstimator.Descriptor: self._descriptorEstimator = self._faceEngine.createFaceDescriptorEstimator( ) else: raise ValueError("Bad estimator type") @property def descriptorEstimator(self) -> FaceDescriptorEstimator: """ Get head pose estimator. If estimator is initialized it will be returned otherwise it will be initialized and returned Returns: estimator """ if self._descriptorEstimator is None: self._descriptorEstimator = self._faceEngine.createFaceDescriptorEstimator( ) return self._descriptorEstimator @property def headPoseEstimator(self) -> HeadPoseEstimator: """ Get head pose estimator. If estimator is initialized it will be returned otherwise it will be initialized and returned Returns: estimator """ if self._headPoseEstimator is None: self._headPoseEstimator = self._faceEngine.createHeadPoseEstimator( ) return self._headPoseEstimator @headPoseEstimator.setter def headPoseEstimator(self, newEstimator: HeadPoseEstimator) -> None: """ Set head pose estimator. Args: newEstimator: new estimator """ self._headPoseEstimator = newEstimator # pylint: disable=C0103 @property def AGSEstimator(self) -> AGSEstimator: """ Get ags estimator. If estimator is initialized it will be returned otherwise it will be initialized and returned Returns: estimator """ if self._AGSEstimator is None: self._AGSEstimator = self._faceEngine.createAGSEstimator() return self._AGSEstimator # pylint: disable=C0103 @AGSEstimator.setter def AGSEstimator(self, newEstimator: AGSEstimator) -> None: """ Set ags estimator. Args: newEstimator: new estimator """ self._AGSEstimator = newEstimator @property def basicAttributesEstimator(self) -> BasicAttributesEstimator: """ Get basic attributes estimator. If estimator is initialized it will be returned otherwise it will be initialized and returned Returns: estimator """ if self._basicAttributesEstimator is None: self._basicAttributesEstimator = self._faceEngine.createBasicAttributesEstimator( ) return self._basicAttributesEstimator @basicAttributesEstimator.setter def basicAttributesEstimator( self, newEstimator: BasicAttributesEstimator) -> None: """ Set basic attributes estimator. Args: newEstimator: new estimator """ self._basicAttributesEstimator = newEstimator @property def eyeEstimator(self) -> EyeEstimator: """ Get eye estimator. If estimator is initialized it will be returned otherwise it will be initialized and returned Returns: estimator """ if self._eyeEstimator is None: self._eyeEstimator = self._faceEngine.createEyeEstimator() return self._eyeEstimator @eyeEstimator.setter def eyeEstimator(self, newEstimator: EyeEstimator) -> None: """ Set eye estimator. Args: newEstimator: new estimator """ self._eyeEstimator = newEstimator @property def emotionsEstimator(self) -> EmotionsEstimator: """ Get emotions estimator. If estimator is initialized it will be returned otherwise it will be initialized and returned Returns: estimator """ if self._emotionsEstimator is None: self._emotionsEstimator = self._faceEngine.createEmotionEstimator() return self._emotionsEstimator @emotionsEstimator.setter def emotionsEstimator(self, newEstimator: EmotionsEstimator) -> None: """ Set emotions estimator. Args: newEstimator: new estimator """ self._emotionsEstimator = newEstimator @property def gazeDirectionEstimator(self) -> GazeEstimator: """ Get gaze direction estimator. If estimator is initialized it will be returned otherwise it will be initialized and returned Returns: estimator """ if self._gazeDirectionEstimator is None: self._gazeDirectionEstimator = self._faceEngine.createGazeEstimator( ) return self._gazeDirectionEstimator @gazeDirectionEstimator.setter def gazeDirectionEstimator(self, newEstimator: GazeEstimator) -> None: """ Set gaze direction estimator. Args: newEstimator: new estimator """ self._gazeDirectionEstimator = newEstimator @property def mouthStateEstimator(self) -> MouthStateEstimator: """ Get mouth state estimator. If estimator is initialized it will be returned otherwise it will be initialized and returned Returns: estimator """ if self._mouthStateEstimator is None: self._mouthStateEstimator = self._faceEngine.createMouthEstimator() return self._mouthStateEstimator @mouthStateEstimator.setter def mouthStateEstimator(self, newEstimator: MouthStateEstimator) -> None: """ Set mouth state estimator. Args: newEstimator: new estimator """ self._mouthStateEstimator = newEstimator @property def warpQualityEstimator(self) -> WarpQualityEstimator: """ Get warp quality estimator. If estimator is initialized it will be returned otherwise it will be initialized and returned Returns: estimator """ if self._warpQualityEstimator is None: self._warpQualityEstimator = self._faceEngine.createWarpQualityEstimator( ) return self._warpQualityEstimator @warpQualityEstimator.setter def warpQualityEstimator(self, newEstimator: WarpQualityEstimator) -> None: """ Set warp quality estimator. Args: newEstimator: new estimator """ self._warpQualityEstimator = newEstimator @property def faceEngine(self) -> VLFaceEngine: """ Get current faceengine. Returns: self._faceEngine """ return self._faceEngine @faceEngine.setter def faceEngine(self, newFaceEngine: VLFaceEngine) -> None: """ Set new faceengine. All initialize estimators will be re-initialized. Args: newFaceEngine: new faceengine """ self._faceEngine = newFaceEngine for estimatorName in self.__slots__: if estimatorName == "_faceEngine": continue if getattr(self, estimatorName) is not None: self.initEstimator( FaceEstimatorsCollection._getEstimatorByAttributeName( estimatorName)) self.warper = self._faceEngine.createWarper() def removeEstimator(self, estimator: FaceEstimator) -> None: """ Remove estimators. Args: estimator: estimator for removing """ estimatorName = self._getAttributeNameByEstimator(estimator) setattr(self, estimatorName, None)