Source code for lunavl.sdk.faceengine.matcher
"""
Module realize face descriptor match.
see `face descriptors matching`_.
"""
from abc import abstractmethod
from typing import List, Union
from FaceEngine import IDescriptorMatcherPtr # pylint: disable=E0611,E0401
from lunavl.sdk.errors.errors import LunaVLError
from lunavl.sdk.errors.exceptions import LunaSDKException
from lunavl.sdk.estimators.face_estimators.face_descriptor import FaceDescriptor, FaceDescriptorBatch
from lunavl.sdk.faceengine.descriptors import FaceDescriptorFactory
[docs]class MatchingResult:
"""
Structure for storing matching results.
Attributes:
distance (float): L2 distance between descriptors
similarity (float): descriptor similarity [0..1]
"""
__slots__ = ('distance', 'similarity')
def __init__(self, distance: float, similarity: float):
self.distance = distance
self.similarity = similarity
[docs]class FaceMatcher:
"""
Base estimator class. Class is a container for core estimations. Mostly estimate attributes can be get through
a corresponding properties.
Attributes:
_coreMatcher (IDescriptorMatcherPtr): core matcher
descriptorFactory (FaceDescriptorFactory): face descriptor factory
"""
__slots__ = ('_coreMatcher', 'descriptorFactory')
def __init__(self, coreMatcher: IDescriptorMatcherPtr, descriptorFactory: FaceDescriptorFactory):
"""
Init.
Args:
coreMatcher: core matcher
"""
self._coreMatcher = coreMatcher
self.descriptorFactory = descriptorFactory
[docs] @abstractmethod
def match(self, reference: FaceDescriptor,
candidates: Union[FaceDescriptor, List[FaceDescriptor],
FaceDescriptorBatch]) -> Union[MatchingResult, List[MatchingResult]]:
"""
Match face descriptor vs face descriptors.
Returns:
List of matching results if match by several descriptors otherwise one MatchingResult.
"""
if isinstance(candidates, FaceDescriptor):
error = self._coreMatcher.match(reference.coreEstimation, candidates.coreEstimation)
if error.isError:
raise LunaSDKException(LunaVLError.fromSDKError(error))
return error.value
elif isinstance(candidates, FaceDescriptorBatch):
error, matchResults = self._coreMatcher.match(reference.coreEstimation, candidates.coreEstimation)
if error.isError:
raise LunaSDKException(LunaVLError.fromSDKError(error))
return matchResults
else:
batch = self.descriptorFactory.generateDescriptorsBatch(len(candidates))
for candidate in candidates:
batch.append(candidate)
error, matchResults = self._coreMatcher.match(reference.coreEstimation, batch.coreEstimation)
if error.isError:
raise LunaSDKException(LunaVLError.fromSDKError(error))
return matchResults