Ejemplo n.º 1
0
 def annotations_to_add(self) -> List[Annotation]:
     labels_to_add = self.labels_to_add()
     annotation_to_add = Annotation(
         shape=Rectangle(x1=0.1, y1=0.1, x2=0.7, y2=0.8),
         labels=[ScoredLabel(label=labels_to_add[0])],
         id=ID("added_annotation_1"),
     )
     other_annotation_to_add = Annotation(
         shape=Rectangle(x1=0.2, y1=0.3, x2=0.8, y2=0.9),
         labels=[ScoredLabel(label=labels_to_add[1])],
         id=ID("added_annotation_2"),
     )
     return [annotation_to_add, other_annotation_to_add]
    def test_rectangle_crop_numpy_array(self):
        """
        <b>Description:</b>
        Check Rectangle crop_numpy_array method

        <b>Input data:</b>
        Rectangle class initiation parameters

        <b>Expected results:</b>
        Test passes if crop_numpy_array method return expected cropped array
        <b>Steps</b>
        1. Check crop_numpy_array method for Rectangle with parameters less than 0
        2. Check crop_numpy_array method for Rectangle with parameters range from 0 to 1
        3. Check crop_numpy_array method for Rectangle with parameters more than 1
        """
        image_height = image_width = 128
        numpy_image_array = np.random.uniform(
            low=0.0, high=255.0, size=(image_height, image_width, 3)
        )
        scenarios = [
            {
                "input_params": {"x1": -0.2, "x2": -0.1, "y1": -0.3, "y2": -0.2},
                "cropped_expected": {"x1": 0, "y1": 0, "x2": 0, "y2": 0},
            },
            {
                "input_params": {"x1": 0.2, "x2": 0.3, "y1": 0.4, "y2": 0.8},
                "cropped_expected": {"x1": 26, "y1": 51, "x2": 38, "y2": 102},
            },
            {
                "input_params": {"x1": 1.1, "x2": 1.3, "y1": 1.1, "y2": 1.5},
                "cropped_expected": {"x1": 141, "y1": 141, "x2": 166, "y2": 192},
            },
        ]
        for rectangle_parameters in scenarios:
            with warnings.catch_warnings():
                warnings.filterwarnings("ignore", "Rectangle coordinates")
                rectangle = Rectangle(**rectangle_parameters.get("input_params"))
            expected_output = rectangle_parameters.get("cropped_expected")
            actual_cropped_image_array = rectangle.crop_numpy_array(numpy_image_array)
            expected_image_array = numpy_image_array[
                expected_output.get("y1") : expected_output.get("y2"),
                expected_output.get("x1") : expected_output.get("x2"),
                ::,
            ]
            assert actual_cropped_image_array.shape[2] == 3
            try:
                assert (expected_image_array == actual_cropped_image_array).all()
            except AttributeError:
                raise AssertionError("Unequal expected and cropped image arrays")
