How to convert numpy array to io.BufferedReader correctly?
Question:
I am trying to send an image received from the opencv cam.read() method to a server, which classifies it. Sadly I don’t know which datatype the server exactly needs. I have noticed that saving the image and opening it with io.open() returns a classification. I tried to convert the image received from cam.read() to anything which also returns a classification. And something strange is happening:
ret, frame = vid.read()
cv2.imwrite("animage.jpg", frame)
animage = Image.fromarray(frame)
imagefile = BytesIO()
animage.save(imagefile, format='png')
imagedata = imagefile.getvalue()
rsp = requests.post(url, auth, files={'img':imagedata}) #returns classification
rsp2 = requests.post(url, auth, files={'img':open("animage.jpg",'rb')}) #returns different class.
The classifications returned are different from each other. Not very much but a little bit and that shouldn’t be the case. Does anyone have any ideas on what I am doing wrong that’s causing this behaviour and which classification is the correct one?
Answers:
I just found out that there is a compress_level
option in the Image.save()
method. This of course also explains the varying results in classification. Setting the compress_level
to zero saved a lot of runtime for me.
If you have an image (np.array), you can convert it into a BufferedReader object as follows.
img = cv2.imread('image.png')
def get_image_handler(img_arr):
ret, img_encode = cv2.imencode('.jpg', img_arr)
str_encode = img_encode.tostring()
img_byteio = BytesIO(str_encode)
img_byteio.name = 'img.jpg'
reader = BufferedReader(img_byteio)
return reader
And use it like
rsp = requests.post(url, auth, files={'img':get_image_handler(img)})
I am trying to send an image received from the opencv cam.read() method to a server, which classifies it. Sadly I don’t know which datatype the server exactly needs. I have noticed that saving the image and opening it with io.open() returns a classification. I tried to convert the image received from cam.read() to anything which also returns a classification. And something strange is happening:
ret, frame = vid.read()
cv2.imwrite("animage.jpg", frame)
animage = Image.fromarray(frame)
imagefile = BytesIO()
animage.save(imagefile, format='png')
imagedata = imagefile.getvalue()
rsp = requests.post(url, auth, files={'img':imagedata}) #returns classification
rsp2 = requests.post(url, auth, files={'img':open("animage.jpg",'rb')}) #returns different class.
The classifications returned are different from each other. Not very much but a little bit and that shouldn’t be the case. Does anyone have any ideas on what I am doing wrong that’s causing this behaviour and which classification is the correct one?
I just found out that there is a compress_level
option in the Image.save()
method. This of course also explains the varying results in classification. Setting the compress_level
to zero saved a lot of runtime for me.
If you have an image (np.array), you can convert it into a BufferedReader object as follows.
img = cv2.imread('image.png')
def get_image_handler(img_arr):
ret, img_encode = cv2.imencode('.jpg', img_arr)
str_encode = img_encode.tostring()
img_byteio = BytesIO(str_encode)
img_byteio.name = 'img.jpg'
reader = BufferedReader(img_byteio)
return reader
And use it like
rsp = requests.post(url, auth, files={'img':get_image_handler(img)})