以JSON格式发送OpenCV图像

2024-04-24 08:16:12 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图以json格式发送OpenCV图像,并在另一端接收它,但在编码和解码图像时遇到了无尽的问题

我用JSON的方式发送:

dumps({"image": b64encode(image[y1:y2, x1:x2]).decode('utf-8')})

另一方面,我试着解码(我需要它作为枕头图像):

^{pr2}$

但我得到了Exception cannot identify image file <_io.BytesIO object at 0x7fbd34c98a98>

也尝试过:

nparr = np.fromstring(b64decode(data['image']), np.uint8)
image = cv2.imdecode(nparr, cv2.COLOR_BGR2RGB)
pil_image = Image.fromarray(image)

但是我得到'NoneType' object has no attribute '__array_interface__'来自Image.fromarray

你知道我做错了什么吗?在


Tags: 图像imagejson编码object格式np方式
1条回答
网友
1楼 · 发布于 2024-04-24 08:16:12

希望这能让你开始。我认为您尝试的从Numpy数组发送未修饰的字节可能行不通,因为接收器不知道图像中通道的宽度、高度和数量,所以我使用pickle来存储这些信息。在

#!/usr/bin/env python3

import cv2
import numpy as np
import base64
import json
import pickle
from PIL import Image

def im2json(im):
    """Convert a Numpy array to JSON string"""
    imdata = pickle.dumps(im)
    jstr = json.dumps({"image": base64.b64encode(imdata).decode('ascii')})
    return jstr

def json2im(jstr):
    """Convert a JSON string back to a Numpy array"""
    load = json.loads(jstr)
    imdata = base64.b64decode(load['image'])
    im = pickle.loads(imdata)
    return im

# Create solid red image 
red = np.full((480, 640, 3), [0, 0, 255], dtype=np.uint8)  

# Make image into JSON string
jstr = im2json(red)

# Extract image from JSON string, and convert from OpenCV to PIL reversing BGR to RGB on the way
OpenCVim = json2im(jstr)
PILimage = Image.fromarray(OpenCVim[...,::-1])
PILimage.show()

由于您在关于为什么您希望这样做的评论中没有回答我的问题,所以这可能不是最佳选择-通过网络(大概)发送未压缩的base64编码图像不是很有效。例如,您可以考虑使用JPEG或PNG编码的数据来节省网络带宽。在

您也可以使用cPickle代替。在


注意,有些人不赞成pickle,而且上面的方法使用了大量的网络带宽。另一种方法可能是在发送之前对图像进行JPEG压缩,然后在接收端直接解压缩成PIL图像。注意这是有损的。在

或者将代码中的.JPG扩展改为.PNG,这是一个损失较小但可能较慢的扩展,对于具有浮点数据或16位数据的图像不起作用(尽管后者可以容纳后者)。在

你也可以看看TIFF,但它取决于你的数据的性质,网络带宽,你需要的灵活性,你的CPU的编码/解码性能。。。在

^{pr2}$

相关问题 更多 >