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
如果缓冲区太短或包含无效数据,则返回空矩阵/图像。
使 imdecode 返回 none 的无效数据究竟是什么?还是其他错误?
我之前误解了你的问题,但现在你的评论更清楚了。
当您以 '.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 是一种有损压缩,并且会有一些小的差异。