一、本文可以解决的问题:
1.希望将opencv中读取图片所获得的ndarray变为字符串格式,以便对其进行json序列化。
2.在进行json.dumps操作中遇到了“TypeError: Object of type 'ndarray' is not JSON serializable”错误
3.在进行json.dumps操作中遇到了"TypeError: Object of type 'bytes' is not JSON serializable"错误
二、将图片转为字符串(编码)
输入:img为cv2.imread()所得的ndarray。在本例中,shape为(576.704,3)
输出:json序列化后的json字符串
编码过程:img图像矩阵→→一维的ndarray矩阵→→bytes对象→→str对象→→json字符串
retval, buffer = cv2.imencode('.jpg', img)
# buffer是ndarray,shape为(117899,1)
# retval为布尔值,表示转换是否成功
# 注:576*704*3=117899
# ndarray不可以进行json序列化
jpg_as_bytes = base64.b64encode(buffer)
# jpg_as_bytes是bytes对象
# bytes对象同样不能进行json序列化
jpg_as_str = jpg_as_bytes.decode('ascii')
# jpg_as_str是字符串(str),可以进行json序列化
json_object=json.dumps({'img_str':jpg_as_str})
# 这时进行json序列化,就不会报错了
三、将字符串还原为图片(解码)
输入:json序列化后的json字符串
输出:可以cv2.imshow()的ndarray
解码过程:json字符串→→str对象→→未解码的bytes对象→→已解码的bytes对象→→一维的ndarray矩阵→→img图像矩阵
jpg_as_str=json.loads(json_object)['img_str']
# jpg_as_str为字符串
jpg_as_bytes = jpg_as_str.encode('ascii')
# jpg_as_bytes为未解码的bytes对象
jpg_original = base64.b64decode(jpg_as_bytes)
# jpg_original为已解码bytes对象
jpg_as_np = np.frombuffer(jpg_original, dtype=np.uint8)
# jpg_as_np为一个一维的ndarray,shape为(117899,1)
img = cv2.imdecode(jpg_as_np, flags=1)
# img为可以直接cv2.imshow()的ndarray
四、完整代码
import json
import cv2
import base64
import numpy as np
if __name__ == '__main__':
# 上半部分为编码
img_path = r'00001.jpg'
img = cv2.imread(img_path)
retval, buffer = cv2.imencode('.jpg', img)
jpg_as_bytes = base64.b64encode(buffer)
jpg_as_str = jpg_as_bytes.decode('ascii')
json_object=json.dumps({'img_str':jpg_as_str})
##########
# 下半部分为解码
jpg_as_str=json.loads(json_object)['img_str']
jpg_as_bytes = jpg_as_str.encode('ascii')
jpg_original = base64.b64decode(jpg_as_bytes)
jpg_as_np = np.frombuffer(jpg_original, dtype=np.uint8)
img1 = cv2.imdecode(jpg_as_np, flags=1)
cv2.imshow('img_test', img1)
cv2.waitKey(0)