Reputation: 189
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
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
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