def draw(self, image: np.ndarray, entity: Annotation, labels: List[ScoredLabel]) -> np.ndarray: """ Draw the labels of a shape in the image top left corner :param image: Image :param entity: Annotation :param labels: labels to be drawn on the image """ return self.draw_labels(image, entity.get_labels())
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))
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