Ejemplo n.º 3
0
 def annotations(self) -> List[Annotation]:
     labels = self.labels()
     rectangle = Rectangle(x1=0.2, y1=0.2, x2=0.6, y2=0.7)
     other_rectangle = Rectangle(x1=0.3, y1=0.2, x2=0.9, y2=0.9)
     detection_annotation = Annotation(
         shape=rectangle,
         labels=[ScoredLabel(label=labels[0])],
         id=ID("detection_annotation_1"),
     )
     segmentation_annotation = Annotation(
         shape=other_rectangle,
         labels=[ScoredLabel(label=labels[1])],
         id=ID("segmentation_annotation_1"),
     )
     return [detection_annotation, segmentation_annotation]
    def test_rectangle_denormalize_wrt_roi_shape(self):
        """
        <b>Description:</b>
        Check Rectangle denormalize_wrt_roi_shape method

        <b>Input data:</b>
        Instance of Rectangle class

        <b>Expected results:</b>
        Test passes if denormalize_wrt_roi_shape method return expected instance of Rectangle class

        <b>Steps</b>
        1. Check values returned by denormalized Rectangle instance
        2. Check raise ValueError exception when roi parameter has unexpected type
        """
        # Positive scenario
        rectangle = self.horizontal_rectangle()
        roi_shape = Rectangle(x1=0.2, y1=0.2, x2=0.4, y2=0.4)
        with warnings.catch_warnings():
            warnings.filterwarnings("ignore", "Rectangle coordinates")
            denormalized = rectangle.denormalize_wrt_roi_shape(roi_shape)
        assert denormalized.x1 == -0.5
        assert denormalized.y1 == -1.0
        assert denormalized.x2 == 1.0
        assert denormalized.y2 == 0.0
        assert denormalized.modification_date == rectangle.modification_date
        # Negative scenario
        with pytest.raises(ValueError):
            rectangle.denormalize_wrt_roi_shape(str)
    def test_rectangle_generate_full_box(self):
        """
        <b>Description:</b>
        Check Rectangle generate_full_box method

        <b>Input data:</b>
        Labels specified for full_box instance of Rectangle class

        <b>Expected results:</b>
        Test passes if generate_full_box method returns instance of Rectangle class with coordinates
        (x1=0.0, y1=0.0, x2=1.0, y2=1.0)

        <b>Steps</b>
        1. Check generate_full_box method for Rectangle instance with no labels specified
        2. Check generate_full_box method for Rectangle instance with labels specified
        """
        detection_label = ScoredLabel(
            LabelEntity(name="detection", domain=Domain.DETECTION)
        )
        for label_actual, label_expected in [
            (None, []),
            ([detection_label], [detection_label]),
        ]:
            full_box = Rectangle.generate_full_box(label_actual)
            assert full_box.type == ShapeType.RECTANGLE
            assert full_box.x1 == full_box.y1 == 0.0
            assert full_box.x2 == full_box.y2 == 1.0
            assert full_box._labels == label_expected
Ejemplo n.º 6
0
    def test_polygon_denormalize_wrt_roi_shape(self):
        """
        <b>Description:</b>
        Check Polygon denormalize_wrt_roi_shape methods

        <b>Input data:</b>
        Initialized instance of Polygon
        Initialized instance of Rectangle

        <b>Expected results:</b>
        Test passes if Polygon denormalize_wrt_roi_shape returns correct values

        <b>Steps</b>
        1. Initialize Polygon instance
        2. Check returning value
        """

        polygon = self.polygon()
        roi = Rectangle(x1=0.5, x2=1.0, y1=0.0, y2=1.0)
        denormalized = polygon.denormalize_wrt_roi_shape(roi)
        assert len(denormalized.points) == 3
        assert denormalized.min_x == 0.0
        assert denormalized.max_x == 0.5
        assert denormalized.min_y == 0.0
        assert denormalized.max_y == 0.2

        with pytest.raises(ValueError):
            polygon.denormalize_wrt_roi_shape("123")
 def optional_result_media_parameters(self) -> dict:
     optional_result_media_parameters = self.default_result_media_parameters(
     )
     roi_label = LabelEntity(
         "ROI label",
         Domain.DETECTION,
         Color(10, 200, 40),
         creation_date=datetime.datetime(year=2021, month=12, day=18),
         id=ID("roi_label_1"),
     )
     roi = Annotation(
         shape=Rectangle(x1=0.3, y1=0.2, x2=0.7, y2=0.6),
         labels=[ScoredLabel(roi_label)],
         id=ID("roi_annotation"),
     )
     result_media_label = LabelEntity(
         "ResultMedia label",
         Domain.CLASSIFICATION,
         Color(200, 60, 100),
         creation_date=datetime.datetime(year=2021, month=12, day=20),
         id=ID("result_media_1"),
     )
     optional_result_media_parameters["roi"] = roi
     optional_result_media_parameters["label"] = result_media_label
     return optional_result_media_parameters
Ejemplo n.º 8
0
    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,
        )
