Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert array of single integer pixels to RGB triplets in Python

I'm playing around with a camera for a microscope using Micro-Manager 1.4. Using the Python interface, I've managed to access the camera, change exposure time etc, and I can capture individual images.

However, each image is returned as NumPy arrays where each pixel is represented as a single integer, e.g. "7765869". As far as I can find online, this is known as a "BufferedImage" in Java, and it means that the RGB values are encoded as:

BufferedImage = R * 2^16 + G * 2^8 + B

My question is: How can I, using e.g. Numpy or OpenCV, convert this kind of array into a more handy array where each pixel is a RGB triplet of uint8 values? Needless to say, the conversion should be as efficient as possible.

like image 590
Happy Avatar asked Oct 17 '13 16:10

Happy


1 Answers

The easiest is to let numpy do the conversion for you. Your numpy array will probably be of type np.uint32. If you view it as an array of np.uint8, you will have an RGB0 format image, i.e. the values of R, G, and B for each pixel, plus an empty np.uint8 following. It's easy to reshape and discard that zero value:

>>> img = np.array([7765869, 16777215], dtype=np.uint32)
>>> img.view(np.uint8)
array([109, 127, 118,   0, 255, 255, 255,   0], dtype=uint8)
>>> img.view(np.uint8).reshape(img.shape+(4,))[..., :3]
array([[109, 127, 118],
       [255, 255, 255]], dtype=uint8)

Best thing is there is no calculation or copying of data, just a reinterpretation of the contents of your original image: I don't think you can get much more efficient than that!

I recall that for some operations OpenCV requires a contiguous array, so you may have to add a .copy() to the end of that expression to really get rid of the column of zeros, not simply ignore it, although this would of course trigger the copy of data that the code above had avoided.

like image 128
Jaime Avatar answered Sep 23 '22 13:09

Jaime