以JSON格式发送OpenCV图像

问题描述 投票:1回答:1

我正在尝试在json中发送OpenCV图像并在另一端接收它但我遇到了无穷无尽的问题编码和解码图像

我用以下方式用JSON发送它:

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

在另一端,我尝试解码它(我需要它作为枕头图像):

image = Image.open(BytesIO(base64.b64decode(data['image'])))

但我得到了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

我有什么想法我做错了吗?

python json opencv base64 python-imaging-library
1个回答
1
投票

希望这可以让你开始。我认为你尝试过的,通过从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的编码/解码性能......

#!/usr/bin/env python3

import cv2
import numpy as np
import base64
import json
from io import BytesIO
from PIL import Image

def im2json(im):
    _, imdata = cv2.imencode('.JPG',im)
    jstr = json.dumps({"image": base64.b64encode(imdata).decode('ascii')})
    return jstr

def json2im(jstr):
    load = json.loads(jstr)
    imdata = base64.b64decode(load['image'])
    im = Image.open(BytesIO(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 into PIL Image
PILimage = json2im(jstr)
PILimage.show()
© www.soinside.com 2019 - 2024. All rights reserved.