Beispiel #1
0
    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
Beispiel #2
0
    def estimateBasicAttributesBatch(
        self,
        warps: List[Union[FaceWarp, FaceWarpedImage]],
        estimateAge: bool,
        estimateGender: bool,
        estimateEthnicity: bool,
        aggregate: bool = False,
    ) -> Tuple[List[BasicAttributes], Union[None, BasicAttributes]]:
        """
        Batch basic attributes estimation on warped images.

        Args:
            warps: warped images
            estimateAge: estimate age or not
            estimateGender: estimate gender or not
            estimateEthnicity: estimate ethnicity or not
            aggregate:  aggregate attributes to one or not

        Returns:
            tuple, first element - list estimated attributes in corresponding order,
            second - optional aggregated attributes.
        Raises:
            LunaSDKException: if estimation failed
        """
        dtAttributes = 0
        if estimateAge:
            dtAttributes |= AttributeRequest.estimateAge
        if estimateGender:
            dtAttributes |= AttributeRequest.estimateGender
        if estimateEthnicity:
            dtAttributes |= AttributeRequest.estimateEthnicity

        images = [warp.warpedImage.coreImage for warp in warps]

        error, baseAttributes, aggregateAttribute = self._coreEstimator.estimate(images, AttributeRequest(dtAttributes))
        if error.isError:
            errors = []
            for image in images:
                errorOne, baseAttributesOne = self._coreEstimator.estimate(image, AttributeRequest(dtAttributes))
                if errorOne.isOk:
                    errors.append(LunaVLError.Ok.format(LunaVLError.Ok.description))
                else:
                    errors.append(LunaVLError.fromSDKError(errorOne))
            raise LunaSDKException(
                LunaVLError.BatchedInternalError.format(LunaVLError.fromSDKError(error).detail), errors
            )

        attributes = [BasicAttributes(baseAttribute) for baseAttribute in baseAttributes]
        if aggregate:
            return attributes, BasicAttributes(aggregateAttribute)
        else:
            return attributes, None
Beispiel #3
0
def estimate(
    warp: Union[HumanWarp, HumanWarpedImage, FaceWarp, FaceWarpedImage],
    descriptorFactory: BaseDescriptorFactory,
    coreEstimator: IDescriptorExtractorPtr,
    descriptor: Optional[BaseDescriptor] = None,
) -> BaseDescriptor:
    """
    Estimate a face descriptor or a human descriptor from the warped image.

    Args:
        warp: warped image
        descriptor: descriptor for saving extract result
        descriptorFactory: descriptor factory
        coreEstimator: descriptor extractor
    Returns:
        estimated descriptor
    Raises:
        LunaSDKException: if estimation failed
    """
    if descriptor is None:
        descriptor = descriptorFactory.generateDescriptor()
        coreDescriptor = descriptor.coreEstimation
    else:
        coreDescriptor = descriptor.coreEstimation

    error, optionalGS = coreEstimator.extractFromWarpedImage(
        warp.warpedImage.coreImage, coreDescriptor)
    if error.isError:
        raise LunaSDKException(LunaVLError.fromSDKError(error))
    descriptor.garbageScore = optionalGS
    return descriptor
Beispiel #4
0
    def estimate(  # type: ignore
            self,
            warp: Union[Warp, WarpedImage],
            descriptor: Optional[FaceDescriptor] = None) -> FaceDescriptor:
        """
        Estimate face descriptor from a warp image.

        Args:
            warp: warped image
            descriptor: descriptor for saving extract result

        Returns:
            estimated descriptor
        Raises:
            LunaSDKException: if estimation failed
        """
        if descriptor is None:
            descriptor = self.descriptorFactory.generateDescriptor()
            coreDescriptor = descriptor.coreEstimation
        else:
            coreDescriptor = descriptor.coreEstimation

        error, optionalGS = self._coreEstimator.extractFromWarpedImage(
            warp.warpedImage.coreImage, coreDescriptor)
        if error.isError:
            raise LunaSDKException(LunaVLError.fromSDKError(error))
        descriptor.garbageScore = optionalGS
        return descriptor