Ejemplo n.º 9
0
    def generate(self) -> DatasetEntity:
        """
        Generate OTE Anomaly Dataset

        Returns:
            DatasetEntity: Output OTE Anomaly Dataset from an MVTec
        """
        samples = self.get_samples()
        dataset_items: List[DatasetItemEntity] = []
        for _, sample in tqdm(samples.iterrows()):
            # Create image
            image = Image(file_path=sample.image_path)

            # Create annotation
            shape = Rectangle(x1=0, y1=0, x2=1, y2=1)
            labels = [ScoredLabel(sample.label)]
            annotations = [Annotation(shape=shape, labels=labels)]
            annotation_scene = AnnotationSceneEntity(annotations=annotations, kind=AnnotationSceneKind.ANNOTATION)

            # Create dataset item
            dataset_item = DatasetItemEntity(media=image, annotation_scene=annotation_scene, subset=sample.subset)

            # Add to dataset items
            dataset_items.append(dataset_item)

        dataset = DatasetEntity(items=dataset_items)
        return dataset
Ejemplo n.º 10
0
    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 on_predict_epoch_end(self, _trainer: pl.Trainer,
                             _pl_module: AnomalyModule, outputs: List[Any]):
        """Called when the predict epoch ends."""
        outputs = outputs[0]
        pred_scores = np.hstack(
            [output["pred_scores"].cpu() for output in outputs])
        pred_labels = np.hstack(
            [output["pred_labels"].cpu() for output in outputs])
        anomaly_maps = np.vstack(
            [output["anomaly_maps"].cpu() for output in outputs])

        # Loop over dataset again to assign predictions
        for dataset_item, pred_score, pred_label, anomaly_map in zip(
                self.ote_dataset, pred_scores, pred_labels, anomaly_maps):

            assigned_label = self.anomalous_label if pred_label else self.normal_label
            shape = Annotation(
                Rectangle(x1=0, y1=0, x2=1, y2=1),
                labels=[
                    ScoredLabel(assigned_label, probability=float(pred_score))
                ],
            )

            dataset_item.append_annotations([shape])

            heatmap = anomaly_map_to_color_map(anomaly_map.squeeze())
            heatmap_media = ResultMediaEntity(
                name="Anomaly Map",
                type="anomaly_map",
                annotation_scene=dataset_item.annotation_scene,
                numpy=heatmap,
            )
            dataset_item.append_metadata_item(heatmap_media)
Ejemplo n.º 12
0
    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)
Ejemplo n.º 13
0
    def test_produces_valid_crop(self):
        """
        <b>Description:</b>
        Checks that shape_produces_valid_crop returns the correct values and
        does not raise errors

        <b>Input data:</b>
        A valid Rectangle at [0, 0.4, 1, 0.5]
        A Polygon that has an invalid bounding box

        <b>Expected results:</b>
        The test passes if the call with the Rectangle returns True and
        the one with the polygon returns False

        <b>Steps</b>
        1. Check Valid Rectangle
        2. Check invalid Polygon
        """
        rectangle = Rectangle(x1=0, y1=0.4, x2=1, y2=0.5)
        assert ShapeFactory.shape_produces_valid_crop(rectangle, 100, 100)

        point1 = Point(x=0.01, y=0.1)
        point2 = Point(x=0.35, y=0.1)
        point3 = Point(x=0.35, y=0.1)
        polygon = Polygon(points=[point1, point2, point3])
        assert not ShapeFactory.shape_produces_valid_crop(polygon, 100, 250)
 def default_result_media_parameters() -> dict:
     rectangle_label = LabelEntity(
         name="Rectangle Annotation Label",
         domain=Domain.DETECTION,
         color=Color(100, 200, 60),
         creation_date=datetime.datetime(year=2021, month=12, day=16),
         id=ID("rectangle_label_1"),
     )
     rectangle_annotation = Annotation(
         shape=Rectangle(x1=0.1, y1=0.4, x2=0.4, y2=0.9),
         labels=[ScoredLabel(rectangle_label)],
         id=ID("rectangle_annotation"),
     )
     annotation_scene = AnnotationSceneEntity(
         annotations=[rectangle_annotation],
         kind=AnnotationSceneKind.ANNOTATION,
         creation_date=datetime.datetime(year=2021, month=12, day=16),
         id=ID("annotation_scene"),
     )
     return {
         "name": "ResultMedia name",
         "type": "Test ResultMedia",
         "annotation_scene": annotation_scene,
         "numpy": RANDOM_IMAGE,
     }
    def __init__(
        self,
        media: IMedia2DEntity,
        annotation_scene: AnnotationSceneEntity,
        roi: Optional[Annotation] = None,
        metadata: Optional[Sequence[MetadataItemEntity]] = None,
        subset: Subset = Subset.NONE,
    ):
        self.__media: IMedia2DEntity = media
        self.__annotation_scene: AnnotationSceneEntity = annotation_scene
        self.__subset: Subset = subset
        self.__roi_lock = Lock()

        # set ROI
        if roi is None:
            for annotation in annotation_scene.annotations:
                # if there is a full box in annotation.shapes, set it as ROI
                if Rectangle.is_full_box(annotation.shape):
                    roi = annotation
                    break
        self.__roi = roi

        self.__metadata: List[MetadataItemEntity] = []
        if metadata is not None:
            self.__metadata = list(metadata)
