Ejemplo n.º 1
0
def rotate(img: np.ndarray, ann: Annotation, degrees: float, mode: str=RotationModes.KEEP) ->\
        (np.ndarray, Annotation):  # @TODO: add "preserve_size" mode
    """
    Rotates the image by random angle.

    Args:
        img: Input image array.
        ann: Input annotation.
        degrees: Rotation angle, counter-clockwise.
        mode: parameter: "keep" - keep original image data, then new regions will be filled with black color;
            "crop" - crop rotated result to exclude black regions;
    Returns:
        A tuple containing rotated image array and annotation.
    """
    _validate_image_annotation_shape(img, ann)
    rotator = ImageRotator(img.shape[:2], degrees)

    if mode == RotationModes.KEEP:
        rect_to_crop = None

    elif mode == RotationModes.CROP:
        rect_to_crop = rotator.inner_crop

    else:
        raise NotImplementedError('Wrong black_regions mode.')

    res_img = rotator.rotate_img(img, use_inter_nearest=False)
    res_ann = ann.rotate(rotator)
    if rect_to_crop is not None:
        res_img = sly_image.crop(res_img, rect_to_crop)
        res_ann = res_ann.relative_crop(rect_to_crop)
    return res_img, res_ann
Ejemplo n.º 2
0
def crop(img: np.ndarray,
         ann: Annotation,
         top_pad: int = 0,
         left_pad: int = 0,
         bottom_pad: int = 0,
         right_pad: int = 0) -> (np.ndarray, Annotation):
    """
    Crops the given image array and annotation from all sides with the given values.

    Args:
        img: Input image array.
        ann: Input annotation.
        top_pad: The size in pixels of the piece of picture that will be cut from the top side.
        left_pad: The size in pixels of the piece of picture that will be cut from the left side.
        bottom_pad: The size in pixels of the piece of picture that will be cut from the bottom side.
        right_pad: The size in pixels of the piece of picture that will be cut from the right side.
    Returns:
        A tuple containing cropped image array and annotation.
    """
    _validate_image_annotation_shape(img, ann)
    height, width = img.shape[:2]
    crop_rect = Rectangle(top_pad, left_pad, height - bottom_pad - 1,
                          width - right_pad - 1)

    res_img = sly_image.crop(img, crop_rect)
    res_ann = ann.relative_crop(crop_rect)
    return res_img, res_ann
Ejemplo n.º 3
0
def instance_crop(img: np.ndarray,
                  ann: Annotation,
                  class_title: str,
                  save_other_classes_in_crop: bool = True,
                  padding_config: dict = None) -> list:
    """
    Crops objects of specified classes from image with configurable padding.

    Args:
        img: Input image array.
        ann: Input annotation.
        class_title: Name of class to crop.
        save_other_classes_in_crop: save non-target classes in each cropped annotation.
        padding_config: Dict with padding
    Returns:
        List of cropped [image, annotation] pairs.
    """
    padding_config = take_with_default(padding_config, {})
    _validate_image_annotation_shape(img, ann)
    results = []
    img_rect = Rectangle.from_size(img.shape[:2])

    if save_other_classes_in_crop:
        non_target_labels = [
            label for label in ann.labels
            if label.obj_class.name != class_title
        ]
    else:
        non_target_labels = []

    ann_with_non_target_labels = ann.clone(labels=non_target_labels)

    for label in ann.labels:
        if label.obj_class.name == class_title:
            src_fig_rect = label.geometry.to_bbox()
            new_img_rect = _rect_from_bounds(padding_config,
                                             img_w=src_fig_rect.width,
                                             img_h=src_fig_rect.height)
            rect_to_crop = new_img_rect.translate(src_fig_rect.top,
                                                  src_fig_rect.left)
            crops = rect_to_crop.crop(img_rect)
            if len(crops) == 0:
                continue
            rect_to_crop = crops[0]
            image_crop = sly_image.crop(img, rect_to_crop)

            cropped_ann = ann_with_non_target_labels.relative_crop(
                rect_to_crop)

            label_crops = label.relative_crop(rect_to_crop)
            for label_crop in label_crops:
                results.append((image_crop, cropped_ann.add_label(label_crop)))
    return results