Beispiel #5
0
    def makeWarpTransformationWithLandmarks(
        self, faceDetection: FaceDetection, typeLandmarks: str
    ) -> Union[Landmarks68, Landmarks5]:
        """
        Make warp transformation with landmarks

        Args:
            faceDetection: face detection  with landmarks5
            typeLandmarks: landmarks for warping ("L68" or "L5")

        Returns:
            warping landmarks
        Raises:
            ValueError: if landmarks5 is not estimated
            LunaSDKException: if transform failed
        """
        transformation = self._createWarpTransformation(faceDetection)
        if typeLandmarks == "L68":
            if faceDetection.landmarks68 is None:
                raise ValueError("landmarks68 does not estimated")
            error, warp = self._coreWarper.warp(faceDetection.landmarks68.coreEstimation, transformation)
        elif typeLandmarks == "L5":
            if faceDetection.landmarks5 is None:
                raise ValueError("landmarks5 does not estimated")
            error, warp = self._coreWarper.warp(faceDetection.landmarks5.coreEstimation, transformation)
        else:
            raise ValueError("Invalid value of typeLandmarks, must be 'L68' or 'L5'")
        if error.isError:
            raise LunaSDKException(LunaVLError.fromSDKError(error))
        if typeLandmarks == "L68":
            return Landmarks68(warp)
        return Landmarks5(warp)
Beispiel #6
0
    def estimate(
        self, warp: Union[FaceWarp, FaceWarpedImage], estimateAge: bool, estimateGender: bool, estimateEthnicity: bool
    ) -> BasicAttributes:
        """
        Estimate a basic attributes (age, gender, ethnicity) from warped images.

        Args:
            warp: warped image
            estimateAge: estimate age or not
            estimateGender: estimate gender or not
            estimateEthnicity: estimate ethnicity or not

        Returns:
            estimated age, gender, ethnicity
        Raises:
            LunaSDKException: if estimation failed
        """
        dtAttributes = 0
        if estimateAge:
            dtAttributes |= AttributeRequest.estimateAge
        if estimateGender:
            dtAttributes |= AttributeRequest.estimateGender
        if estimateEthnicity:
            dtAttributes |= AttributeRequest.estimateEthnicity

        error, baseAttributes = self._coreEstimator.estimate(warp.warpedImage.coreImage, AttributeRequest(dtAttributes))
        if error.isError:
            raise LunaSDKException(LunaVLError.fromSDKError(error))
        return BasicAttributes(baseAttributes)
Beispiel #7
0
    def estimate(
        self,
        detection: Optional[FaceDetection] = None,
        image: Optional[VLImage] = None,
        boundingBox: Optional[BoundingBox] = None,
    ) -> float:
        """
        Estimate emotion on warp.

        Args:
            image: image in R8G8B8 format
            boundingBox: face bounding box of corresponding the image
            detection: face detection

        Returns:
            estimated ags, float in range[0,1]
        Raises:
            LunaSDKException: if estimation failed
            ValueError: if image and detection is Noee
        """
        if detection is None:
            if image is None or boundingBox is None:
                raise ValueError(
                    "image and boundingBox or detection bust be not None")
            error, ags = self._coreEstimator.estimate(
                image.coreImage, boundingBox.coreEstimation)
        else:
            error, ags = self._coreEstimator.estimate(
                detection.image.coreImage,
                detection.boundingBox.coreEstimation)
        if error.isError:
            raise LunaSDKException(LunaVLError.fromSDKError(error))
        return ags
Beispiel #8
0
    def estimate(self, transformedLandmarks: Union[Landmarks5, Landmarks68],
                 warp: Union[Warp, WarpedImage]) -> EyesEstimation:
        """
        Estimate mouth state on warp.

        Args:
            warp: warped image
            transformedLandmarks: transformed landmarks

        Returns:
            estimated states
        Raises:
            LunaSDKException: if estimation failed
        """
        cropper = EyeCropper()
        if isinstance(transformedLandmarks, Landmarks5):
            eyeRects = cropper.cropByLandmarks5(
                warp.warpedImage.coreImage,
                transformedLandmarks.coreEstimation)
        else:
            eyeRects = cropper.cropByLandmarks68(
                warp.warpedImage.coreImage,
                transformedLandmarks.coreEstimation)
        error, eyesEstimation = self._coreEstimator.estimate(
            warp.warpedImage.coreImage, eyeRects)
        if error.isError:
            raise LunaSDKException(LunaVLError.fromSDKError(error))
        return EyesEstimation(eyesEstimation)