Ejemplo n.º 16
0
    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 test_ellipse_denormalize_wrt_roi_shape(self):
        """
        <b>Description:</b>
        Check Ellipse denormalize_wrt_roi_shape methods

        <b>Input data:</b>
        Initialized instance of Ellipse
        Initialized instance of Rectangle

        <b>Expected results:</b>
        Test passes if Ellipse denormalize_wrt_roi_shape returns correct values

        <b>Steps</b>
        1. Initialize Ellipse instance
        2. Check returning value
        """

        ellipse = self.ellipse()
        roi = Rectangle(x1=0.5, x2=1.0, y1=0.0, y2=1.0)
        denormalized = ellipse.denormalize_wrt_roi_shape(roi)
        assert denormalized.x1 == 0.0
        assert denormalized.y1 == 0.0
        assert denormalized.x2 == 1.0
        assert denormalized.y2 == 0.5

        with pytest.raises(ValueError):
            ellipse.denormalize_wrt_roi_shape("123")
Ejemplo n.º 18
0
    def test_dataset_item_roi(self):
        """
        <b>Description:</b>
        Check DatasetItemEntity class "roi" property

        <b>Input data:</b>
        DatasetItemEntity class object with specified "media", "annotation_scene", "roi", "metadata" and "subset"
        parameters

        <b>Expected results:</b>
        Test passes if value returned by "roi" property is equal to expected

        <b>Steps</b>
        1. Check value returned by "roi" property for DatasetItemEntity with specified "roi" parameter
        2. Check value returned by "roi" property for DatasetItemEntity with not specified "roi" parameter
        3. Check value returned by "roi" property for DatasetItemEntity with not specified "roi" parameter but one
        of annotation objects in annotation_scene is equal to full Rectangle
        """
        media = DatasetItemParameters.generate_random_image()
        annotations = DatasetItemParameters().annotations()
        annotation_scene = DatasetItemParameters().annotations_entity()
        roi = DatasetItemParameters().roi()
        metadata = DatasetItemParameters.metadata()
        # Checking "roi" property for DatasetItemEntity with specified "roi" parameter
        specified_roi_dataset_item = DatasetItemParameters().dataset_item()
        assert specified_roi_dataset_item.roi == roi
        # Checking that "roi" property is equal to full_box for DatasetItemEntity with not specified "roi" parameter
        non_specified_roi_dataset_item = DatasetItemEntity(media,
                                                           annotation_scene,
                                                           metadata=metadata)
        default_roi = non_specified_roi_dataset_item.roi.shape
        assert isinstance(default_roi, Rectangle)
        assert Rectangle.is_full_box(default_roi)
        # Checking that "roi" property will be equal to full_box for DatasetItemEntity with not specified "roi" but one
        # of Annotation objects in annotation_scene is equal to full Rectangle
        full_box_label = LabelEntity("Full-box label",
                                     Domain.DETECTION,
                                     id=ID("full_box_label"))
        full_box_annotation = Annotation(Rectangle.generate_full_box(),
                                         [ScoredLabel(full_box_label)])
        annotations.append(full_box_annotation)
        annotation_scene.annotations.append(full_box_annotation)
        full_box_label_dataset_item = DatasetItemEntity(media,
                                                        annotation_scene,
                                                        metadata=metadata)
        assert full_box_label_dataset_item.roi is full_box_annotation
 def roi(self) -> Annotation:
     """Region Of Interest."""
     with self.__roi_lock:
         if self.__roi is None:
             requested_roi = Annotation(Rectangle.generate_full_box(),
                                        labels=[])
             self.__roi = requested_roi
         else:
             requested_roi = self.__roi
         return requested_roi
    def get_annotations(
        self,
        labels: Optional[List[LabelEntity]] = None,
        include_empty: bool = False,
        ios_threshold: float = 0.0,
    ) -> List[Annotation]:
        """
        Returns a list of annotations that exist in the dataset item (wrt. ROI)

        :param labels: Subset of input labels to filter with; if ``None``, all the shapes within the ROI are returned
        :param include_empty: if True, returns both empty and non-empty labels
        :param ios_threshold: Only return shapes where Area(self.roi ∩ shape)/ Area(shape) > ios_threshold.
        :return: The intersection of the input label set and those present within the ROI
        """
        is_full_box = Rectangle.is_full_box(self.roi.shape)
        annotations = []
        if is_full_box and labels is None and not include_empty:
            # Fast path for the case where we do not need to change the shapes
            annotations = self.annotation_scene.annotations
        else:
            # Todo: improve speed. This is O(n) for n shapes.
            roi_as_box = ShapeFactory.shape_as_rectangle(self.roi.shape)

            labels_set = {label.name
                          for label in labels} if labels is not None else {}

            for annotation in self.annotation_scene.annotations:
                if (not is_full_box and self.roi.shape.intersect_percentage(
                        annotation.shape) <= ios_threshold):
                    continue

                shape_labels = annotation.get_labels(include_empty)

                if labels is not None:
                    shape_labels = [
                        label for label in shape_labels
                        if label.name in labels_set
                    ]

                    if len(shape_labels) == 0:
                        continue

                if not is_full_box:
                    # Create a denormalized copy of the shape.
                    shape = annotation.shape.denormalize_wrt_roi_shape(
                        roi_as_box)
                else:
                    # Also create a copy of the shape, so that we can safely modify the labels
                    # without tampering with the original shape.
                    shape = copy.deepcopy(annotation.shape)

                annotations.append(Annotation(shape=shape,
                                              labels=shape_labels))
        return annotations
