序列化后OpenCV ndarray映像保存失败

时间:2019-05-05 18:02:56

标签: opencv image-processing serialization numpy-ndarray

我正在尝试使用opencv调整图像大小,然后将图像保存到文件中。当我尝试不使用序列化encoded_image编写ndarray时,输出图像保存得很好。但是,当我尝试序列化相同的ndarray并将ndarray im_ndarray写入file时,输出映像已损坏。

import numpy as np
import cv2
import json


class NDArrayEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, np.ndarray):
            return obj.tolist()
        return json.JSONEncoder.default(self, obj)



def image_resize(bytes):  
    nparr = np.fromstring(bytes, np.uint8)
    # json_str = {'x1': [x.tolist() for x in nparr]}
    # return json.dumps(json_str)

    img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)

    color = [200, 200, 200]
    top, bottom, left, right = [100] * 4

    r = 150.0 / img.shape[1]
    dim = (150, int(img.shape[0] * r))
    resized = cv2.resize(img, dim, interpolation=cv2.INTER_AREA)

    img_with_border = cv2.copyMakeBorder(resized, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color)
    success, encoded_image = cv2.imencode('.jpg', img_with_border)


    json_str = json.dumps({'test': encoded_image}, cls=NDArrayEncoder, indent=4)
    return json_str, encoded_image



im1 = open('/_salwar.jpg', 'rb').read()
im2, encoded_image = image_resize(im1)
jl = json.loads(im2)


from numpy import array
im_ndarray = array(jl['test'])

print (np.array_equal(im_ndarray,encoded_image))
# Returns - True
print (type(im_ndarray), type(encoded_image))
# Returns - <class 'numpy.ndarray'> <class 'numpy.ndarray'>

# Saves Corrupted Image
with open('picture_out_imnd.jpg', 'wb') as f:
    f.write(im_ndarray)
    #f.write(im_ndarray.tobytes()) # Fails as well

# Saves without any problem. 
with open('picture_out_encoded.jpg', 'wb') as f:
        f.write(encoded_image)

im_ndarrayencoded_image均为ndarray类型,并且相等。为什么一个保存得很好,而另一个保存失败?

谢谢

1 个答案:

答案 0 :(得分:0)

以下作品:

import numpy as np
import cv2
import json


class NDArrayEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, np.ndarray):
            return obj.tolist()
        return json.JSONEncoder.default(self, obj)



def image_resize(bytes):
    """Responds to any HTTP request.
    Args:
        request (flask.Request): HTTP request object.
    Returns:
        The response text or any set of values that can be turned into a
        Response object using
        `make_response <http://flask.pocoo.org/docs/1.0/api/#flask.Flask.make_response>`.
    """
    # request_json = request.get_json()

    nparr = np.fromstring(bytes, np.uint8)
    # json_str = {'x1': [x.tolist() for x in nparr]}
    # return json.dumps(json_str)

    img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)

    color = [200, 200, 200]
    top, bottom, left, right = [100] * 4

    r = 150.0 / img.shape[1]
    dim = (150, int(img.shape[0] * r))
    resized = cv2.resize(img, dim, interpolation=cv2.INTER_AREA)

    #print ('Resized:' , type(resized), resized.shape)

    img_with_border = cv2.copyMakeBorder(resized, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color)
    #print('IM_with_border:', type(img_with_border), img_with_border.shape)

    success, encoded_image = cv2.imencode('.jpg', img_with_border)
    json_str = json.dumps({'test': encoded_image}, cls=NDArrayEncoder, indent=4)

    #print('Encoded_Image:', type(encoded_image), encoded_image.shape)


    return json_str, encoded_image



im1 = open('/_salwar.jpg', 'rb').read()
im2, encoded_image = image_resize(im1)
jl = json.loads(im2)

im_ndarray = np.asarray(jl['test'], dtype='uint8')

with open('picture_out1.jpg', 'wb') as f:
    f.write(im_ndarray.tobytes())