Beispiel #9
0
def estimateDescriptorsBatch(
    warps: Union[List[Union[HumanWarp, HumanWarpedImage]],
                 List[Union[FaceWarp, FaceWarpedImage]]],
    descriptorFactory: Type[BaseDescriptorFactory],
    coreEstimator: IDescriptorExtractorPtr,
    aggregate: bool = False,
    descriptorBatch: Optional[BaseDescriptorBatch] = None,
) -> Tuple[BaseDescriptorBatch, Union[BaseDescriptor, None]]:
    """
    Estimate a batch of descriptors from warped images.

    Args:
        warps: warped images
        aggregate:  whether to estimate  aggregate descriptor or not
        descriptorBatch: optional batch for saving descriptors
        descriptorFactory: descriptor factory
        coreEstimator: descriptor extractor
    Returns:
        tuple of batch and the aggregate descriptors (or None)
    Raises:
        LunaSDKException: if estimation failed

    """
    if descriptorBatch is None:
        descriptorBatch = descriptorFactory.generateDescriptorsBatch(
            len(warps))
    if aggregate:
        aggregatedDescriptor = descriptorFactory.generateDescriptor()

        error, optionalGSAggregateDescriptor, scores = coreEstimator.extractFromWarpedImageBatch(
            [warp.warpedImage.coreImage for warp in warps],
            descriptorBatch.coreEstimation,
            aggregatedDescriptor.coreEstimation,
            len(warps),
        )
        if error.isError:
            raise LunaSDKException(LunaVLError.fromSDKError(error))
        aggregatedDescriptor.garbageScore = optionalGSAggregateDescriptor
    else:
        aggregatedDescriptor = None
        error, scores = coreEstimator.extractFromWarpedImageBatch(
            [warp.warpedImage.coreImage for warp in warps],
            descriptorBatch.coreEstimation, len(warps))
        if error.isError:
            raise LunaSDKException(LunaVLError.fromSDKError(error))
        descriptorBatch.scores = scores
    return descriptorBatch, aggregatedDescriptor
Beispiel #10
0
 def rawDescriptor(self) -> bytes:
     """
     Get raw descriptors
     Returns:
         bytes with metadata
     """
     error, descBytes = self.coreEstimation.save()
     if error.isError():
         raise LunaSDKException(LunaVLError.fromSDKError(error))
     return descBytes
Beispiel #11
0
    def __init__(
        self,
        body: Union[bytes, bytearray, ndarray, CoreImage],
        imgFormat: Optional[ColorFormat] = None,
        filename: str = "",
    ):
        """
        Init.

        Args:
            body: body of image - bytes numpy array or core image
            imgFormat: img format
            filename: user mark a source of image
        Raises:
            TypeError: if body has incorrect type
            LunaSDKException: if failed to load image to sdk Image
        """
        if imgFormat is None:
            imgFormat = ColorFormat.R8G8B8
        self.coreImage = CoreImage()

        if isinstance(body, CoreImage):
            self.coreImage = body
        elif isinstance(body, bytes):
            error = self.coreImage.loadFromMemory(body, len(body),
                                                  imgFormat.coreFormat)
            if error.isError:
                raise LunaSDKException(LunaVLError.fromSDKError(error))
        elif isinstance(body, bytearray):
            error = self.coreImage.loadFromMemory(bytes(body), len(body),
                                                  imgFormat.coreFormat)
            if error.isError:
                raise LunaSDKException(LunaVLError.fromSDKError(error))
        elif isinstance(body, ndarray):
            #: todo, format ?????
            self.coreImage.setData(body, imgFormat.coreFormat)
        else:
            raise TypeError("Bad image type")

        self.source = body
        self.filename = filename
