1

I have a byte array of an image in RGBA (received from a request in django) and I want this in grayscale. How can I do it?

Basically, I have a bytestring (e.g., b'\x00\x00\x00....\x00', single string of bytes of RGBA values of an image) and I want to convert it into a grayscale numpy array like:

[[0,  0,...,0],
 [255,0,...,0],
 [...],
 [...]]

The length of the byte array is 360000 for an image of 300x300 pixels.

Berriel
  • 12,659
  • 4
  • 43
  • 67
fortyTwo102
  • 113
  • 1
  • 9
  • Please, provide an input and expected output. – Berriel Apr 14 '19 at 12:55
  • check these previous questions [Convert RGB to Black & White in OpenCV](https://stackoverflow.com/questions/1585535/convert-rgb-to-black-white-in-opencv) [Difference between hex colour, RGB, & RGBA and when should each they be used?](https://stackoverflow.com/questions/40908277/difference-between-hex-colour-rgb-rgba-and-when-should-each-they-be-used/40908439) – Majo_Jose Apr 14 '19 at 12:57
  • cv2.cvtColor with code RGBA2GRAY or BGRA2GRAY – Micka Apr 14 '19 at 13:16
  • @davyjones97 check my answer, it may help you – Berriel Apr 14 '19 at 13:30
  • Can't comment (no reputation), but your question needs more details. What is your byte array? What image format are you talking about? If they are already RGB values, simply averaging the RGB values (R + G + B) / 3 will give something. There are other algorithms for different needs as well. – Iceberglet Apr 14 '19 at 12:58
  • Updated the question. and it RGBA values, Idk if the extra is A is significant? – fortyTwo102 Apr 14 '19 at 13:15

2 Answers2

0

You can convert your bytestring into an np.array, then convert it to Grayscale or do whatever operation you may need.

import cv2
import numpy as np

# this is to simulate your bytestring
x = b'\x00'*300*300*4

# convert to np.array()
img = np.frombuffer(x, dtype=np.uint8).reshape((300, 300, 4))

print(img.shape)
# (300, 300, 4)

# process the image, e.g.,
img_gray = cv2.cvtColor(img, cv2.COLOR_RGBA2GRAY)

print(img_gray.shape)
# (300, 300)
Berriel
  • 12,659
  • 4
  • 43
  • 67
  • The RGBA pic is turning out perfect but when I convert it to B&W using that code, it's coming out as all violet. Any idea why that would happen? – fortyTwo102 Apr 14 '19 at 14:21
  • You are probably using `matplotlib` to display the image and the default [`cmap`](https://matplotlib.org/examples/color/colormaps_reference.html) is `viridis`, you should add `cmap='gray'` (e.g., `plt.imshow(img_gray, cmap='gray')`). – Berriel Apr 14 '19 at 14:24
  • Berriel uh it's all black now. – fortyTwo102 Apr 14 '19 at 14:30
  • If you are using my code, it should be. My `x` is made of zeros, therefore the image should be all black. Check the `np.unique()` to see if you have values different than 0. – Berriel Apr 14 '19 at 14:34
  • No I'm not using the same exact code as yours. LIke I said the image comes out perfect in RGBA format (before the B&W conversion). And yes it is all zeroes. I wonder if it converted correctly? – fortyTwo102 Apr 14 '19 at 14:38
  • Are you sure the bytestring is not all zeros? Can you share the bytestring via [pastebin](https://pastebin.com/)? – Berriel Apr 14 '19 at 14:39
  • It's way, way too long and slows down my console if I try to print it. But yes Im sure its not all zeroes because the pic before conversion is perfect. – fortyTwo102 Apr 14 '19 at 14:44
  • Maybe the problem is in how you converted to bytestring. Can you check what are the unique bytes in the bytestring? (e.g., `print(np.unique([v for v in x]))`) – Berriel Apr 14 '19 at 15:03
  • Getting this : [ 0 16 32 48 63 64 79 80 95 96 111 112 124 127 128 136 143 144 147 148 156 158 159 160 172 175 176 183 184 186 191 192 195 196 199 200 202 205 206 207 208 210 211 215 216 220 223 224 226 231 232 233 235 236 239 240 241 243 244 245 246 247 248 250 251 252 253 254 255] – fortyTwo102 Apr 14 '19 at 15:13
  • There is something else in your code. The `np.frombuffer` using `np.uint8` should be fine. I would need to see more code to help you better. – Berriel Apr 14 '19 at 15:17
  • @davyjones97 What is the `np.unique()` after the `np.frombuffer()` and before the `cv2.cvtColor()`? – Berriel Apr 14 '19 at 15:18
  • Its the same. I think the problem is with this godforesaken RGBA format. I can't manage to convert any pic in that format to grayscale. Even OpenCV's cv2.imread(filename,0) is returning all zeroes. – fortyTwo102 Apr 14 '19 at 15:23
  • @davyjones97 Can you tell me what is the `np.unique(img[:, :, 3])`? – Berriel Apr 14 '19 at 15:25
  • ah this is interesting. the np.unique(img[:, :, i]) (for i=0,1,2,3) is [0],[0],[0], that array above. – fortyTwo102 Apr 14 '19 at 15:29
  • @davyjones97 which means you have a black image before the `cvtColor`. As I said, I would need to see more code to help you better. And also, this is getting out of the scope of the original question. If you can isolate the issue, I recommend you to open a new question, if you cannot find an answer. – Berriel Apr 14 '19 at 15:34
  • But I don't though. I think it means that the Image that I have in RGBA format (which is a black doodle on white bg) is just rendered by the alpha value, or the A in RGBA, and that's why the conversion methods are failing because all of them convert using that r* something+g * something+b * something formula. – fortyTwo102 Apr 14 '19 at 15:37
  • @davyjones97 I see your confusion. You will need to implement your own conversion if you want to assume that alpha should means white. In general, we do not want the conversion to assume that our background is something (e.g., a solid color). It is easy to implement. If you have some problem doing this, and you cannot find an answer for this, open a new question and post the link here. I can help. – Berriel Apr 14 '19 at 15:40
  • https://stackoverflow.com/questions/55677216/how-to-convert-an-rgba-image-to-grayscale-in-python – fortyTwo102 Apr 14 '19 at 15:55
  • @davyjones97 The question is ill-posed. You should provide your definition of *conversion*, since the default conversion does not fits your needs. Also, try to provide a sample input image. As is, you are likely to be downvoted or receive answers with `cv2.COLOR_RGBA2GRAY`. – Berriel Apr 14 '19 at 15:58
0

With opencv you can convert an image to grayscale with that line gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

I hope it will help you!

Adrien

AdForte
  • 305
  • 2
  • 12