看看这段代码,
img = cv2.imread("image2.jpg",0)
img_str = cv2.imencode('.jpg', img)[1] #Encodes and stores in buffer
print(img_str)
#for i,item in enumerate(img_str): } THIS
# img_str[i] = 255-item } IS CONFUSING
nparr = np.frombuffer(img_str, np.uint8)
img2 = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
我的问题是没有这个,
#for i,item in enumerate(img_str): } THIS
# img_str[i] = 255-item } IS CONFUSING
代码运行正常imdecode返回相同!但是当我取消注释时,imdecode返回无
如果缓冲区太短或包含无效数据,则返回空矩阵/图像。
使imdecode返回无效的无效数据究竟是什么?还是其他任何错误?
答案 0 :(得分:2)
我以前误解了你的问题,但现在你的评论更清楚了。
当你encode an image in '.jpg' 不是像往常一样的像素数组,而是一个代表jpeg图像的字节数组。它将等效于使用本机函数直接读取图像的字节。
如果转换每个字节,它将无法正确解码,您的数据将无效。
让我们更仔细地检查数据:
首先,我们加载图像并对数据进行编码
# Exactly what you have to load and encode
import cv2
import numpy as np
img = cv2.imread("image2.jpg",0)
img_str = cv2.imencode('.jpg', img)[1]
现在,让我们展平图像阵列并查看前10个像素(我使用的是驱动器中的随机图像):
img.flatten()[0:10]
这给了我:
[191, 191, 191, 191, 191, 191, 191, 191, 191, 191]
现在,让我们显示编码的前10个字节:
print(img_str.flatten()[0:10])
我得到了:
[255 216 255 224 0 16 74 70 73 70]
正如你所看到的,它与以前完全不同......不仅如此,至少2个第一个字节提供了有关图像的信息,因为它在我之前提到的链接中有解释。
图片开头是以下代码:
0xFF, 0xD8
如果你把它放在十进制数字中它会给你:
255 216
哪个是字节数组的前2个字节...如果为所有字节减去255-byte
,那么初始部分将是0 39
,这将是解码器解析的无效语法它
总之,在编码之后不要更改图像字节,如果需要,在编码之前更改图像字节,并尝试使用OpenCV的函数或从numpy更快地完成它,循环在python中需要很长时间。要反转图像然后对其进行编码,请使用以下代码:
import cv2
import numpy as np
img = cv2.imread("image2.jpg",0)
invImg = cv2.bitwise_not(img) # equivalent to 255-img
img_str = cv2.imencode('.jpg', invImg )[1]
img2 = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
另一件需要考虑的事情,如果你有一个图像并对其进行编码并在jpg中进行解码,那么将不会是同一图像,因为jpg是一个有损压缩,它会有一些差异很小。