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")
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