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)
    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
    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 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")
Beispiel #5
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