Ejemplo n.º 21
0
 def upper_side_intersect_shapes() -> list:
     return [
         Rectangle(x1=0.2, y1=0.4, x2=0.5, y2=0.7),
         Polygon([
             Point(0.35, 0.7),
             Point(0.2, 0.6),
             Point(0.2, 0.4),
             Point(0.5, 0.4),
             Point(0.5, 0.6),
             Point(0.35, 0.7),
         ]),
     ]
Ejemplo n.º 22
0
 def lower_side_intersect_shapes() -> list:
     return [
         Rectangle(x1=0.2, y1=0.1, x2=0.5, y2=0.4),
         Polygon([
             Point(0.35, 0.1),
             Point(0.2, 0.2),
             Point(0.2, 0.4),
             Point(0.5, 0.4),
             Point(0.5, 0.2),
             Point(0.35, 0.1),
         ]),
     ]
    def test_result_media_eq(self):
        """
        <b>Description:</b>
        Check ResultMediaEntity class object __eq__ method

        <b>Input data:</b>
        ResultMediaEntity class objects with specified "name", "type", "annotation_scene", "numpy", "roi"
        and "label" parameters

        <b>Expected results:</b>
        Test passes if value returned by __eq__ method is equal to expected

        <b>Steps</b>
        1. Check value returned by __eq__ method for comparing equal ResultMediaEntity objects
        2. Check value returned by __eq__ method for comparing ResultMediaEntity objects with unequal
        "name", "type", "label" and "numpy" parameters - expected equality
        3. Check value returned by __eq__ method for comparing ResultMediaEntity objects with unequal
        "annotation_scene" and "roi" parameters - expected inequality
        4. Check value returned by __eq__ method for comparing ResultMediaEntity with different type object
        """
        initialization_params = self.optional_result_media_parameters()
        result_media = ResultMediaEntity(**initialization_params)
        # Comparing equal ResultMediaEntity objects
        equal_result_media = ResultMediaEntity(**initialization_params)
        assert result_media == equal_result_media
        # Comparing ResultMediaEntity objects with unequal "name", "type", "label" and "numpy" parameters,
        # expected equality
        unequal_values = {
            "name": "Unequal name",
            "type": "Unequal type",
            "label": LabelEntity("Unequal label", Domain.CLASSIFICATION),
            "numpy": np.random.uniform(low=0.0, high=255.0, size=(1, 2, 3)),
        }
        for key in unequal_values:
            unequal_params = dict(initialization_params)
            unequal_params[key] = unequal_values.get(key)
            equal_result_media = ResultMediaEntity(**unequal_params)
            assert result_media == equal_result_media
        # Comparing ResultMediaEntity objects with unequal "annotation_scene" and "roi" parameters, expected inequality
        unequal_values = {
            "annotation_scene":
            AnnotationSceneEntity(annotations=[],
                                  kind=AnnotationSceneKind.NONE),
            "roi":
            Rectangle.generate_full_box(),
        }
        for key in unequal_values:
            unequal_params = dict(initialization_params)
            unequal_params[key] = unequal_values.get(key)
            unequal_result_media = ResultMediaEntity(**unequal_params)
            assert result_media != unequal_result_media
        # Comparing ResultMediaEntity with different type object
        assert result_media != str
    def test_rectangle_is_full_box(self):
        """
        <b>Description:</b>
        Check Rectangle is_full_box method

        <b>Input data:</b>
        Rectangle class initiation parameters

        <b>Expected results:</b>
        Test passes if is_full_box method return expected bool value

        <b>Steps</b>
        1. Check positive scenario for is_full_box method: x1=y1=0, x2=y2=1
        2. Check negative scenarios for is_full_box method
        """
        full_box_rectangle_params = {"x1": 0.0, "y1": 0.0, "x2": 1.0, "y2": 1.0}
        # Positive scenario for Rectangle instance
        full_box_rectangle = Rectangle(**full_box_rectangle_params)
        assert Rectangle.is_full_box(full_box_rectangle)
        # Negative scenarios for Rectangle instance
        # Generating all scenarios when Rectangle object not a full_box
        keys_list = ["x1", "y1", "x2", "y2"]
        parameter_combinations = []
        for i in range(1, len(keys_list) + 1):
            parameter_combinations.append(list(itertools.combinations(keys_list, i)))
        # In each of scenario creating a copy of full_Box rectangle parameters and replacing to values from prepared
        # dictionary
        not_full_box_values_dict = {"x1": 0.01, "y1": 0.01, "x2": 0.9, "y2": 0.9}
        for combination in parameter_combinations:
            for scenario in combination:
                not_full_box_params = dict(full_box_rectangle_params)
                for key in scenario:
                    not_full_box_params[key] = not_full_box_values_dict.get(key)
                not_full_box_rectangle = Rectangle(**not_full_box_params)
                assert not Rectangle.is_full_box(not_full_box_rectangle), (
                    f"Expected False returned by is_full_box method for rectangle with parameters "
                    f"{not_full_box_params}"
                )
        # Negative scenario for not Rectangle class instance
        assert not Rectangle.is_full_box(str)
    def test_rectangle_coordinates_validation(self):
        """
        <b>Description:</b>
        Check Rectangle coordinates

        <b>Input data:</b>
        Rectangle class initiation parameters

        <b>Expected results:</b>
        Test passes if Rectangle correctly checks coordinates during initiation of Rectangle object

        <b>Steps</b>
        1. Check Rectangle coordinates with correct width and height
        2. Check Rectangle coordinates with incorrect width: (x2 - x1) <= 0
        3. Check Rectangle coordinates with incorrect height: (y2 - y1) <= 0
        4. Check Rectangle coordinates with all coordinates equal 0
        """
        # checks for correct width and height
        self.horizontal_rectangle()
        self.vertical_rectangle()
        self.square()
        with warnings.catch_warnings():
            warnings.filterwarnings("ignore", "Rectangle coordinates")
            Rectangle(x1=0.2, y1=0.1, x2=1.4, y2=1.5)
        Rectangle(x1=0.2, y1=0.1, x2=0.4, y2=0.5)
        # checks for incorrect coordinates
        width_less_than_zero_params = {"x1": 0.4, "y1": 0.0, "x2": 0.1, "y2": 0.2}
        width_equal_zero_params = {"x1": 0.1, "y1": 0.0, "x2": 0.1, "y2": 0.2}
        height_less_than_zero_params = {"x1": 0.1, "y1": 0.4, "x2": 0.3, "y2": 0.1}
        height_params_equal_zero_params = {"x1": 0.1, "y1": 0.4, "x2": 0.3, "y2": 0.4}
        zero_rectangle_params = {"x1": 0.0, "x2": 0.0, "y1": 0.0, "y2": 0.0}
        for incorrect_coordinates in [
            width_less_than_zero_params,
            width_equal_zero_params,
            height_less_than_zero_params,
            height_params_equal_zero_params,
            zero_rectangle_params,
        ]:
            with pytest.raises(ValueError):
                Rectangle(**incorrect_coordinates)
def init_environment(params, model_template, number_of_images=10):
    resolution = (224, 224)
    colors = [(0, 255, 0), (0, 0, 255)]
    cls_names = ['b', 'g']
    texts = ['Blue', 'Green']
    env_labels = [
        LabelEntity(name=name,
                    domain=Domain.CLASSIFICATION,
                    is_empty=False,
                    id=ID(i)) for i, name in enumerate(cls_names)
    ]

    items = []

    for _ in range(0, number_of_images):
        for j, lbl in enumerate(env_labels):
            class_img = np.zeros((*resolution, 3), dtype=np.uint8)
            class_img[:] = colors[j]
            class_img = cv.putText(class_img, texts[j], (50, 50),
                                   cv.FONT_HERSHEY_SIMPLEX, .8 + j * .2,
                                   colors[j - 1], 2, cv.LINE_AA)

            image = Image(data=class_img)
            labels = [ScoredLabel(label=lbl, probability=1.0)]
            shapes = [Annotation(Rectangle.generate_full_box(), labels)]
            annotation_scene = AnnotationSceneEntity(
                kind=AnnotationSceneKind.ANNOTATION, annotations=shapes)
            items.append(
                DatasetItemEntity(media=image,
                                  annotation_scene=annotation_scene))

    rng = random.Random()
    rng.seed(100)
    rng.shuffle(items)
    for i, _ in enumerate(items):
        subset_region = i / number_of_images
        if subset_region >= 0.9:
            subset = Subset.TESTING
        elif subset_region >= 0.6:
            subset = Subset.VALIDATION
        else:
            subset = Subset.TRAINING
        items[i].subset = subset

    dataset = DatasetEntity(items)
    labels_schema = generate_label_schema(dataset.get_labels(),
                                          multilabel=False)
    environment = TaskEnvironment(model=None,
                                  hyper_parameters=params,
                                  label_schema=labels_schema,
                                  model_template=model_template)
    return environment, dataset
