imdecode 返回 None Python opencv2

voi*_*oid 8 python opencv image python-2.7

看看这段代码,

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)
Run Code Online (Sandbox Code Playgroud)

我的问题是没有这个,

#for i,item in enumerate(img_str):    }  THIS
 #   img_str[i] = 255-item            }  IS CONFUSING
Run Code Online (Sandbox Code Playgroud)

代码运行良好 imdecode 返回相同!但是当我取消注释它 imdecode 返回None

Opencv 文档说

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

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

api*_*i55 7

我之前误解了你的问题,但现在你的评论更清楚了。

当您以 '.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]
Run Code Online (Sandbox Code Playgroud)

现在,让我们展平图像阵列并查看前 10 个像素(我使用驱动器中的随机图像):

img.flatten()[0:10]
Run Code Online (Sandbox Code Playgroud)

这给了我:

[191, 191, 191, 191, 191, 191, 191, 191, 191, 191]
Run Code Online (Sandbox Code Playgroud)

现在,让我们展示编码后的前 10 个字节:

print(img_str.flatten()[0:10])
Run Code Online (Sandbox Code Playgroud)

我得到:

[255 216 255 224   0  16  74  70  73  70]
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,它与以前完全不同......不仅如此,至少前 2 个字节提供了有关图像的信息,正如我之前在链接中所解释的那样。

图像的开头是以下代码:

0xFF, 0xD8
Run Code Online (Sandbox Code Playgroud)

如果你把它放在十进制数中,它会给你:

255 216
Run Code Online (Sandbox Code Playgroud)

这是字节数组的前 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)
Run Code Online (Sandbox Code Playgroud)

要考虑的另一件事是,如果您有一个图像并对其进行编码并以 jpg 进行解码,则它不会是相同的图像,因为 jpg 是一种有损压缩,并且会有一些小的差异。