Rotating

Introduction

In image processing we often have to rotate images for various reasons, such as adjusting an image’s orientation and/or creating variations of the image. In deep learning, we can rotate images help us to augment and enrich the image datasets so that the same image sample would have slight variations while retaining the essence and the pattern of the class, potentially helping the algorithm to generalize and learn a more robust representation of an object.

VisuMorph’s rotate function is designed with this in mind. Beside simple rotation of an image, it can also fill the background of the rotated image so that we can avoid filling our image with unwanted empty spaces. SciPy and PIL do not offer this feature.

Importing libraries

Import the necessary libraries, including rotate, load_image.

from visumorph import rotate, load_image, Image
import numpy as np
from PIL import Image as PImage
from IPython.display import display

Loading the Image

First, we load our sample image for using visumorph.load_image function:

img = load_image("../tests/img/raw/meme.jpg")
meme = PImage.fromarray(img.image)
display(meme)
_images/ec3137c8308ebefcfd5472e1a81fea434bfc903076aec94287e9ab660ac9cfaa.png

Simple rotation

Once loaded the image as a Image object, we can apply rotate on it.

Please note that the rotation should be supplied in degree, and a positive number means clockwise rotation and a negative number means anti-clockwise rotation. This behaviour is different from the popular implementations such as SciPy and PIL.

# simple rotation, 45 degrees clockwise
rotated_45 = rotate(img, 45)

rotated_45 = PImage.fromarray(rotated_45.image)
display(rotated_45)
_images/30fec1eb53f1fc0ed3b295a14d2294e9b2ce464c8130d24a69a8e1bca9665290.png
# simple rotation, 145 degrees anti-clockwise
rotated_neg_145 = rotate(img, -145)

rotated_neg_145 = PImage.fromarray(rotated_neg_145.image)
display(rotated_neg_145)
_images/a94d17d2f1a674b4c2f11292cde5a95c38bb0d518ed3e85808c74473835027e7.png

Rotation with a Background

As you might have noticed that in the previous example there are some black spaces around the corners in the rotated image. This is expected behaviour as depending on the degree of rotation, the rotated image might not be able to cover all the pixels in the original dimension. By default, rotate will fill these empty spaces with black pixels as shown above.

To do this, you can provide a background argument to the rotate function. Let’s say we want to fill our corners with white background:

# using a white pixel as background
white_pixel = Image(np.array([255, 255, 255]).reshape((1, 1, 3)).astype(np.uint8))

# rotate the image with 45 degrees with the white pixel
rotated_with_bg = rotate(img, 45, background=white_pixel)

rotated_with_bg = PImage.fromarray(rotated_with_bg.image)
display(rotated_with_bg)
_images/cff7da09622c12249c883a33b1943776fb4d5e45cc1fc9a564bf7c97e40d0600.png

Additionally, since this function accepts VisuMorph’s Image as background, we can also specify an image instead of simply a colored pixel.

If the image is not large enough for filling the entire image dimension, rotate will tile the image in order to expand the background image until it is able to fill up the entire range of the original image’s dimension:

# using an image as the background
background = img

# rotate the image with 45 degrees with the background
rotated_with_bg = rotate(img, 45, background=background)

rotated_with_bg = PImage.fromarray(rotated_with_bg.image)
display(rotated_with_bg)
_images/b566f24d6adaa1cbfa9ded5fed3dfa776e7b45d6420e50aeb93c625ecbbbfadc.png

By combining different functions in VisuMorph, you can get interesting backgrounds:

from visumorph import scale, flip
# using a transformed image as the background
background = flip(scale(img, 0.05), v=1)

# rotate the image with 45 degrees with the background
rotated_with_bg = rotate(img, 45, background=background)

rotated_with_bg = PImage.fromarray(rotated_with_bg.image)
display(rotated_with_bg)
_images/fd4e449f752f8cd190d5b694bc33899c3b7d9c9141497ec3f33dfea53aa38723.png