Python OpenCV 图像到字节字符串以进行 json 传输
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/40928205/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python OpenCV Image to byte string for json transfer
提问by Hyman O'neill
I use python3with numpy, scipy and opencv.
我将python3与numpy、scipy 和 opencv 一起使用。
I'm trying to convert a image read through OpenCV and connected camera interface into a binary string, to send it within a json object through some network connection.
我正在尝试将通过 OpenCV 和连接的相机接口读取的图像转换为二进制字符串,以通过某些网络连接将其发送到 json 对象中。
I have tried enconding the array as jpg and the decode the UTF-16 string, but I get no usable results. as example, with
我尝试将数组编码为 jpg 并解码 UTF-16 字符串,但我没有得到可用的结果。例如,与
img = get_image()
converted = cv2.imencode('.jpg', img)[1].tostring()
print(converted)
I get a byte-string as result:
我得到一个字节串作为结果:
b'\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x00\x00\x01\x00\x01\x00\x00\xff\xdb\x00C\x00\x02\x01\x01\x01\x01\x01\x02\x01....
b'\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x00\x00\x01\x00\x01\x00\x00\xff\xdb\x00C\x00\x02\x01\x01\x01 \x01\x01\x02\x01....
But this data cannot be used as content of a json object, because it contains invalid characters. Is there a way I can display the real bytes behind this string? I believe that \xff represents byte value FF, so I need as String like FFD8FFE0... and so on, instead of \xff\xd8\xff\xe0. What am I doing wrong?
但是这个数据不能用作json对象的内容,因为它包含无效字符。有没有办法可以显示这个字符串后面的真实字节?我相信\xff 代表字节值FF,所以我需要像FFD8FFE0... 这样的字符串,而不是\xff\xd8\xff\xe0。我究竟做错了什么?
I tried to encode it as UTF-8 and UTF16 after the code above, but I get several errors on that:
我尝试在上面的代码之后将其编码为 UTF-8 和 UTF16,但是我遇到了几个错误:
utf_string = converted.decode('utf-16-le')
UnicodeDecodeError: 'utf-16-le' codec can't decode bytes in position 0-1: illegal UTF-16 surrogate
UnicodeDecodeError: 'utf-16-le' 编解码器无法解码位置 0-1 中的字节:非法的 UTF-16 代理
text = strrrrrr.decode('utf-8')
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte
UnicodeDecodeError: 'utf-8' 编解码器无法解码位置 0 中的字节 0xff:起始字节无效
I can't figure out a way to get this right.
我想不出办法来解决这个问题。
I also tried to convert it into a base64 encoded string, like explained in http://www.programcreek.com/2013/09/convert-image-to-string-in-python/But that doesn't work either. ( This solution is not preferred, as it requires the image being written temporarly to disk, which is not exactly what I need. Preferrably the image should only be hold in memory, never on disk.)
我还尝试将其转换为 base64 编码的字符串,如 http://www.programcreek.com/2013/09/convert-image-to-string-in-python/ 中所述,但这也不起作用。(这个解决方案不是首选,因为它需要将图像临时写入磁盘,这不是我所需要的。最好图像应该只保存在内存中,而不是磁盘上。)
The solution should contain a way to encode the image as json-conform string and also a way to decode it back to numpy-array, so it can be used again with cv2.imshow().
该解决方案应该包含一种将图像编码为 json-conform 字符串的方法,以及一种将其解码回 numpy-array 的方法,因此它可以再次与 cv2.imshow() 一起使用。
Thanks for any help.
谢谢你的帮助。
回答by Martin Evans
You do not need to save the buffer to a file. The following script captures an image from a webcam, encodes it as a JPG image, and then converts that data into a printable base64 encoding which can be used with your JSON:
您不需要将缓冲区保存到文件中。以下脚本从网络摄像头捕获图像,将其编码为 JPG 图像,然后将该数据转换为可用于 JSON 的可打印 base64 编码:
import cv2
import base64
cap = cv2.VideoCapture(0)
retval, image = cap.read()
retval, buffer = cv2.imencode('.jpg', image)
jpg_as_text = base64.b64encode(buffer)
print(jpg_as_text)
cap.release()
Giving you something starting like:
给你一些开始的东西:
/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAIBAQEBAQIBAQECAgICAgQDAgICAgUEBAMEBgUGBgYFBgYGBwkIBgcJBwYGCAsICQoKCg
This could be extended to show how to convert it back to binary and then write the data to a test file to show that the conversion was successful:
这可以扩展以显示如何将其转换回二进制,然后将数据写入测试文件以显示转换成功:
import cv2
import base64
cap = cv2.VideoCapture(0)
retval, image = cap.read()
cap.release()
# Convert captured image to JPG
retval, buffer = cv2.imencode('.jpg', image)
# Convert to base64 encoding and show start of data
jpg_as_text = base64.b64encode(buffer)
print(jpg_as_text[:80])
# Convert back to binary
jpg_original = base64.b64decode(jpg_as_text)
# Write to a file to show conversion worked
with open('test.jpg', 'wb') as f_output:
f_output.write(jpg_original)
回答by lamhoangtung
Some how the above answer doesn't work for me, it needs some update. Here is the new answer to this:
以上答案对我不起作用的一些原因,它需要一些更新。这是对此的新答案:
To encode for JSON:
为 JSON 编码:
import base64
import json
import cv2
img = cv2.imread('./0.jpg')
string = base64.b64encode(cv2.imencode('.jpg', img)[1]).decode()
dict = {
'img': string
}
with open('./0.json', 'w') as outfile:
json.dump(dict, outfile, ensure_ascii=False, indent=4)
To decode back to np.array
:
解码回np.array
:
import base64
import json
import cv2
import numpy as np
response = json.loads(open('./0.json', 'r').read())
string = response['img']
jpg_original = base64.b64decode(string)
jpg_as_np = np.frombuffer(jpg_original, dtype=np.uint8)
img = cv2.imdecode(jpg_as_np, flags=1)
cv2.imwrite('./0.jpg', img)
Hope this could help someone :P
希望这可以帮助某人:P