HackNode
HackNode

Reputation: 189

CV2 not displaying colors when converting to uint8

I have a python list that contains the RGBA data of a PNG image represented as int32, which was sent over from a Java socket server.

A sample output of this data as a numpy array without any conversions:

[[-12763847 -12763847 -12763847 ...  -5590160 -12039396 -12434915]
 [-12763847 -12763847 -12763847 ...  -6643102 -12828909 -12830184]
 [-12763847 -12763847 -12763847 ...  -8419763 -13487094 -12435167]]

CV2, of course, accepts uint8 as the data type (displaying as int32 shows a black screen), so I convert my list to a numpy array with dtype = np.uint8 with the following:

image_data = np.array(data_list, dtype = np.uint8)

A sample output of this:

[[ 57  57  57 ... 112  28  29]
 [ 57  57  57 ...  98  19  24]
 [ 57  57  57 ...  77  10  33]]

However, when I display the image using

cv2.imshow("Image", image_data)

I get a window showing the image, but in grayscale; it lacks colors.

How do I prevent the colors from being ignored?

Upvotes: 3

Views: 1639

Answers (2)

Mark Setchell
Mark Setchell

Reputation: 208003

Hopefully this will help you see how to extract the Red, Green and Blue channels from the 32-bit values. I started off with the first row of your array.

im=np.array([-12763847,-12763847,-12763847,-5590160,-12039396,-12434915],dtype=np.int32)

R = ((im & 0xff).astype(np.uint8)
# array([ 57,  57,  57, 112,  28,  29], dtype=uint8)

G = ((im>>8) & 0xff).astype(np.uint8)
# array([ 61,  61,  61, 179,  75,  66], dtype=uint8)

B = ((im>>16) & 0xff).astype(np.uint8)
# array([ 61,  61,  61, 170,  72,  66], dtype=uint8)

If those values look correct, you should be able to merge them into a colour image with:

img = cv2.merge((B,G,R))

bearing in mind that OpenCV uses BGR channel ordering rather than the more conventional RGB.


The ordering of the bytes in your 32-bit number may be different from what I am guessing above. The easiest way to test is to put a red card in front of your camera, and see what comes through, then a green card, then a blue one. The four channels (R,G,B,A) should be given by the following but which is which may be a matter for experiment:

(im    ) & 0xff
(im>>8 ) & 0xff
(im>>16) & 0xff
(im>>24) & 0xff

Upvotes: 2

Dinari
Dinari

Reputation: 2557

For outputting color image with cv2 you need to image to be of shape (x,y,3), the last axis being the colors.

As your data is int32 representation of RGBA, I assume each number actually hold 4 different numbers, where the first 2 bytes are the uint8 of red, the second green, third blue and last alpha: (0000 0001, 0000 0010, 0000 0100,0000 1000) in this example r is 1, g is 2, b is 4 and alpha is 8.
You will need to extract this 8 bytes into the separate colors.

In addition, keep in mind that cv2 color space is BGR and not RGB, so you will have to switch channels after converting.

Upvotes: 2

Related Questions