Sunday, July 21, 2013

Vectorize Image with Python scikit-image

Short story: a friend of mine wanted to display an interactive dental chart on the web but most of the images he found was some hand-drawn image which wasn't fit into his site look-and-feel. So decided to vectorize one image, it shouldn't be a hard task ...
After some research I end up here:  http://scikit-image.org/docs/dev/auto_examples/ and I succeeded to get vectorized outlines in an hour. Lets go through it step-by-step:

0. This is an image with teeth I wanted to get in vectorized format, each tooth separately:


I have anaconda on my windows machine but if you have python with the general science tools (numpy, matplotlib, skimage, skipy) this code should work for you.

1. Loading the image from the file. With imread we get a 3D numpy array. In the 3rd dimension are the RGB values:


2. In the samples the algorithms where used on grayscale images, so firstr I had to convert the image to grayscale. This means I get a 2D array from the 3D one.

If it's needed the image can be croped simply with array slice (e.g.: cropedimg = gimg[330:480, 50:480]) and with matplotlib the image can be displayed any time just calling imshow(gimg).

3. Detecting the contours with skimage.

As result we get an array containing the vector representation of all found contour lines separately. Let's display the results:

4. For me the contour line was too detailed and rough so I wanted to have a more schematic result. With the tolerance parameter it's possible to set how detailed is the approximation. Finally we print an original and an approximated contour.



6 comments:

Unknown said...

s/skipy/scipy/g

Unknown said...

Thanks for the post. You've saved me a lot of time and now I can focus on the actual problem I was working on instead of how to get it into python :)

Unknown said...
This comment has been removed by the author.
Find the next Kdrama to watch here said...

You seem to have forgotten a very important line. The bit that actually prints the output. We were output less for a long time. For all the other unfortunate souls - add plt.show() at the end. Thank you.

Ubu Roi said...

Hello, thanks for the post! I am doing a similar task and I would like to know how did you detected the contours and separated them into an array of vectors, other comments suggets there is a code somewhere in the post but I cant really find it, did you changed the tolerance parameter of what function?

Thanks in advance

Ubu Roi said...

Found it, nevermind!