Ejemplo n.º 27
0
    def test_shape_intersect_percentage(self):
        """
        <b>Description:</b>
        Check Shape intersect_percentage method for Rectangle, Ellipse and Polygon objects

        <b>Expected results:</b>
        Test passes if intersect_percentage method returns expected values

        <b>Steps</b>
        1. Check intersect_percentage method when Shapes intersect completely
        2. Check intersect_percentage method when Shapes intersect partially
        3. Check intersect_percentage method when Shapes intersect by one side
        4. Check intersect_percentage method when Shapes not intersect
        5. Check GeometryException exception raised with incorrect parameters for intersect_percentage method
        """
        inscribed_shapes_list = [
            self.rectangle(), self.ellipse(),
            self.polygon()
        ]
        # Check when Shapes intersect completely
        for full_element in [
                self.fully_covering_rectangle(),
                self.fully_covering_ellipse(),
                self.fully_covering_polygon(),
        ]:
            for inscribed in inscribed_shapes_list:
                assert round(full_element.intersect_percentage(inscribed),
                             2) == 1.0
        # Check when Shapes intersect partially
        second_rectangle = Rectangle(x1=0.3, y1=0.4, x2=0.7, y2=0.6)
        assert self.rectangle().intersect_percentage(second_rectangle) == 0.75
        assert round(self.ellipse().intersect_percentage(self.rectangle()),
                     2) == 0.44
        assert self.polygon().intersect_percentage(self.rectangle()) == 0.45
        # Check when Shapes intersect by one side
        for upper_shape in self.upper_side_intersect_shapes():
            for lower_shape in self.lower_side_intersect_shapes():
                assert lower_shape.intersect_percentage(upper_shape) == 0.0
        # Check shen Shapes not intersect
        for shape in inscribed_shapes_list:
            for not_inscribed_shape in (
                    self.not_inscribed_rectangle(),
                    self.not_inscribed_ellipse(),
                    self.not_inscribed_polygon(),
            ):
                assert shape.intersect_percentage(not_inscribed_shape) == 0.0
        # Checking GeometryException exception raised
        with pytest.raises(GeometryException):
            with warnings.catch_warnings():
                warnings.filterwarnings("ignore", "Polygon coordinates")
                self.base_self_intersect_polygon().intersect_percentage(
                    self.other_self_intersect_polygon())
 def check_result_media_attributes(result_media: ResultMediaEntity,
                                   expected_values: dict):
     assert result_media.name == expected_values.get("name")
     assert result_media.type == expected_values.get("type")
     assert result_media.annotation_scene == expected_values.get(
         "annotation_scene")
     assert np.array_equal(result_media.numpy, expected_values.get("numpy"))
     if not expected_values.get("roi"):
         assert isinstance(result_media.roi.shape, Rectangle)
         assert Rectangle.is_full_box(result_media.roi.shape)
     else:
         assert result_media.roi == expected_values.get("roi")
     assert result_media.label == expected_values.get("label")
