First, we need to know what we mean by the above title. So, let’s explore.
What are some Python image manipulation use cases?
So, Python is considered as the Swiss knife of programming languages, as we can do so many things with it. One of them is manipulating images. Image manipulation can include changing resolution, resizing, changing contrast, saturation, file extensions, color channels, and many more.
Python Image Manipulation Modules
Python has multiple image manipulation modules. So, for the scope of this blog, let’s discuss Pillow and OpenCV first.
Pillow and OpenCV
So, Pillow is part of Python’s PIL (Python Imaging Library), it’s as simple as an image manipulation module can be. The functions are simple and a very high level of editing can’t be done with it.
On the other hand, the functions in OpenCV are much more complicated and versatile, you can add masks, extract backgrounds, use bitwise operation on image pixels, and do operations on different colour channels.
Out of those two modules, we are going to use Pillow for this blog to get started. We can move onto the more complicated module, OpenCV, in a future blog.
But the installation and import procedure for OpenCV has still been mentioned.
Installation
For Windows users:
Simply open your ‘cmd’ and type:
For Pillow:
`pip install pillow`
For OpenCV:
`pip install opencv-python `
For Linux users:
For Pillow:
`pip3 install pillow `
For OpenCV:
`pip3 install opencv-python`
To Import Simply
from PIL import Image #for pillow
import cv2 as cv #for opencv
Samples
Going forward, we are going to see the code for the operations, and we might want to perform on below sample images, separated by modules-first Pillow, and then OpenCV.
Referred to as cat.jpg and mountain.jpg
Pillow
Now just a small disclaimer, Pillow has hundreds of functions, and you might need to use many of them, but this blog will only give you an idea on the basic functions and just the feel of the syntax overall.
Any kind of operation you think is possible, you just need to go and search for it.
Let’s hope the function you are looking for is present in this blog, but even if it’s not, you can head over to the pillow documentation here :- https://pillow.readthedocs.io/en/stable/handbook/tutorial.html or https://pillow.readthedocs.io/en/stable/reference/index.html.
Open Image
from PIL import Image
# just opening an image by it’s path
# if image is in the same folder
# we can just write its name
img1 = Image.open(‘cat.jpg’)
img2 = Image.open(‘mountain.jpg’)
# we can use the img object we created to perform operations
img1.show()
img2.show()
# we can also save the image using a different name or extension
img1.save(‘kitty.png’)
This will simply show the image in your default image viewer.
Resize Images
Change Resolution
from PIL import Image
i = Image.open(“cat.jpg”)
print(i.size) # printing out original width and height
i.show()
i_new = i.resize((200,100)) # resizing to new (width, height)
print(i_new.size)
i_new.show()
i_new.save(“cat_resized.jpg”)
Output
We see the original image, the resized image and their shapes as output.
Crop Image
from PIL import Image
img = Image.open(‘./cat.jpg’)
# top left of image is 0,0 and we are selecting the x,y coordinates of the top left and bottom right corner of the crop respectively
img = img.crop((200, 200, 300, 300))
img.show()
So, the crop method takes 4 inputs, which are x1,y1,x2,y2 respectively, and x2 and y2 shouldn’t be more than the size of the image itself.
Move Images
Rotate Image
from PIL import Image
i = Image.open(“mountain.jpg”)
i = i.rotate(90) # inputs in degrees
# saving rotated image
i.save(“mountain_rotated.jpg”)
i.show()
Shift Image
from PIL import Image, ImageChops
img = Image.open(“cat.jpg”)
# first we pass the image then the x axis shift and then the y axis shift respectively
img = ImageChops.offset(img, -200, 100)
img.save(“cat_offset.jpg”)
img.show()
Flip Image
from PIL import Image, ImageOps
i = Image.open(“cat.jpg”)
i_flip = ImageOps.flip(i)
# saving flipped(vertically) image
i_flip.save(“cat_flipped.jpg”)
i_flip.show()
i_mir = ImageOps.mirror(i)
# saving mirrored(horizontally) image
i_mirr.save(“cat_mirrored.jpg”)
i_mirr.show()
Below are the mirrored and flipped outputs, respectively. Keep in mind this doesn’t affect the resolution whatsoever.
Edit Images
Blur Image
from PIL import Image, ImageFilter
i = Image.open(“cat.jpg”)
# there are different types of filters available the number inside the Gaussian Blur decides the strength of the blur
i_blur = i.filter(ImageFilter.GaussianBlur(6))
i_blur.save(“cat_blur.jpg”)
i_blur.show()
Black and White Image
from PIL import Image, ImageFilter
i = Image.open(“cat.jpg”)
# here changing the mode changes the output image colour mode
i_bw = i.convert(mode=’L’)
i_bw.save(“cat_bw.jpg”)
i_bw.show()
# this mode kind of pixelates the lines/edges
i_grain = i.convert(mode=’1′)
i_grain.save(“cat_grain.jpg”)
i_grain.show()
Keep in mind these conversions are mostly mutual. You can mix and match all these conversions.
For example, you can have a blurred, black and white cat image crop .
You can also have a mirrored, grainey resized, and rotated image.
Multiple Operations Example
One thing to keep in mind is that based on the sequence of the operation, the output image can be the same even when the operations are performed in a different order on the same image, or it can be different, depending on the operation types, the sequence and the image.
from PIL import Image, ImageFilter, ImageOps
img = Image.open(‘./cat.jpg’)
# cropping the body area of the cat
img = img.crop((200, 125, 420, 310))
# Blurring the image
img = img.filter(ImageFilter.GaussianBlur(6))
# then mirroring the image
img = ImageOps.mirror(img)
# and converting the image into black and white in the end
img = img.convert(mode=’L’)
img.show()
Mass Operations Example
Now you might have realised that the operations we performed can be done even in an image editing app, even though this is faster as we only need to write a couple of lines of code.
But coding the image edits has a significant advantage in a scenario, when we have hundreds of images.
We can integrate the Pillow module functions with the Python syntax and apply logic, and we can use if else conditions or for loops, so filter out images based on name and then perform operations based on that.
Using loops, we can perform operations on hundreds, even tens of thousands of images with simple lines of code, which is impractical if we open images one by one in an application.
So let’s take this huge dataset, for example : https://www.kaggle.com/cashutosh/gender-classification-dataset
Now here, the resolutions and names are different and not at all organised, so we will use Pillow to resize and rename all these images one by one:
from PIL import Image
import os # we need os to list out the files in the dataset folder
# let’s take the training dataset for now and we can repeat the process for the test dataset by just changing the root
root = “./gender_dataset/train”
# here we are storing the different folder names in a list
folders = os.listdir(root)
folders.sort()
# now we are iterating on the folders
for folder in folders:
# now for every folder we are listing out all the files(images) inside that folder
files = os.listdir(root+folder)
print(folder)
x = 0
for file in files:
# any if condition can be used here based on the file name eg.
# if “.png” in file:
# continue
# this number will be used for new image names
x+=1
# now we open the images
i = Image.open(root + folder + “/”+ file)
# here we resize all the images to 1 resolution
i = i.resize((96,64))
# and save the images with new name in a different folder with same name
i.save(“./gender_resized/train/”+folder+”/”+str(x)+”.jpg”)
# just printing out the name of the image so know our progress
print(x)
Output Folder:
Just the first few images
Conclusion
Now, we hope you’ve learned about how one can use Python modules for image manipulation. Simple as it may be, Pillow is still much better and faster when you want to perform basic operations on a huge number of images.
Many more advanced image operations are left and will be continued in the next part of this blog, in which we will use OpenCV to perform image manipulation.
Simple as it may be, Pillow is still much better and faster when you want to perform basic operations on a huge number of images. If you enjoyed reading this blog, you can also read this blog-’’Image Classification with Python.’’