Create a simple Image Classifier
You will learn:
- How to prepare the image to be classified
- How to create an image classifier
- Classify the image using the classifier we’ve built
1. How to prepare the image to be classified?
Classify an image means that we want to assign a class name to an image. For example let’s take the images we have below:
Considering the black color as background, we can say that the image on the left contains a horizontal white line, while the one on the right a vertical white line. We can classify the image on the left as “Horizontal” and the on on the righ as “Vertical”.
Let’s consider these simple images to have a size of 3×3 (3 pixels of width and 3 of height).
Let’s now focus only on one image, we will take the vertical one. The image to the computer will look like this:
[[ 0 255 0]
[ 0 255 0]
[ 0 255 0]]
As we learned on the Opencv tutorial, the black pixel has value 0 while the white pixel has value 255.
The first step we need to do to prepare the image, is to simplify the numbers inside the arrays. So instead of having 0 and 255, we are going to have 0 for the black and 1 for the white.
We can achieve this result by dividing the image by 255 like on Line 9 and 10.
import cv2 import numpy as np # Load images vertical = cv2.imread("images/vertical.png", cv2.IMREAD_GRAYSCALE) horizontal = cv2.imread("images/horizontal.png", cv2.IMREAD_GRAYSCALE) # 1) Image preparation vertical = vertical / 255 horizontal = horizontal / 255
If we print the image now it will look like this:
[[ 0 1 0]
[ 0 1 0]
[ 0 1 0]]
The second thing we need to know is that the computer understands the images in a linear way. So the image above that is a square 3×3, for the computer is a long line on 9 pixels.
So we need to convert the square image and sqeeze it into a row.
vertical_flattened = vertical.flatten() horizontal_flattened = horizontal.flatten()
If we print our flattened image now it will look like this:
[0 1 0 0 1 0 0 1 0]
Our image is now ready to be processed by the image classifier.
2. Create an Image classifier
An image classifier can be a simple python code which is able to classify an image.
If we take as example the same images above the code needs to be able to tell as whether the image is Vertical or Horizontal.
Our two images right now to the computer look like this:
Vertical: [0 1 0 0 1 0 0 1 0]
Horizontal: [0 0 0 1 1 1 0 0 0]
The core of the classifier would be finding an operation which is able to distinguish them.
Let’s try with the sum.
If we sum the numbers inside the vertical: [0 + 1 + 0 + 1 + 0 +1 + 0 + 0 + 1 + 0] the result will be 3.
If we make the sum of the horizontal: [0 + 0 + 0 + 1 + 1 + 1 + 0 + 0 + 0] the result will be 3.
As we can see, both the images give the same result, so the sum is not enough to distinguish them.
Adding a Filter
To make the classifier more advanced, we can add a filter. A filter in this case will be an array of the same size of the image so containing 9 numbers.
Let’s use on our filter the values 1 and – 1.
filter = [1, -1, 1, -1, 1, -1, 1, -1, 1]
We multiply the filter with the horizontal and vertical line and make the sum.
result1 = sum(vertical_flattened * filter) result2 = sum(horizontal_flattened * filter)
Both result1 and result2 are euqals to -1. That means that still even with this filter we’re not able to distinguish them. That doesn’t mean that this method doesn’t work, simply it means that this specific filter is not good in this case.
We can try using a different filter:
filter = [1, -1, 1, 1, -1, 1, 1, -1, 1] result1 = sum(vertical_flattened * filter) result2 = sum(horizontal_flattened * filter)
Now we will see that this filter is able to make a distinction between the vertical and the horizontal image.
result1 will be equal to -3, result2 will be equal to 1.
Classify the image
Considering that using a filter we were able to make a distinction between the vertical and horizontal, as they were giving a different result, now we can put a condition to identify which one is vertical and which is horizontal.
If after applying the filter the result is equals to 1 than we can say that the image is a horizontal line, otherwise it’s a vertical line.
if result1 == 1: print("Horizontal") else: print("Vertical")
This is our image classifier, a really simple one.
3 Testing the classifier
We are going to try this classifier with some new images, but first we need to simplify everything a put it into a function.
The idea would be that in only one line we can call the classifier and it is going to tell us whether the image is a vertical or a horizontal line.
Let’s then take everything we’ve just learn’t and let’s put it into a function.
import cv2 import numpy as np def classify_image(img): # 1) Simplify image by dividing 255 img = img / 255 # 2) Flatten the image img_flattened = img.flatten() # 3) Filter filter = [1, -1, 1, 1, -1, 1, 1, -1, 1] # 4) Multiply filter * flattened image convolution = img_flattened * filter # 5) Sum sum_convolution = sum(convolution) # 6) Condition if sum_convolution == 1: return "Horizontal" else: return "Vertical"
The function “classify_image” is going to take the image and tell us whether it’s a vertical or horizontal line.
To make it more challenging, I’m going to try with two new images:
We load these two images using opencv:
img1 = cv2.imread("images/down_horizontal.png", cv2.IMREAD_GRAYSCALE) img2 = cv2.imread("images/left_vertical.png", cv2.IMREAD_GRAYSCALE) result1 = classify_image(img1) result2 = classify_image(img2) print("Img1", result1) print("Img2", result2)
We will see that for the white horizontal line the result we get is “Horizontal”, while for the vertical line we get “Vertical”.