Ejemplo n.º 29
0
    def test_dataset_item_setters(self):
        """
        <b>Description:</b>
        Check DatasetItemEntity class "roi", "subset" and "annotation_scene" setters

        <b>Input data:</b>
        DatasetItemEntity class object with specified "media", "annotation_scene", "roi", "metadata" and "subset"
        parameters

        <b>Expected results:</b>
        Test passes if assigned values of "roi", "subset" and "annotation_scene" properties are equal to expected

        <b>Steps</b>
        1. Check value returned by "roi" property after using @roi.setter
        2. Check value returned by "subset" property after using @subset.setter
        3. Check value returned by "annotation_scene" property after using @subset.annotation_scene
        """
        dataset_item = DatasetItemParameters().dataset_item()
        # Checking value returned by "roi" property after using @roi.setter
        new_roi_label = ScoredLabel(
            LabelEntity("new ROI label", Domain.DETECTION))
        new_dataset_roi = Annotation(Rectangle(x1=0.2, y1=0.2, x2=1.0, y2=1.0),
                                     [new_roi_label])
        dataset_item.roi = new_dataset_roi
        assert dataset_item.roi == new_dataset_roi
        # Checking value returned by subset property after using @subset.setter
        new_subset = Subset.TRAINING
        dataset_item.subset = new_subset
        assert dataset_item.subset == new_subset
        # Checking value returned by annotation_scene property after using @annotation_scene.setter
        new_annotation_label = ScoredLabel(
            LabelEntity("new annotation label", Domain.CLASSIFICATION))
        new_annotation = Annotation(Rectangle(x1=0.1, y1=0, x2=0.9, y2=1.0),
                                    [new_annotation_label])
        new_annotation_scene = AnnotationSceneEntity(
            [new_annotation], AnnotationSceneKind.PREDICTION)
        dataset_item.annotation_scene = new_annotation_scene
        assert dataset_item.annotation_scene == new_annotation_scene
Ejemplo n.º 30
0
 def roi(self):
     roi = Annotation(
         shape=Rectangle(
             x1=0.1,
             y1=0.1,
             x2=0.9,
             y2=0.9,
             modification_date=datetime.datetime(year=2021, month=12,
                                                 day=9),
         ),
         labels=self.roi_scored_labels(),
         id=ID("roi_annotation"),
     )
     return roi