def denormalize_wrt_roi_shape(self, roi_shape: Rectangle) -> "Ellipse": """ Transforming shape from the normalized coordinate system to the `roi` coordinate system. This function is the inverse of ``normalize_wrt_roi_shape`` :example: Assume we have Ellipse `c1` which lives in the top-right quarter of the normalized coordinate space. The `roi` is a rectangle living in the half right of the normalized coordinate space. This function returns Ellipse `c1` expressed in the coordinate space of `roi`. (should return top-half) Ellipse denormalized to a rectangle as ROI >>> from ote_sdk.entities.annotation import Annotation >>> from ote_sdk.entities.shapes.ellipse import Ellipse >>> c1 = Ellipse(x1=0.5, x2=1.0, y1=0.0, y2=0.5) # An ellipse in the top right >>> roi = Rectangle(x1=0.5, x2=1.0, y1=0.0, y2=1.0) # the half-right >>> normalized = c1.denormalize_wrt_roi_shape(roi_shape) # should return top half >>> normalized Ellipse(, x1=0.0, y1=0.0, x2=1.0, y2=0.5, scored_labels=[]) :param roi_shape: Region of Interest :return: New polygon in the ROI coordinate system """ if not isinstance(roi_shape, Rectangle): raise ValueError("roi_shape has to be a Rectangle.") roi_shape = roi_shape.clip_to_visible_region() x1 = (self.x1 - roi_shape.x1) / roi_shape.width y1 = (self.y1 - roi_shape.y1) / roi_shape.height x2 = (self.x2 - roi_shape.x1) / roi_shape.width y2 = (self.y2 - roi_shape.y1) / roi_shape.height return Ellipse(x1=x1, y1=y1, x2=x2, y2=y2)
def normalize_wrt_roi_shape(self, roi_shape: Rectangle) -> "Ellipse": """ Transforms from the `roi` coordinate system to the normalized coordinate system. This function is the inverse of ``denormalize_wrt_roi_shape``. :example: Assume we have Ellipse `c1` which lives in the top-right quarter of a 2D space. The 2D space where `c1` lives in is an `roi` living in the top-left quarter of the normalized coordinate space. This function returns Ellipse `c1` expressed in the normalized coordinate space. >>> from ote_sdk.entities.annotation import Annotation >>> from ote_sdk.entities.shapes.rectangle import Rectangle >>> from ote_sdk.entities.shapes.ellipse import Ellipse >>> c1 = Ellipse(x1=0.5, y1=0.5, x2=0.6, y2=0.6) >>> roi = Rectangle(x1=0.0, x2=0.5, y1=0.0, y2=0.5) >>> normalized = c1.normalize_wrt_roi_shape(roi_shape) >>> normalized Ellipse(, x1=0.25, y1=0.25, x2=0.3, y2=0.3, scored_labels=[]) :param roi_shape: Region of Interest :return: New polygon in the image coordinate system """ if not isinstance(roi_shape, Rectangle): raise ValueError("roi_shape has to be a Rectangle.") roi_shape = roi_shape.clip_to_visible_region() return Ellipse( x1=self.x1 * roi_shape.width + roi_shape.x1, y1=self.y1 * roi_shape.height + roi_shape.y1, x2=self.x2 * roi_shape.width + roi_shape.x1, y2=self.y2 * roi_shape.height + roi_shape.y1, )
def denormalize_wrt_roi_shape(self, roi_shape: Rectangle) -> "Polygon": """ Transforming shape from the normalized coordinate system to the `roi` coordinate system. This function is the inverse of ``normalize_wrt_roi_shape`` :example: Assume we have Polygon `p1` which lives in the top-right quarter of the normalized coordinate space. The `roi` is a rectangle living in the half right of the normalized coordinate space. This function returns Polygon `p1` expressed in the coordinate space of `roi`. (should return top-half) Polygon denormalized to a rectangle as ROI >>> from ote_sdk.entities.shapes.rectangle import Rectangle >>> from ote_sdk.entities.annotation import Annotation >>> p1 = Polygon(points=[Point(x=0.5, y=0.0), Point(x=0.75, y=0.2), Point(x=0.6, y=0.1)]) >>> roi = Rectangle(x1=0.5, x2=1.0, y1=0.0, y2=1.0) # the half-right >>> normalized = p1.denormalize_wrt_roi_shape(roi_shape) >>> normalized Polygon(, len(points)=3, scored_labels=[]) :param roi_shape: Region of Interest :return: New polygon in the ROI coordinate system """ if not isinstance(roi_shape, Rectangle): raise ValueError("roi_shape has to be a Rectangle.") roi_shape = roi_shape.clip_to_visible_region() points = [p.denormalize_wrt_roi_shape(roi_shape) for p in self.points] return Polygon(points=points)
def normalize_wrt_roi_shape(self, roi_shape: Rectangle) -> "Polygon": """ Transforms from the `roi` coordinate system to the normalized coordinate system. This function is the inverse of ``denormalize_wrt_roi_shape``. :example: Assume we have Polygon `p1` which lives in the top-right quarter of a 2D space. The 2D space where `p1` lives in is an `roi` living in the top-left quarter of the normalized coordinate space. This function returns Polygon `p1` expressed in the normalized coordinate space. >>> from ote_sdk.entities.annotation import Annotation >>> from ote_sdk.entities.shapes.rectangle import Rectangle >>> p1 = Polygon(points=[Point(x=0.5, y=0.0), Point(x=0.75, y=0.2), Point(x=0.6, y=0.1)]) >>> roi = Rectangle(x1=0.0, x2=0.5, y1=0.0, y2=0.5) >>> normalized = p1.normalize_wrt_roi_shape(roi_shape) >>> normalized Polygon(, len(points)=3, scored_labels=[]) :param roi_shape: Region of Interest :return: New polygon in the image coordinate system """ if not isinstance(roi_shape, Rectangle): raise ValueError("roi_shape has to be a Rectangle.") roi_shape = roi_shape.clip_to_visible_region() points = [p.normalize_wrt_roi(roi_shape) for p in self.points] return Polygon(points=points)
def denormalize_wrt_roi_shape(self, roi_shape: Rectangle): """ The inverse of normalize_wrt_roi_shape. Transforming Polygon from the normalized coordinate system to the `roi` coordinate system. This is used to pull ground truth during training process of the tasks. Examples given in the Shape implementations. :param roi_shape: """ roi_shape = roi_shape.clip_to_visible_region() return Point( x=(self.x - roi_shape.x1) / roi_shape.width, y=(self.y - roi_shape.y1) / roi_shape.height, )
def normalize_wrt_roi(self, roi_shape: Rectangle) -> "Point": """ The inverse of denormalize_wrt_roi_shape. Transforming Polygon from the `roi` coordinate system to the normalized coordinate system. This is used when the tasks want to save the analysis results. For example in Detection -> Segmentation pipeline, the analysis results of segmentation needs to be normalized to the roi (bounding boxes) coming from the detection. :param roi_shape: """ roi_shape = roi_shape.clip_to_visible_region() width = roi_shape.width height = roi_shape.height x1 = roi_shape.x1 y1 = roi_shape.y1 return Point(x=self.x * width + x1, y=self.y * height + y1)
def test_rectangle_clip_to_visible_region(self): """ <b>Description:</b> Check Rectangle clip_to_visible_region method <b>Input data:</b> Rectangle class initiation parameters <b>Expected results:</b> Test passes if clip_to_visible_region method return correct value <b>Steps</b> 1. Check values returned by clip_to_visible_region method for 0<x1<x2, 0<y1<y2, x1<x2<1, y1<y2<1 2. Check values returned by clip_to_visible_region method for x1<0, y1<0, x2>1, y2>1 3. Check values returned by clip_to_visible_region method for x1=0, y1=0, x2=1, y2=1 4. Check ValueError exception raised if x1<0 and x1<x2<0: clipped Rectangle width will be equal 0 5. Check ValueError exception raised if 1<x1<x2 and x2>1: clipped Rectangle width will be equal 0 6. Check ValueError exception raised if y1<0 and y1<y2<0: clipped Rectangle height will be equal 0 7. Check ValueError exception raised if 1<y1<y2 and y2>1: clipped Rectangle height will be equal 0 """ positive_scenarios = [ { "input_params": { "x1": 0.3, "y1": 0.2, "x2": 0.6, "y2": 0.4, "labels": self.rectangle_labels(), }, "params_expected": {"x1": 0.3, "y1": 0.2, "x2": 0.6, "y2": 0.4}, }, { "input_params": { "x1": -0.2, "y1": -0.3, "x2": 1.6, "y2": 1.4, "labels": self.rectangle_labels(), }, "params_expected": {"x1": 0.0, "y1": 0.0, "x2": 1.0, "y2": 1.0}, }, { "input_params": { "x1": 0.0, "y1": 0.0, "x2": 1.0, "y2": 1.0, "labels": self.rectangle_labels(), }, "params_expected": {"x1": 0.0, "y1": 0.0, "x2": 1.0, "y2": 1.0}, }, ] for scenario in positive_scenarios: with warnings.catch_warnings(): warnings.filterwarnings("ignore", "Rectangle coordinates") rectangle_actual = Rectangle(**scenario.get("input_params")) rectangle_expected = Rectangle(**scenario.get("params_expected")) rectangle_actual.modification_date = self.modification_date rectangle_expected.modification_date = self.modification_date assert rectangle_actual.clip_to_visible_region() == rectangle_expected negative_scenarios = [ {"x1": -0.4, "y1": 0.2, "x2": -0.2, "y2": 0.4}, {"x1": 1.2, "y1": 0.2, "x2": 1.6, "y2": 0.4}, {"x1": 0.4, "y1": -0.4, "x2": 0.6, "y2": -0.2}, {"x1": 1.2, "y1": 1.2, "x2": 1.6, "y2": 1.4}, ] for scenario in negative_scenarios: with warnings.catch_warnings(): warnings.filterwarnings("ignore", "Rectangle coordinates") rectangle_actual = Rectangle(**scenario) with pytest.raises(ValueError): rectangle_actual.clip_to_visible_region()