Notebooks

Guide #03: Supervisely SDK for augmentations

iPython Project Created 4 days ago Free
How to perform traditional augmentations to images and their annotations in a few lines
Free Signup

Supervisely Python SDK Tutorial #3: Augmentations

This tutorial covers the image augmentations available in the Supevisely Python SDK. Augmentations are image transformations that preserve the essence of the image content: a cat shifted 100 pixels to the left is still a cat. Augmenting the input data is the standard approach to add diversity to the training data for a neural network without having to acquire and manually label more training images.

In our SDK, there are two modules that contain augmentation functions:

  • aug module contains augmentations that affect the spatial properties of the image: random crops, rotations etc. When objects move around in the image, it is important to modify the annotation in exactly the same way to keep the labels aligned with the modified image. To make sure the the same transformation is applied to both the image and its annotation, the augmentations are done jointly on an image - annotation pair.
  • imaging.image contains image-only augmentations that preserve the spatial structure of the image, such as contrast or brightness changes or injecting noise into the pixels colors. Since none of the objects in the image move with such changes, the original annotations can be safely reused with the augmented image.

In this tutorial we simply go over the available augmentations and visualize their results.

Imports

Required imports

In [1]:
import supervisely_lib as sly  # Supervisely Python SDK

# Matplotlib for rendering images in Jupyter.
%matplotlib inline
import matplotlib.pyplot as plt

Prepare sample input

Here we read an example image - annotation pair from a provided Supervisely project and define convenience helpers for visualizing the results

Load input data

Check out our Tutorial #1 for an in-depth guide on working with on-disk projects and labeling data via Supervisely SDK.

In [2]:
project = sly.Project('./tutorial_project', sly.OpenMode.READ)
img_path, ann_path = project.datasets.get("dataset_01").get_item_paths("image_01")
img = sly.image.read(img_path)
ann = sly.Annotation.load_json_file(ann_path, project.meta)

Define visualization helpers

We will display the original image, overlayed filled labeled objects, and object contours.

In [3]:
#helper function to draw image and annotation
def draw_labeled_image(img, ann):
    canvas_draw = img.copy()
    canvas_draw_contour = img.copy()
    ann.draw(canvas_draw)
    ann.draw_contour(canvas_draw_contour, thickness=4)
    
    fig = plt.figure(figsize=(20, 20))
    #plt.suptitle(title, fontsize=20)
    
    fig.add_subplot(1, 3, 1)
    plt.imshow(img)
    
    fig.add_subplot(1, 3, 2)
    plt.imshow(canvas_draw)
    
    fig.add_subplot(1, 3, 3)
    plt.imshow(canvas_draw_contour)
    
    plt.show()

Original image and its annotation

First let us check out the loaded input image and the labels we have for it. Notice we have multiple label types in one image:

  • A rectangle bounding box for the motorcycle.
  • A binary bitmap mask for the person.
  • A polygonal contour for the dog. This will let us see how the different lable types behave during augmentations.
In [4]:
draw_labeled_image(img, ann)
Out [4]:
<Figure size 1440x1440 with 3 Axes>

Spatial augmentations

These affect both the image and its annotation.

Horizontal flip (left-right)

In [5]:
flipped_img, flipped_ann = sly.aug.fliplr(img, ann)
draw_labeled_image(flipped_img, flipped_ann)
Out [5]:
<Figure size 1440x1440 with 3 Axes>

Vertical flip

In [6]:
flipped_img, flipped_ann = sly.aug.flipud(img, ann)
draw_labeled_image(flipped_img, flipped_ann)
Out [6]: