Python - byte image to NumPy array using OpenCV
Solution 1
I created a 2x2 JPEG image to test this. The image has white, red, green and purple pixels. I used cv2.imdecode
and numpy.frombuffer
import cv2
import numpy as np
f = open('image.jpg', 'rb')
image_bytes = f.read() # b'\xff\xd8\xff\xe0\x00\x10...'
decoded = cv2.imdecode(np.frombuffer(image_bytes, np.uint8), -1)
print('OpenCV:\n', decoded)
# your Pillow code
import io
from PIL import Image
image = np.array(Image.open(io.BytesIO(image_bytes)))
print('PIL:\n', image)
This seems to work, although the channel order is BGR and not RGB as in PIL.Image
. There are probably some flags you might use to tune this. Test results:
OpenCV:
[[[255 254 255]
[ 0 0 254]]
[[ 1 255 0]
[254 0 255]]]
PIL:
[[[255 254 255]
[254 0 0]]
[[ 0 255 1]
[255 0 254]]]
Solution 2
I searched all over the internet finally I solved:
NumPy array (cv2 image) - Convert
NumPy to bytes
and
bytes to NumPy
:.
#data = cv2 image array
def encodeImage(data):
#resize inserted image
data= cv2.resize(data, (480,270))
# run a color convert:
data= cv2.cvtColor(data, cv2.COLOR_BGR2RGB)
return bytes(data) #encode Numpay to Bytes string
def decodeImage(data):
#Gives us 1d array
decoded = np.fromstring(data, dtype=np.uint8)
#We have to convert it into (270, 480,3) in order to see as an image
decoded = decoded.reshape((270, 480,3))
return decoded;
# Load an color image
image= cv2.imread('messi5.jpg',1)
img_code = encodeImage(image) #Output: b'\xff\xd8\xff\xe0\x00\x10...';
img = decodeImage(img_code) #Output: normal array
cv2.imshow('image_deirvlon',img);
print(decoded.shape)
You can get full code from here
Related videos on Youtube
Comments
-
Martin Brisiak about 4 years
I have an image in bytes:
print(image_bytes)
b'\xff\xd8\xff\xfe\x00\x10Lavc57.64.101\x00\xff\xdb\x00C\x00\x08\x04\x04\x04\x04\x04\x05\x05\x05\x05\x05\x05\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x07\x07\x07\x08\x08\x08\x07\x07\x07\x06\x06\x07\x07\x08\x08\x08\x08\t\t\t\x08\x08\x08\x08\t\t\n\n\n\x0c\x0c\x0b\x0b\x0e\x0e\x0e\x11\x11\x14\xff\xc4\x01\xa2\x00\x00\x01\x05\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x01\x00\x03\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\ ... some other stuff
I am able to convert it to a NumPy array using
Pillow
:image = numpy.array(Image.open(io.BytesIO(image_bytes)))
But I don't really like using Pillow. Is there a way to use clear OpenCV, or directly NumPy even better, or some other faster library?
-
GPPK about 6 yearsPossible duplicate of Convert a byte arry to OpenCV image in C++
-
Martin Brisiak about 6 yearsThanks for your feed back, although that's c++, not python.
-
GPPK about 6 yearsYes but it's the same code for python just with less brackets... docs.opencv.org/3.0-beta/modules/imgcodecs/doc/…
-
GPPK about 6 years@Norrius I read "I have image in bytes" and "image_bytes" and had to make the assumption it was. If that is not the case then OP needs to clarify in the question why it is different.
-
Norrius about 6 years@GPPK "byte image to numpy array using opencv" seems reasonably clear to me. The only question is what format the image is in. OP?
-
Martin Brisiak about 6 yearsabout the format i have to admit that i'm not completely sure, looks like char representation of hex in
bytes
format to me but otherwise i'm lost :(type(image_bytes) = bytes
-
Mark Setchell about 6 yearsIt's a JPEG image since
ff,d8,ff
is the JPEG signature, so you will need toimdecode()
it. See here... stackoverflow.com/a/49492989/2836621
-
-
alex3465 almost 3 yearsis there any alternative for
cv2.imdecode
in Keras?