Thursday, April 22, 2010

Python Image Library - Part 2: OpenCV

Now that I have my PIL installation working it's time to get some complicated image processing done and OpenCV is, pretty much, the best choice out there at the moment - especially since it's development became active again and numerous bugs have been fixed, new functions added, etc.

This FAQ at the very bottom of the page points to an adaptors.py module that has the functions to convert back and forth between Ipl & PIL and Ipl & numpy. The module does indeed come with the latest distribution of OpenCV. Unfortunately, it has not been updated since about version 1.0...

Fear not, with few minor tweaks to accommodate new IplImage structure you can get it to load your PIL Image into the IplImage. (Later I found the code that essentially does the same here).

So what now you ask? Yes it worked. Kind of. The image of red strawberry comes out as a bright blue strawberry once converted to Ipl. It appears that the kind soul at OpenCV that provided the conversion code entirely missed the issue of Ipl images being BGR while PIL Image is RGB. Mind you, it works in the opposite direction as PIL has two mode input parameters: one for input image mode and one for the output image mode, so it just knows to shift the color bits.

Back to searching. There seems to be a good number of solutions consisting of complicated pixel-by-pixel shifting, flipping, etc. Many of them rely on old OpenCV CvMat and IplImage structures where you actually had access to the data directly in a linear array fashion. I must say, while trying to get said solutions to work I got some very entertaining variations on the display of that strawberry.

And then, I found it. And I mean The IT solution. I was actually searching for some different approach keyword and the result was a preview of a PIL Handbook. So here is the solution:

pi=Image.open("image.jpg")
r,g,b=pi.split()
pi2=Image.merge("RGB",(b,g,r))

That's all. Now you have your BGR-ready image that you pass along to the IplImage, which comes out with the strawberry being a correctly-red colour.

Here's the entire conversion code from the PIL cookbook with this fix added:

import Image, cv
pi = Image.open('building.jpg') # PIL image
cv_im = cv.CreateImageHeader(pi.size, cv.IPL_DEPTH_8U, 3)
r,g,b=pi.split()
pi2=Image.merge("RGB",(b,g,r))
cv.SetData(cv_im, pi2.tostring())


Enjoy :)

No comments:

Post a Comment