This is a tutorial about how to write a simple code in Python to show the differences between 2 images.
Although It’s a crude code this can be very useful for practicing fundamental programming skills. You can also find a more elegant approach here. (soon to be published.)
In something like 25 lines of code you can see the demonstration of:
for loops, PIL library usage, manual counter (c), conditional expression (if – else), continue / break statement and data array subtraction (numpy).
- Quick styling of matplotlib graphs and charts.
First thing first, let’s get out the Python libraries and make them ready to use:
import numpy as np import cv2 import PIL from PIL import Image from PIL import ImageDraw
Course Provided by
Imageand discover its capabilities.
At this point you are ready to open an image file. All you need is to assign an image path and then open it with Image using:
Image.open(f) where f is the path.
f1 = r'C://Users/xx/Desktop/macfd.jpg' f2 = r'C://Users/xx/Desktop/macfd2.jpg' data1 = Image.open(f1) data2 = Image.open(f2)
Hudson River (on the right) is the river between Manhattan and New Jersey and the river between Manhattan and Brooklyn is called East River (on the left).
Here is the same image with a tiny difference.
On January 15, 2009, some New Yorkers couldn’t believe their eyes as an Airbus A320 descended and smoothly touched down on Hudson River in a matter of a couple of minutes. Plane “rivered” somewhere across 48th Street saving lives of all 155 people on board.
Captain Sullenberger’s heroic achievement was going to be remembered as Miracle on the Hudson describing the unlikely odds of his massive aircraft successfully ditched on Hudson River after suffering a strike with a flock of Canada geese and lost both engines shortly after taking off from New York’s own LaGuardia Airport.
Let’s see if Python can tell the difference between a normal Hudson River and Hudson River with an Airbus A320 on it.
Let’s start with converting the image to Black & White (“L”) in order to eliminate color differences and achieve computation simplicity with one channel color mode.
data3 = data1.convert("L") data4 = data2.convert("L")
Now, let’s get the pixels of each image.
raw1 = data3.getdata() raw2 = data4.getdata()
We imported numpy to subtract 2 pixel arrays from each other. Now it’s time to shine for numpy:
diff_pix = np.subtract(raw1,raw2)
Now let’s create an empty image same size as others and create an image from the differences between 2 previous images:
img_final = Image.new("L",(602,756)) img_final.putdata(diff_pix)
Code below might appear complex, it’s not. First half is figuring out where the big pixel difference happens. Second half is drawing an appropriate rectangle.
Last 3 lines is to show the image and save it as well. (I had to save the image to show it on this page, you may wanna skip that step.)
- To see a tutorial about drawing on images and calculating box position you can see this post here.
- To see a tutorial about digital image pixel positions you can see this post here.
So the code is simple.
It looks for the first pixel where pixel difference between images is bigger than 25. As soon as it’s bigger than 25 the counter stops showing the different pixel’s position.
Then a division by 602 (image’s horizontal resolution) gives us the coordinates to draw the box.
Box is drawn with an approximate negative margin so that the box covers the object as a whole.
c=0 for i in diff_pix: if i > 25: break else: c+=1 x10 = c%602 y10 = c//602 x1,y1,x2,y2 = x10-30, y10-20, x10+30, y10+20 Drawer = ImageDraw.Draw(data2) Drawer.rectangle((x1, y1, x2, y2), outline="red", width=3) f3 = r'C://Users/xx/Desktop/macfd3.bmp' data2.show() data2.save(f3)
Voila! We have an image with a drawing that points out the difference. It’s relatively manual and crude which can be good if you’re looking to practice a lot of fundamental coding concepts.
FULL PYTHON CODE
#Opening images and converting to B&W f1 = r'C://Users/xx/Desktop/macfd.jpg' f2 = r'C://Users/xx/Desktop/macfd2.jpg' data1 = Image.open(f1) data2 = Image.open(f2) data3 = data1.convert("L") data4 = data2.convert("L") raw1 = data3.getdata() raw2 = data4.getdata() #Subtracting pixels diff_pix = np.subtract(raw1,raw2) #Creating a new image with only the different pixels img_final = Image.new("L",(602,756)) img_final.putdata(diff_pix) #Calculating box coordinates c=0 for i in diff_pix: if i > 25: break else: c+=1 x10 = c%602 y10 = c//602 #Drawing the box x1,y1,x2,y2 = x10-30, y10-20, x10+30, y10+20 Drawer = ImageDraw.Draw(data2) Drawer.rectangle((x1, y1, x2, y2), outline="red", width=3) #Saving the image with box f3 = r'C://Users/xx/Desktop/macfd3.bmp' data2.show() data2.save(f3)