Monday, 18 November 2013

Image processing in python with scikit-learn and pymorph

I have been using MATLAB quite a bit for some time. But being a proprietary language it has some drawbacks. One has to fork out lot of money to buy it and renew it yearly license. On top of that one hast to busy many toolboxes.Check this blog for finding various advantages of switching over from MATLAB to Python. You will find very helpful insights into key difference  between MATLAB and python numpy here.

Recently for couples of weeks now, I have to experimenting with python which is an open source software for some of my tasks that I do mainly related to classification, segmentation of remote sensing image etc during my weekend free time. So after sacrificing two of my weekends time for scouring python and different libraries which otherwise I would spend for my leisure activity, I am now pretty comfortable with python language as well for image processing tasks. Sweet :-) .

In this post I will show some morphological image analysis with python. I can see this will be series of post related to python. I plan to cover classification, clustering, edge detection in my subsequent posts.

For installing python, I have used pythonXY which comes with many libraries that might be needed for the scientific data analysis such as scipy, numpy, matplotlib and many others.PythoXY also comes with an Interactive development environment (IDE) for python which is called Spyder. With Spyder, you don’t have run python from command prompt. Other benefit includes integrated help, variable explorer, history console etc. In addition its all FREE.

Here is the interface how it looks.
Spyder iterface

I will be using library called “scikit-image” which comes in a bundle with pythonXY and in addition I would be using a library called “PyMorph” for morphological image analysis. Scikit-image also has a morphologicl module but there you would only find basic morphological operators like opening, closing, erosion and dialation. In PyMorph there are many advance morphological operator such opening by reconstruction and closing by reconstruction, Auto sequential filter(ASF), ASF by reconstruction etc. So after installing pythonXY, download the PYMoprh library and install it.

So, in this post I would show you how to use scikit-image for creating some basic shapes, calculating i area for each shapes or blobs and writing areas in the figure, finding bounding box of each blobs and plotting it in the figures. After finding areas of each figures, I will show how to remove certain blob  which has less area t than specified area.

% -*- coding: utf-8 -*-
Created on Mon Nov 18 15:42:21 2013
@author: shailesh
"""
%%%
% call necessary libraries
import math
import matplotlib.pyplot as plt
import numpy as np
from skimage.draw import ellipse
from skimage.draw import polygon
from skimage.draw import circle
from skimage.morphology import label
from skimage.measure import regionprops
from skimage.transform import rotate
import matplotlib.patches as mpatches
import pymorph as MM

%%%
% draw some arbitary shapes
image = np.zeros((1000, 1000),dtype=uint8)
% create an ellipse with centre (350,350) with minor axis = 100 and major = 220
rr, cc = ellipse(300, 350, 100, 220)
image[rr,cc] = 1

% create a polygon
x = np.array([1, 7, 4, 1])
x = np.array([1, 70, 40, 1])
y = np.array([1, 20, 80, 1])
rr, cc = polygon(y, x)
image[rr, cc] = 1

% create a polygon
rr, cc = circle(200, 200, 50)
image[rr, cc] = 1
fig, ax = plt.subplots(ncols=1, nrows=1, figsize=(6, 6))
ax.imshow(image)

%lable connected regions
label_img = label(image)
%find properties of connected regions
regions = regionprops(label_img,['Centroid', 'BoundingBox', 'Area'])

%loop through connected regions and find
% Centroid', 'BoundingBox', 'Area' for each blobs
for props in regions:
y0, x0 = props['Centroid']
minr, minc, maxr, maxc = props['BoundingBox']
area =props['Area']
rect = mpatches.Rectangle((minc, minr), maxc - minc, maxr - minr,
fill=False, edgecolor='red', linewidth=2)
ax.add_patch(rect)
ax.text(x0, y0, str(area), fontsize=10, color="blue")
%show figure
plt.gray()
plt.axis((0, 1000, 1000, 0))
plt.show()

%%% remove small blobs
image = image.astype(np.uint8)
%remove blobs with area less than 10000 '
% MM.areaopen is coming from PyMorph
b=MM.areaopen(image,10000)
fig, ax = plt.subplots(ncols=1, nrows=1, figsize=(6, 6))
ax.imshow(b)
ax.title('blobs with areas greater than 10000 ')
plt.gray()
plt.axis((0, 1000, 1000, 0))
plt.show()
% to close the pixels
plt.close("all")

Here are the figures produced by above code.

Initial figure after some blobs were made. The area of each blobs and bounding box were plotted as well
figure_1

Figure where blobs with area less than 10000 pixels are remove with pymorph.
figure_2

So this is a hypothetical simple illustration. But the real application of this kind of analysis could be many in remote sensing field. For example, after detection buildings you can easily remove buildings with size less than minimum mapping unit (say 100 m2). Similarly it can be used for removing some artifacts which are small in area that you might not be interested in. And the list can go on.

In next few blogs, i will be writing more about other morphological image processing operators as well as classfiers such Support Vector Machine (SVM), Random Forest (RF) etc.