imdecode返回无Python opencv2

时间:2018-02-09 06:55:19

标签: python image python-2.7 opencv

看看这段代码,

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返回

Opencv docs say

  

如果缓冲区太短或包含无效数据,则返回空矩阵/图像。

使imdecode返回无效的无效数据究竟是什么?还是其他任何错误?

1 个答案:

答案 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是一个有损压缩,它会有一些差异很小。

相关问题