[docs]classMomentOfArea(Algorithm):"""Estimate the eye orientation using the second order moments of the eyeball polygon. The eye orientation refers to the horizontal direction of the eye. It comes useful for determining the partial eye occlusion (e.g. occlusion at the horizontal middle third of the iris). References: [1] https://t1.daumcdn.net/cfile/tistory/15425F4150F4EBFC19 [2] https://en.wikipedia.org/wiki/Image_moment """
[docs]classParameters(Algorithm.Parameters):"""MomentOfArea parameters. eccentricity_threshold: float in [0, 1]. The threshold below which a shape is considered not linear enough to reliably estimate its orientation. """eccentricity_threshold:float=Field(ge=0.0,le=1.0)
__parameters_type__=Parametersdef__init__(self,eccentricity_threshold:float=0.1)->None:"""Assign parameters. Args: eccentricity_threshold: float in [0, 1]. The threshold below which a shape is considered not linear enough to reliably estimate its orientation. Defaults to 0.1. """super().__init__(eccentricity_threshold=eccentricity_threshold)
[docs]defrun(self,geometries:GeometryPolygons)->EyeOrientation:"""Compute the eye orientation using the second order moments or the eyeball. WARNING: cv2.moments MUST only receive np.float32 arrays. Otherwise, the array will be interpreted as a sparse matrix instead of a list of points. See https://github.com/opencv/opencv/issues/6643#issuecomment-224204774. Args: geometries (GeometryPolygons): segmentation map used for eye orientation estimation. Raises: EyeOrientationEstimationError if the eyeball's eccentricity is below `eccentricity_threshold` i.e. if the eyeball shape is not circular enough to reliably estimate the orientation. Returns: EyeOrientation: eye orientation object. """moments=cv2.moments(geometries.eyeball_array)eccentricity=math_utils.eccentricity(moments)ifeccentricity<self.params.eccentricity_threshold:raiseEyeOrientationEstimationError("The eyeball is too circular to reliably determine its orientation. "f"Computed eccentricity: {eccentricity}. Threshold: {self.params.eccentricity_threshold}")orientation=math_utils.orientation(moments)returnEyeOrientation(angle=orientation)