Image classification in python

I have a set of images that are considered as good quality image and other set that are considered as bad quality image. I have to train a classification model so that any new image can be said good/bad. SVM seems to be the best approach to do it. I know how to do it in MATLAB.

But,can anyone suggest how to do it in python? What are the libraries? For SVM scikit is there, what about feature extraction of image and PCA?

4 Answers

As this question highly overlaps with a similar question I have already answered, I would include that answer here (linked in the comments underneath the question):

In images, some frequently used techniques for feature extraction are binarizing and blurring

Binarizing: converts the image array into 1s and 0s. This is done while converting the image to a 2D image. Even gray-scaling can also be used. It gives you a numerical matrix of the image. Grayscale takes much lesser space when stored on Disc.

This is how you do it in Python:

from PIL import Image

%matplotlib inline

#Import an image
image = Image.open("xyz.jpg")

image


Example Image:

Now, convert into gray-scale:

im = image.convert('L')

im


will return you this image:

And the matrix can be seen by running this:

array(im)


The array would look something like this:

array([[213, 213, 213, ..., 176, 176, 176],
[213, 213, 213, ..., 176, 176, 176],
[213, 213, 213, ..., 175, 175, 175],
...,
[173, 173, 173, ..., 204, 204, 204],
[173, 173, 173, ..., 205, 205, 204],
[173, 173, 173, ..., 205, 205, 205]], dtype=uint8)


Now, use a histogram plot and/or a contour plot to have a look at the image features:

from pylab import *

# create a new figure
figure()
gray()
# show contours with origin upper left corner
contour(im, origin='image')
axis('equal')
axis('off')

figure()

hist(im_array.flatten(), 128)

show()


This would return you a plot, which looks something like this:

Blurring: Blurring algorithm takes weighted average of neighbouring pixels to incorporate surroundings color into every pixel. It enhances the contours better and helps in understanding the features and their importance better.

And this is how you do it in Python:

from PIL import *

figure()
p = image.convert("L").filter(ImageFilter.GaussianBlur(radius = 2))
p.show()


And the blurred image is:

So, these are some ways in which you can do feature engineering. And for advanced methods, you have to understand the basics of Computer Vision and neural networks, and also the different types of filters and their significance and the math behind them.

The entire analytics is done with the PIL package. I wouldn't claim that it's a one-stop shop for Image analytics, but for a starter to novice level, it is pretty much it.

• I have quite some idea about image processing, done some projects using MATLAB. Its the first time i am using Python for image. So didn't had idea about the libraries. – maggs Feb 5 '16 at 9:14

There are certain feature extraction algorithms in opencv library. Some of them are SURF or SIFT, HOG in opencv. Local Binary Pattern(LBP) in sklearn library in Python. One more technique is to create Bag of visual words. There also exists BOW class in opencv. To understand the concept of bag of visual words you can look for some of the research papers.

SURF in opencv Python:

surf = cv2.SURF(400)
kp, des = surf.detectAndCompute(img,None)


You can see the opencv documentation for more details. Similarly you can know about all other feature extraction methods. Here is one more blog regarding HOG feature extraction.

Once you extract all your features from your training data-set images, you can use svm library of sklearn to train your classifier. There are plenty of resources out there that will help you start with ML in python.

Can you tell us which criteria do you use for considering a picture "good quality image" or "bad quality image"?

An idea of how to handle it could be for example choosing unfocused pictures as bad ones. One way to discriminate it could be compute the Sobel operator over the image in order to obtain the edges. A blurry image will contain less edges than a good one, but also it will depend on the type of image (it's not the same a landscape with just the sea and the sand than a picture of a table full of stuff), so you will need to normalize your image, but no idea yet how to handle this normalization.

My suggestion on libraries for python is OpenCv. It's documentation for Python language was awful when I tried to use some years ago, but surely it has improved a lot since then.

If you have a fairly large set of 'good' and 'bad' images, You can use a convolutional neural network (CNN) with a package like pytorch or tensorflow (pytorch is more pythonic). As I understand it, nowadays for image tasks, CNNs are what all the cool kids use.

There is a package to preload models and you can take something small like vgg16 as shown here and then replace the last layer with a fully connected output of size 2 as shown toward the end of the tutorial, or download the notebook.

Its nice that You don't have care what 'good' and 'bad' are in this case (so it can be very true to your question), as long as you have like 10K images...