def generate_labels_list(include_empty: bool = True) -> list: classification_label = ScoredLabel( LabelEntity( name="classification", domain=Domain.CLASSIFICATION, color=Color(red=187, green=28, blue=28), creation_date=datetime(year=2021, month=10, day=25), )) detection_label = ScoredLabel( LabelEntity( name="detection", domain=Domain.DETECTION, color=Color(red=180, green=30, blue=24), creation_date=datetime(year=2021, month=9, day=24), )) empty_label = ScoredLabel( LabelEntity( name="empty_rectangle_label", domain=Domain.CLASSIFICATION, color=Color(red=178, green=25, blue=30), creation_date=datetime(year=2021, month=7, day=26), is_empty=True, )) labels_list = [classification_label, detection_label] if include_empty: labels_list.append(empty_label) return labels_list
def get_ancestors_by_prediction( label_schema: LabelSchemaEntity, prediction: ScoredLabel ) -> List[ScoredLabel]: """ Get all the ancestors for a given label node """ ancestor_labels = label_schema.get_ancestors(prediction.get_label()) return [ScoredLabel(al, prediction.probability) for al in ancestor_labels]
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 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_shape_entity_not_implemented_methods(self): """ <b>Description:</b> Check not implemented methods of ShapeEntity class <b>Expected results:</b> Test passes if NotImplementedError exception raises when using not implemented methods on ShapeEntity instance """ rectangle_entity = Rectangle(x1=0.2, y1=0.2, x2=0.6, y2=0.7) ellipse_entity = Ellipse(x1=0.4, y1=0.1, x2=0.9, y2=0.8) polygon_entity = Polygon([ Point(0.3, 0.4), Point(0.3, 0.7), Point(0.5, 0.75), Point(0.8, 0.7), Point(0.8, 0.4), ]) for shape in [rectangle_entity, ellipse_entity, polygon_entity]: with pytest.raises(NotImplementedError): ShapeEntity.get_area(shape) with pytest.raises(NotImplementedError): ShapeEntity.intersects(shape, shape) with pytest.raises(NotImplementedError): ShapeEntity.intersect_percentage(shape, shape) with pytest.raises(NotImplementedError): ShapeEntity.get_labels(shape) with pytest.raises(NotImplementedError): ShapeEntity.append_label( shape, ScoredLabel( LabelEntity(name="classification", domain=Domain.CLASSIFICATION)), ) with pytest.raises(NotImplementedError): ShapeEntity.set_labels( shape, [ ScoredLabel( LabelEntity(name="detection", domain=Domain.DETECTION)) ], ) with pytest.raises(NotImplementedError): ShapeEntity.normalize_wrt_roi_shape(shape, rectangle_entity) with pytest.raises(NotImplementedError): ShapeEntity.denormalize_wrt_roi_shape(shape, rectangle_entity) with pytest.raises(NotImplementedError): ShapeEntity._as_shapely_polygon(shape)
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
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 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
def test_annotation_scene_entity_get_label_ids(self): """ <b>Description:</b> Check Annotation get_label_ids method <b>Input data:</b> Initialized instance of AnnotationSceneEntity <b>Expected results:</b> Test passes if AnnotationSceneEntity get_label_ids method returns correct values <b>Steps</b> 1. Create AnnotationSceneEntity instances 2. Check returning value of get_label_ids method """ annotation_scene_entity = self.annotation_scene_entity assert annotation_scene_entity.get_label_ids() == {ID()} bus = LabelEntity(id=ID(123456789), name="bus", domain=Domain.DETECTION) bus_label = ScoredLabel(bus) labels = [bus_label] annotation = Annotation(shape=self.rectangle, labels=labels) annotation_scene_entity.append_annotation(annotation) assert annotation_scene_entity.get_label_ids() == {ID(), ID(123456789)}
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
def test_annotation_scene_entity_append_annotation(self): """ <b>Description:</b> Check Annotation append_annotation method <b>Input data:</b> Initialized instance of AnnotationSceneEntity <b>Expected results:</b> Test passes if AnnotationSceneEntity append_annotation method returns correct values <b>Steps</b> 1. Create AnnotationSceneEntity instances 2. Check returning value of append_annotation method """ annotation_scene_entity = self.annotation_scene_entity tree = LabelEntity(name="tree", domain=Domain.DETECTION) tree_label = ScoredLabel(tree) labels = [tree_label] annotation = Annotation(shape=self.rectangle, labels=labels) assert len(annotation_scene_entity.annotations) == 2 annotation_scene_entity.append_annotation(annotation) assert len(annotation_scene_entity.annotations) == 3
def get_multiclass_predictions(logits: np.ndarray, labels: List[LabelEntity], activate: bool = True) -> List[ScoredLabel]: i = np.argmax(logits) if activate: logits = softmax_numpy(logits) return [ScoredLabel(labels[i], probability=float(logits[i]))]
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)
def rectangle_labels() -> list: rectangle_label = LabelEntity( name="Rectangle label", domain=Domain.DETECTION, color=Color(red=100, green=50, blue=200), id=ID("rectangle_label_1"), ) other_rectangle_label = LabelEntity( name="Other rectangle label", domain=Domain.SEGMENTATION, color=Color(red=200, green=80, blue=100), id=ID("rectangle_label_2"), ) return [ ScoredLabel(label=rectangle_label), ScoredLabel(label=other_rectangle_label), ]
def test_scored_label(self): """ <b>Description:</b> Check the ScoredLabel can correctly return the value <b>Input data:</b> LabelEntity <b>Expected results:</b> Test passes if the results match """ car = LabelEntity(id=ID(123456789), name="car", domain=Domain.DETECTION, is_empty=True) person = LabelEntity(id=ID(987654321), name="person", domain=Domain.DETECTION, is_empty=True) car_label = ScoredLabel(car) person_label = ScoredLabel(person) for attr in [ "id", "name", "color", "hotkey", "creation_date", "is_empty" ]: assert getattr(car_label, attr) == getattr(car, attr) assert car_label.get_label() == car assert car_label == ScoredLabel(car) assert car_label != car assert car_label != person_label assert hash(car_label) == hash(str(car_label)) probability = 0.0 assert car_label.probability == probability delta_probability = 0.4 probability += delta_probability car_label.probability += delta_probability assert car_label.probability == probability car.color = Color(red=16, green=15, blue=56, alpha=255) assert ( "ScoredLabel(123456789, name=car, probability=0.4, domain=DETECTION, color=" in repr(car_label)) assert "Color(red=16, green=15, blue=56, alpha=255), hotkey=ctrl+0)" in repr( car_label)
def test_shape_set_labels(self): """ <b>Description:</b> Check Shape set_labels method for Rectangle, Ellipse and Polygon objects <b>Expected results:</b> Test passes if set_labels method returns expected values <b>Steps</b> 1. Check set_labels method to add labels list to Shape object with no labels specified 2. Check set_labels method to add empty labels list to Shape object with no labels specified 3. Check set_labels method to add labels list to Shape object with labels specified 4. Check set_labels method to add empty labels list to Shape object with labels specified """ not_empty_label = self.appendable_label() new_labels_list = [ not_empty_label, ScoredLabel( LabelEntity( name="new_label", domain=Domain.CLASSIFICATION, color=Color(red=183, green=31, blue=28), creation_date=datetime(year=2021, month=9, day=25), is_empty=True, )), ] expected_not_empty_labels_list = [not_empty_label] # Check for adding labels list to Shape with no labels specified for no_labels_shape in [ self.fully_covering_rectangle(), self.fully_covering_ellipse(), self.fully_covering_polygon(), ]: no_labels_shape.set_labels(new_labels_list) assert no_labels_shape.get_labels( ) == expected_not_empty_labels_list assert no_labels_shape.get_labels( include_empty=True) == new_labels_list # Check for adding empty labels list to Shape with no labels specified for no_labels_shape in [ self.fully_covering_rectangle(), self.fully_covering_ellipse(), self.fully_covering_polygon(), ]: no_labels_shape.set_labels([]) assert no_labels_shape.get_labels() == [] assert no_labels_shape.get_labels(include_empty=True) == [] # Check for adding labels list to Shape with labels specified for shape in [self.rectangle(), self.ellipse(), self.polygon()]: shape.set_labels(new_labels_list) assert shape.get_labels() == expected_not_empty_labels_list assert shape.get_labels(include_empty=True) == new_labels_list # Check for adding empty labels list to Shape with labels specified for shape in [self.rectangle(), self.ellipse(), self.polygon()]: shape.set_labels([]) assert shape.get_labels() == [] assert shape.get_labels(include_empty=True) == []
def appendable_label(empty=False) -> ScoredLabel: return ScoredLabel( LabelEntity( name="appended_label", domain=Domain.CLASSIFICATION, color=Color(red=181, green=28, blue=31), creation_date=datetime(year=2021, month=11, day=22), is_empty=empty, ))
def test_dataset_item_append_annotations(self): """ <b>Description:</b> Check DatasetItemEntity class "append_annotations" method <b>Input data:</b> DatasetItemEntity class object with specified "media", "annotation_scene", "roi", "metadata" and "subset" parameters <b>Expected results:</b> Test passes if annotations list returned after "append_annotations" method is equal to expected <b>Steps</b> 1. Check annotations list returned after "append_annotations" method with specified non-included annotations 2. Check annotations list returned after "append_annotations" method with incorrect shape annotation """ # Checking annotations list returned after "append_annotations" method with specified non-included annotations dataset_item = DatasetItemParameters().default_values_dataset_item() full_box_annotations = list(dataset_item.annotation_scene.annotations) annotations_to_add = self.annotations_to_add() normalized_annotations = [] for annotation in annotations_to_add: normalized_annotations.append( Annotation( shape=annotation.shape.normalize_wrt_roi_shape( dataset_item.roi.shape), labels=annotation.get_labels(), )) dataset_item.append_annotations(annotations_to_add) # Random id is generated for normalized annotations normalized_annotations[ 0].id = dataset_item.annotation_scene.annotations[2].id normalized_annotations[ 1].id = dataset_item.annotation_scene.annotations[3].id assert ( dataset_item.annotation_scene.annotations == full_box_annotations + normalized_annotations) # Checking annotations list returned after "append_annotations" method with incorrect shape annotation incorrect_shape_label = LabelEntity( name="Label for incorrect shape", domain=Domain.CLASSIFICATION, color=Color(red=80, green=70, blue=155), id=ID("incorrect_shape_label"), ) incorrect_polygon = Polygon( [Point(x=0.01, y=0.1), Point(x=0.35, y=0.1), Point(x=0.35, y=0.1)]) incorrect_shape_annotation = Annotation( shape=incorrect_polygon, labels=[ScoredLabel(incorrect_shape_label)], id=ID("incorrect_shape_annotation"), ) dataset_item.append_annotations([incorrect_shape_annotation]) assert ( dataset_item.annotation_scene.annotations == full_box_annotations + normalized_annotations)
def convert_to_annotation( self, predictions: List[Tuple[int, float]], metadata: Optional[Dict] = None) -> AnnotationSceneEntity: labels = [] for index, score in predictions: labels.append(ScoredLabel(self.labels[index], float(score))) if not labels and self.empty_label: labels = [ScoredLabel(self.empty_label, probability=1.0)] elif self.hierarchical: labels.extend( get_ancestors_by_prediction(self.label_schema, labels[0])) annotations = [ Annotation(Rectangle.generate_full_box(), labels=labels) ] return AnnotationSceneEntity(kind=AnnotationSceneKind.PREDICTION, annotations=annotations)
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
def get_multilabel_predictions(logits: np.ndarray, labels: List[LabelEntity], pos_thr: float = 0.5, activate: bool = True) -> List[ScoredLabel]: if activate: logits = sigmoid_numpy(logits) item_labels = [] for i in range(logits.shape[0]): if logits[i] > pos_thr: label = ScoredLabel(label=labels[i], probability=float(logits[i])) item_labels.append(label) return item_labels
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
def test_annotation_scene_entity_contains_any(self): """ <b>Description:</b> Check Annotation contains_any method <b>Input data:</b> Initialized instance of AnnotationSceneEntity <b>Expected results:</b> Test passes if AnnotationSceneEntity contains_any method returns correct values <b>Steps</b> 1. Create AnnotationSceneEntity instances 2. Check returning value of contains_any method """ annotation_scene_entity = self.annotation_scene_entity annotation_scene_entity.annotations = self.annotations car = LabelEntity(name="car", domain=Domain.DETECTION, is_empty=True) person = LabelEntity(name="person", domain=Domain.DETECTION) tree = LabelEntity(name="tree", domain=Domain.DETECTION) car_label = ScoredLabel(car) person_label = ScoredLabel(person) tree_label = ScoredLabel(tree) labels = [car_label] labels2 = [car_label, person_label] annotation = Annotation(shape=self.rectangle, labels=labels2) annotations = [annotation] annotation_scene_entity2 = AnnotationSceneEntity( annotations=annotations, kind=AnnotationSceneKind.ANNOTATION) assert annotation_scene_entity.contains_any(labels=labels) is False assert annotation_scene_entity2.contains_any(labels=labels2) is True assert annotation_scene_entity2.contains_any( labels=[tree_label]) is False
def convert_to_annotation( self, predictions: np.ndarray, metadata: Dict[str, Any]) -> AnnotationSceneEntity: pred_score = predictions.reshape(-1).max() pred_label = pred_score >= metadata.get("threshold", 20) assigned_label = self.anomalous_label if pred_label else self.normal_label annotations = [ Annotation( Rectangle.generate_full_box(), labels=[ ScoredLabel(assigned_label, probability=float(pred_score)) ], ) ] return AnnotationSceneEntity(kind=AnnotationSceneKind.PREDICTION, annotations=annotations)
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 convert_to_annotation( self, predictions: List[utils.Detection], metadata: Dict[str, Any]) -> AnnotationSceneEntity: annotations = [] image_size = metadata["original_shape"][1::-1] for box in predictions: scored_label = ScoredLabel(self.labels[int(box.id)], float(box.score)) coords = np.array(box.get_coords(), dtype=float) / np.tile( image_size, 2) annotations.append( Annotation( Rectangle(coords[0], coords[1], coords[2], coords[3]), labels=[scored_label], )) annotation_scene = AnnotationSceneEntity( kind=AnnotationSceneKind.PREDICTION, annotations=annotations, ) return annotation_scene
def get_dataset_items(self, ann_file_path: Path, data_root_dir: Path, subset: Subset) -> List[DatasetItemEntity]: """Loads dataset based on the image path in annotation file. Args: ann_file_path (Path): Path to json containing the annotations. For example of annotation look at `data/anomaly/[train, test,val].json. data_root_dir (Path): Path to folder containing images. subset (Subset): Subset of the dataset. Returns: List[DatasetItemEntity]: List containing subset dataset. """ # read annotation file samples = pd.read_json(ann_file_path) dataset_items = [] for _, sample in samples.iterrows(): # Create image # convert path to str as PosixPath is not supported by Image image = Image(file_path=str(data_root_dir / sample.image_path)) # Create annotation shape = Rectangle(x1=0, y1=0, x2=1, y2=1) label: LabelEntity = (self.normal_label if sample.label == "good" else self.abnormal_label) labels = [ScoredLabel(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=subset) # Add to dataset items dataset_items.append(dataset_item) return dataset_items
def __convert_to_annotations(self, predictions: np.ndarray) -> List[Annotation]: """ Converts a list of Detections to OTE SDK Annotation objects :param predictions: A list of predictions with shape [num_prediction, 6] or [num_predictions, 7] :returns: A list of Annotation objects with Rectangle shapes :raises ValueError: This error is raised if the shape of prediction is not (n, 7) or (n, 6) """ annotations = [] if predictions.shape[1:] < (6, ) or predictions.shape[1:] > (7, ): raise ValueError( f"Shape of prediction is not expected, expected (n, 7) or (n, 6) " f"got {predictions.shape}") for prediction in predictions: if prediction.shape == (7, ): # Some OpenVINO models use an output shape of [7,] # If this is the case, skip the first value as it is not used prediction = prediction[1:] label = int(prediction[0]) confidence = prediction[1] scored_label = ScoredLabel(self.label_map[label], confidence) annotations.append( Annotation( Rectangle(prediction[2], prediction[3], prediction[4], prediction[5]), labels=[scored_label], )) return annotations
def generate_random_annotated_image( image_width: int, image_height: int, labels: Sequence[LabelEntity], min_size=50, max_size=250, shape: Optional[str] = None, max_shapes: int = 10, intensity_range: List[Tuple[int, int]] = None, random_seed: Optional[int] = None, ) -> Tuple[np.ndarray, List[Annotation]]: """ Generate a random image with the corresponding annotation entities. :param intensity_range: Intensity range for RGB channels ((r_min, r_max), (g_min, g_max), (b_min, b_max)) :param max_shapes: Maximum amount of shapes in the image :param shape: {"rectangle", "ellipse", "triangle"} :param image_height: Height of the image :param image_width: Width of the image :param labels: Task Labels that should be applied to the respective shape :param min_size: Minimum size of the shape(s) :param max_size: Maximum size of the shape(s) :param random_seed: Seed to initialize the random number generator :return: uint8 array, list of shapes """ from skimage.draw import random_shapes, rectangle if intensity_range is None: intensity_range = [(100, 200)] image1: Optional[np.ndarray] = None sc_labels = [] # Sporadically, it might happen there is no shape in the image, especially on low-res images. # It'll retry max 5 times until we see a shape, and otherwise raise a runtime error if ( shape == "ellipse" ): # ellipse shape is not available in random_shapes function. use circle instead shape = "circle" for _ in range(5): rand_image, sc_labels = random_shapes( (image_height, image_width), min_shapes=1, max_shapes=max_shapes, intensity_range=intensity_range, min_size=min_size, max_size=max_size, shape=shape, random_seed=random_seed, ) num_shapes = len(sc_labels) if num_shapes > 0: image1 = rand_image break if image1 is None: raise RuntimeError( "Was not able to generate a random image that contains any shapes") annotations: List[Annotation] = [] for sc_label in sc_labels: sc_label_name = sc_label[0] sc_label_shape_r = sc_label[1][0] sc_label_shape_c = sc_label[1][1] y_min, y_max = max(0.0, float(sc_label_shape_r[0] / image_height)), min( 1.0, float(sc_label_shape_r[1] / image_height)) x_min, x_max = max(0.0, float(sc_label_shape_c[0] / image_width)), min( 1.0, float(sc_label_shape_c[1] / image_width)) if sc_label_name == "ellipse": # Fix issue with newer scikit-image libraries that generate ellipses. # For now we render a rectangle on top of it sc_label_name = "rectangle" rr, cc = rectangle( start=(sc_label_shape_r[0], sc_label_shape_c[0]), end=(sc_label_shape_r[1] - 1, sc_label_shape_c[1] - 1), shape=image1.shape, ) image1[rr, cc] = ( random.randint(0, 200), # nosec random.randint(0, 200), # nosec random.randint(0, 200), # nosec ) if sc_label_name == "circle": sc_label_name = "ellipse" label_matches = [ label for label in labels if sc_label_name == label.name ] if len(label_matches) > 0: label = label_matches[0] box_annotation = Annotation( Rectangle(x1=x_min, y1=y_min, x2=x_max, y2=y_max), labels=[ScoredLabel(label, probability=1.0)], ) annotation: Annotation if label.name == "ellipse": annotation = Annotation( Ellipse( x1=box_annotation.shape.x1, y1=box_annotation.shape.y1, x2=box_annotation.shape.x2, y2=box_annotation.shape.y2, ), labels=box_annotation.get_labels(include_empty=True), ) elif label.name == "triangle": points = [ Point( x=(box_annotation.shape.x1 + box_annotation.shape.x2) / 2, y=box_annotation.shape.y1, ), Point(x=box_annotation.shape.x1, y=box_annotation.shape.y2), Point(x=box_annotation.shape.x2, y=box_annotation.shape.y2), ] annotation = Annotation( Polygon(points=points), labels=box_annotation.get_labels(include_empty=True), ) else: annotation = box_annotation annotations.append(annotation) else: logger.warning( "Generated a random image, but was not able to associate a label with a shape. " f"The name of the shape was `{sc_label_name}`. ") return image1, annotations
class TestAnnotation: rectangle = Rectangle(x1=0.5, x2=1.0, y1=0.0, y2=0.5) labels: List[ScoredLabel] = [] annotation = Annotation(shape=rectangle, labels=labels) car = LabelEntity( id=ID(123456789), name="car", domain=Domain.DETECTION, color=Color(red=16, green=15, blue=56, alpha=255), is_empty=True, ) person = LabelEntity( id=ID(987654321), name="person", domain=Domain.DETECTION, color=Color(red=11, green=18, blue=38, alpha=200), is_empty=False, ) car_label = ScoredLabel(car) person_label = ScoredLabel(person) labels2 = [car_label, person_label] @pytest.mark.priority_medium @pytest.mark.component @pytest.mark.reqids(Requirements.REQ_1) def test_annotation_default_property(self): """ <b>Description:</b> Check that Annotation can correctly return default property value <b>Input data:</b> Annotation class <b>Expected results:</b> Test passes if the Annotation return correct values <b>Steps</b> 1. Create Annotation instances 2. Check default values """ annotation = self.annotation assert type(annotation.id) == ID assert annotation.id is not None assert str(annotation.shape ) == "Rectangle(x=0.5, y=0.0, width=0.5, height=0.5)" assert annotation.get_labels() == [] @pytest.mark.priority_medium @pytest.mark.component @pytest.mark.reqids(Requirements.REQ_1) def test_annotation_setters(self): """ <b>Description:</b> Check that Annotation can correctly return modified property value <b>Input data:</b> Annotation class <b>Expected results:</b> Test passes if the Annotation return correct values <b>Steps</b> 1. Create Annotation instances 2. Set another values 3. Check changed values """ annotation = self.annotation ellipse = Ellipse(x1=0.5, y1=0.1, x2=0.8, y2=0.3) annotation.shape = ellipse annotation.id = ID(123456789) assert annotation.id == ID(123456789) assert annotation.shape == ellipse @pytest.mark.priority_medium @pytest.mark.component @pytest.mark.reqids(Requirements.REQ_1) def test_annotation_magic_methods(self): """ <b>Description:</b> Check Annotation __repr__, __eq__ methods <b>Input data:</b> Initialized instance of Annotation <b>Expected results:</b> Test passes if Annotation magic methods returns correct values <b>Steps</b> 1. Create Annotation instances 2. Check returning value of magic methods """ annotation = self.annotation other_annotation = self.annotation point1 = Point(0.3, 0.1) point2 = Point(0.8, 0.3) point3 = Point(0.6, 0.2) points = [point1, point2, point3] third_annotation = Annotation(shape=Polygon(points=points), labels=self.labels) assert ( repr(annotation) == "Annotation(shape=Ellipse(x1=0.5, y1=0.1, x2=0.8, y2=0.3), labels=[], id=123456789)" ) assert annotation == other_annotation assert annotation != third_annotation assert annotation != str @pytest.mark.priority_medium @pytest.mark.component @pytest.mark.reqids(Requirements.REQ_1) def test_annotation_get_labels(self): """ <b>Description:</b> Check Annotation get_labels method <b>Input data:</b> Initialized instance of Annotation <b>Expected results:</b> Test passes if Annotation get_labels method returns correct values <b>Steps</b> 1. Create Annotation instances 2. Check returning value of get_labels method 3. Check returning value of get_labels method with include_empty=True """ annotation = Annotation(shape=self.rectangle, labels=self.labels2) assert ( "[ScoredLabel(987654321, name=person, probability=0.0, domain=DETECTION," in str(annotation.get_labels())) assert "color=Color(red=11, green=18, blue=38, alpha=200), hotkey=)]" in str( annotation.get_labels()) assert "[ScoredLabel(123456789, name=car" in str( annotation.get_labels(include_empty=True)) assert ", probability=0.0, domain=DETECTION," in str( annotation.get_labels(include_empty=True)) assert "color=Color(red=16, green=15," in str( annotation.get_labels(include_empty=True)) assert "blue=56, alpha=255), hotkey=ctrl+0)," in str( annotation.get_labels(include_empty=True)) @pytest.mark.priority_medium @pytest.mark.component @pytest.mark.reqids(Requirements.REQ_1) def test_annotation_get_label_ids(self): """ <b>Description:</b> Check Annotation get_label_ids method <b>Input data:</b> Initialized instance of Annotation <b>Expected results:</b> Test passes if Annotation get_label_ids method returns correct values <b>Steps</b> 1. Create Annotation instances 2. Check returning value of get_label_ids method 3. Check returning value of get_label_ids method with include_empty=True """ annotation = Annotation(shape=self.rectangle, labels=self.labels2) assert annotation.get_label_ids() == {ID(987654321)} assert annotation.get_label_ids(include_empty=True) == { ID(987654321), ID(123456789), } @pytest.mark.priority_medium @pytest.mark.component @pytest.mark.reqids(Requirements.REQ_1) def test_annotation_append_label(self): """ <b>Description:</b> Check Annotation append_label method <b>Input data:</b> Initialized instance of Annotation <b>Expected results:</b> Test passes if Annotation append_label method correct appending label <b>Steps</b> 1. Create Annotation instances 2. Append label 3. Check labels """ annotation = self.annotation annotation.append_label(label=self.car_label) assert annotation.get_labels() == [] # car_label is empty annotation.append_label(label=self.person_label) assert "name=person" in str(annotation.get_labels()) @pytest.mark.priority_medium @pytest.mark.component @pytest.mark.reqids(Requirements.REQ_1) def test_annotation_set_labels(self): """ <b>Description:</b> Check Annotation set_labels method <b>Input data:</b> Initialized instance of Annotation <b>Expected results:</b> Test passes if Annotation set_labels method correct setting label <b>Steps</b> 1. Create Annotation instances 2. Set labels 3. Check labels """ annotation = self.annotation assert annotation.get_labels() != [] annotation.set_labels(labels=[]) assert annotation.get_labels() == [] annotation.set_labels(labels=self.labels2) assert "name=person" in str(annotation.get_labels()) assert "name=car" not in str( annotation.get_labels()) # car_label is empty