Beispiel #12
0
def assertError(error: FSDKErrorResult) -> None:
    """
    Assert core optional.
    Args:
        error: optional

    Raises:
        LunaSDKException: if optional contains error

    """
    if error.isError:
        raise LunaSDKException(LunaVLError.fromSDKError(error))
Beispiel #13
0
    def match(
        self,
        reference: Union[FaceDescriptor, bytes],
        candidates: Union[FaceDescriptor, bytes, List[Union[FaceDescriptor,
                                                            bytes]],
                          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(reference, bytes):
            referenceForMatcher = self.descriptorFactory.generateDescriptor(
                reference)
        else:
            referenceForMatcher = reference

        if isinstance(candidates, bytes):
            candidatesForMatcher = self.descriptorFactory.generateDescriptor(
                candidates)
        elif isinstance(candidates, list):
            candidatesForMatcher = []
            for idx in range(len(candidates)):
                if isinstance(candidates[idx], bytes):
                    candidatesForMatcher.append(
                        self.descriptorFactory.generateDescriptor(
                            candidates[idx]))
                else:
                    candidatesForMatcher.append(candidates[idx])
        else:
            candidatesForMatcher = candidates

        if isinstance(candidatesForMatcher, FaceDescriptor):
            error, matchResults = self._coreMatcher.match(
                referenceForMatcher.coreEstimation,
                candidatesForMatcher.coreEstimation)
        elif isinstance(candidatesForMatcher, FaceDescriptorBatch):
            error, matchResults = self._coreMatcher.match(
                referenceForMatcher.coreEstimation,
                candidatesForMatcher.coreEstimation)
        else:
            batch = self.descriptorFactory.generateDescriptorsBatch(
                len(candidatesForMatcher))
            for candidate in candidatesForMatcher:
                batch.append(candidate)
            error, matchResults = self._coreMatcher.match(
                referenceForMatcher.coreEstimation, batch.coreEstimation)

        if error.isError:
            raise LunaSDKException(LunaVLError.fromSDKError(error))
        return matchResults
Beispiel #14
0
def assertError(error: FSDKErrorResult,
                context: Optional[List[Any]] = None) -> None:
    """
    Assert core optional.
    Args:
        error: optional
        context: list with errors

    Raises:
        LunaSDKException: if optional contains error

    """
    if error.isError:
        raise LunaSDKException(LunaVLError.fromSDKError(error), context)
Beispiel #15
0
def validateInputByBatchEstimator(estimator, *args):
    """
    Validate input data using batch estimator

    Args:
        estimator: estimator
        args: args to validate by estimator

    Raises:
         LunaSDKException(LunaVLError.BatchedInternalError): if data is not valid
         LunaSDKException: if validation is failed
    """
    validationError, sdkErrors = estimator.validate(*args)
    if validationError.isOk:
        return
    errors = [LunaVLError.fromSDKError(error) for error in sdkErrors]

    if validationError.error != FSDKError.ValidationFailed:
        raise LunaSDKException(LunaVLError.fromSDKError(validationError),
                               errors)

    raise LunaSDKException(
        LunaVLError.BatchedInternalError.format(
            LunaVLError.fromSDKError(validationError).detail), errors)
Beispiel #16
0
    def estimate(self, warp: Union[Warp, WarpedImage]) -> Quality:
        """
        Estimate quality from a warp.

        Args:
            warp: raw warped image or warp

        Returns:
            estimated quality
        Raises:
            LunaSDKException: if estimation failed
        """
        error, coreQuality = self._coreEstimator.estimate(warp.warpedImage.coreImage)
        if error.isError:
            raise LunaSDKException(LunaVLError.fromSDKError(error))
        return Quality(coreQuality)
Beispiel #17
0
    def estimate(self, warp: Union[FaceWarp, FaceWarpedImage]) -> Mask:
        """
        Estimate mask from a warp.

        Args:
            warp: raw warped image or warp

        Returns:
            estimated mask
        Raises:
            LunaSDKException: if estimation failed
        """
        error, mask = self._coreEstimator.estimate(warp.warpedImage.coreImage)
        if error.isError:
            raise LunaSDKException(LunaVLError.fromSDKError(error))
        return Mask(mask)
Beispiel #18
0
    def estimate(self, warp: Union[FaceWarp, FaceWarpedImage]) -> MouthStates:
        """
        Estimate mouth state on warp.

        Args:
            warp: warped image

        Returns:
            estimated states
        Raises:
            LunaSDKException: if estimation failed
        """
        error, mouthState = self._coreEstimator.estimate(
            warp.warpedImage.coreImage)
        if error.isError:
            raise LunaSDKException(LunaVLError.fromSDKError(error))
        return MouthStates(mouthState)
Beispiel #19
0
    def estimate(self, warp: Union[FaceWarp, FaceWarpedImage]) -> Emotions:
        """
        Estimate emotion on warp.

        Args:
            warp: warped image

        Returns:
            estimated emotions
        Raises:
            LunaSDKException: if estimation failed
        """
        error, emotions = self._coreEstimator.estimate(
            warp.warpedImage.coreImage)
        if error.isError:
            raise LunaSDKException(LunaVLError.fromSDKError(error))
        return Emotions(emotions)
Beispiel #20
0
    def estimate(self, transformedLandmarks: Union[Landmarks5, Landmarks68],
                 warp: Union[Warp, WarpedImage]) -> GazeDirection:
        """
        Estimate a gaze direction

        Args:
            warp: warped image
            transformedLandmarks: transformed landmarks
        Returns:
            estimated states
        Raises:
            LunaSDKException: if estimation failed
        """
        error, gaze = self._coreEstimator.estimate(
            warp.warpedImage.coreImage, transformedLandmarks.coreEstimation)
        if error.isError:
            raise LunaSDKException(LunaVLError.fromSDKError(error))
        return GazeDirection(gaze)
Beispiel #21
0
    def estimateByBoundingBox(self, detection: BoundingBox,
                              imageWithDetection: VLImage) -> HeadPose:
        """
        Estimate head pose by detection.

        Args:
            detection: detection bounding box
            imageWithDetection: image with the detection.
        Returns:
            estimate head pose
        Raises:
            LunaSDKException: if estimation is failed
        """
        error, headPoseEstimation = self._coreEstimator.estimate(
            imageWithDetection.coreImage, detection.coreEstimation)

        if error.isError:
            raise LunaSDKException(LunaVLError.fromSDKError(error))
        return HeadPose(headPoseEstimation)
Beispiel #22
0
    def estimateBy68Landmarks(self, landmarks68: Landmarks68) -> HeadPose:
        """
        Estimate head pose by 68 landmarks.

        Args:
            landmarks68: landmarks68

        Returns:
            estimate head pose
        Raises:
            LunaSDKException: if estimation is failed
        """
        error, headPoseEstimation = self._coreEstimator.estimate(
            landmarks68.coreEstimation)

        if error.isError:
            raise LunaSDKException(LunaVLError.fromSDKError(error))

        return HeadPose(headPoseEstimation)
Beispiel #23
0
    def warp(self, humanDetection: HumanDetection) -> HumanWarp:
        """
        Create warp from detection.

        Args:
            humanDetection: human body detection with landmarks17

        Returns:
            Warp
        Raises:
            LunaSDKException: if creation failed
        """
        error, warp = self._coreWarper.warp(humanDetection.coreEstimation)
        if error.isError:
            raise LunaSDKException(LunaVLError.fromSDKError(error))

        warpedImage = HumanWarpedImage(body=warp,
                                       filename=humanDetection.image.filename)

        return HumanWarp(warpedImage, humanDetection)
Beispiel #24
0
    def warp(self, faceDetection: FaceDetection) -> FaceWarp:
        """
        Create warp from detection.

        Args:
            faceDetection: face detection with landmarks5

        Returns:
            Warp
        Raises:
            LunaSDKException: if creation failed
        """
        transformation = self._createWarpTransformation(faceDetection)
        error, warp = self._coreWarper.warp(faceDetection.image.coreImage, transformation)
        if error.isError:
            raise LunaSDKException(LunaVLError.fromSDKError(error))

        warpedImage = FaceWarpedImage(body=warp, filename=faceDetection.image.filename)

        return FaceWarp(warpedImage, faceDetection)
Beispiel #25
0
    def getErrorsExtractingOneByOne() -> List[LunaVLError]:
        """
        Extract descriptor without batching and collect errors
        Returns:
            list with errors
        """
        errors = []
        for idx, warp in enumerate(warps):
            if len(descriptorBatch):
                coreDescriptor = descriptorBatch[idx].coreEstimation
            else:
                descriptor = descriptorFactory.generateDescriptor()
                coreDescriptor = descriptor.coreEstimation

            errorOne, _ = coreEstimator.extractFromWarpedImage(
                warp.warpedImage.coreImage, coreDescriptor)
            if errorOne.isError:
                errors.append(LunaVLError.fromSDKError(errorOne))
            else:
                errors.append(LunaVLError.Ok.format(
                    LunaVLError.Ok.description))

            return errors
Beispiel #26
0
def estimateDescriptorsBatch(
    warps: Union[List[Union[HumanWarp, HumanWarpedImage]],
                 List[Union[FaceWarp, FaceWarpedImage]]],
    descriptorFactory: Type[BaseDescriptorFactory],
    coreEstimator: IDescriptorExtractorPtr,
    aggregate: bool = False,
    descriptorBatch: Optional[BaseDescriptorBatch] = None,
) -> Tuple[BaseDescriptorBatch, Union[BaseDescriptor, None]]:
    """
    Estimate a batch of descriptors from warped images.

    Args:
        warps: warped images
        aggregate:  whether to estimate  aggregate descriptor or not
        descriptorBatch: optional batch for saving descriptors
        descriptorFactory: descriptor factory
        coreEstimator: descriptor extractor
    Returns:
        tuple of batch and the aggregate descriptors (or None)
    Raises:
        LunaSDKException: if estimation failed
    """
    def getErrorsExtractingOneByOne() -> List[LunaVLError]:
        """
        Extract descriptor without batching and collect errors
        Returns:
            list with errors
        """
        errors = []
        for idx, warp in enumerate(warps):
            if len(descriptorBatch):
                coreDescriptor = descriptorBatch[idx].coreEstimation
            else:
                descriptor = descriptorFactory.generateDescriptor()
                coreDescriptor = descriptor.coreEstimation

            errorOne, _ = coreEstimator.extractFromWarpedImage(
                warp.warpedImage.coreImage, coreDescriptor)
            if errorOne.isError:
                errors.append(LunaVLError.fromSDKError(errorOne))
            else:
                errors.append(LunaVLError.Ok.format(
                    LunaVLError.Ok.description))

            return errors

    if descriptorBatch is None:
        descriptorBatch = descriptorFactory.generateDescriptorsBatch(
            len(warps))
    if aggregate:
        aggregatedDescriptor = descriptorFactory.generateDescriptor()

        error, optionalGSAggregateDescriptor, scores = coreEstimator.extractFromWarpedImageBatch(
            [warp.warpedImage.coreImage for warp in warps],
            descriptorBatch.coreEstimation,
            aggregatedDescriptor.coreEstimation,
            len(warps),
        )
        if error.isError:
            errors = getErrorsExtractingOneByOne()
            raise LunaSDKException(
                LunaVLError.BatchedInternalError.format(
                    LunaVLError.fromSDKError(error).detail), errors)

        aggregatedDescriptor.garbageScore = optionalGSAggregateDescriptor
    else:
        aggregatedDescriptor = None
        error, scores = coreEstimator.extractFromWarpedImageBatch(
            [warp.warpedImage.coreImage for warp in warps],
            descriptorBatch.coreEstimation, len(warps))
        if error.isError:
            errors = getErrorsExtractingOneByOne()
            raise LunaSDKException(
                LunaVLError.BatchedInternalError.format(
                    LunaVLError.fromSDKError(error).detail), errors)

        descriptorBatch.scores = scores
    return descriptorBatch, aggregatedDescriptor