在 python 中,我想将使用 OpenCV 处理过的图像转换为某种图像格式(在本例中为 TIFF,但可能是:BMP、JPEG、PNG、.. ...)。
为此目的,将 OpenCV 图像编码到内存缓冲区就足够了。问题是,当我使用 cv2.imencode()
执行此操作时,返回的对象仍然看起来像一个 numpy
数组:
import cv2
img_cv2_aka_nparr = cv2.imread('test.jpg')
my_format = '.tiff'
retval, im_buffer = cv2.imencode(my_format, img_cv2_aka_nparr)
print type(im_buffer)
im_buffer
只是另一个 numpy
数组——它根本不是 TIFF 编码的字节流!据我所知,python 中的 OpenCV 图像总是表现得像 numpy
数组,甚至通过 type()
看起来像 numpy
数组。
事实上,如果你想创建一个虚拟的“OpenCV 图像”,你必须使用 numpy
- 参见例如https://stackoverflow.com/a/22921648/1021819
这是为什么,我该如何解决?也就是说,我如何获得实际的 TIFF 编码字节流而不是另一个 numpy
数组?
现在我喜欢 numpy
,但在这种情况下,我需要非 python 服务可以读取图像,因此它需要采用通用(最好是无损)格式(见列表以上)。
(我已经了解了在 JSON 中嵌入 numpy
的方法并决定反对它。)
我可以使用 PIL
/pillow、scipy
和一些,但我试图尽量减少依赖性(即到目前为止只有 cv2
, numpy
和内在函数)。
谢谢!
最佳答案
正在关注 https://stackoverflow.com/a/50630390/1021819并根据 Dan Masek 的评论构建(但不是很多),所需的额外步骤只是使用 im_buffer.tobytes()
,它返回可以通过流发送的字节串。
Python OpenCV 图像似乎确实表示为纯 numpy
数组。正如 Dan Masek 所指出的,可以使用 cv2.imencode()
将数组转换为 TIFF、PNG、BMP、JPG 等。
关于格式和压缩的选择显然存在一些争论。在上面的例子中,人们更喜欢无损压缩,暗示 TIFF、BMP 或 PNG(仍有争议)。 Python 绑定(bind)到 OpenCV 没有用于 TIFF 压缩的可调参数(不像(?)C++ 绑定(bind)?),所以要发现那里正在做什么并不容易。压缩级别显然可以使用其他库更好,但我的目标是最大限度地减少依赖性(见上文)。
BMP 编码图像不小于 TIFF 图像。 PNG 压缩在 python OpenCV 中是可调的,并且设置
cv2.imencode('.png', nparr, [int(cv2.IMWRITE_PNG_COMPRESSION),1])
给出了迄今为止最好的大小-速度权衡。谢谢。
关于python - 如何从 OpenCV 图像而不是 numpy 数组中获取 TIFF 字节流?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52001891/