【问题标题】:How do I get a TIFF bytestream from an OpenCV image, rather than a numpy array?如何从 OpenCV 图像而不是 numpy 数组中获取 TIFF 字节流?
【发布时间】:2019-01-30 18:47:32
【问题描述】:

在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 服务可以读取图像,因此它需要采用通用(最好是无损)格式(参见上面的列表)。

(我已经在 J​​SON 中嵌入numpy 的房子转了一圈,并决定反对它。)

我可以使用 PIL/pillow、scipy 和一些,但我正在尝试最小化依赖关系(即到目前为止只有 cv2numpy 和内在函数)。

谢谢!

【问题讨论】:

  • "它根本不是 TIFF 编码的字节流" -- 当然是,包含在单行 numpy 数组中。
  • @DanMašek 有趣...所以如果我通过 RESTful 界面返回它,我可以将它作为 TIFF 客户端打开?
  • 是的。您需要先致电tostring()tobytes()
  • @DanMašek 谢谢 - 是的 - 请你发布一个我可以接受的答案吗?我确实觉得这落在了迄今为止 OpenCV/numpy/SO 文献的裂缝中。 (另外:为什么..?!)
  • @DanMašek 我已经发布了一个答案,但你值得称赞,所以我会暂时打开它,看看你是否想发布一个答案。感谢大家的帮助! :)

标签: python numpy opencv image-processing


【解决方案1】:

按照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(仍有争议)。与 OpenCV 的 python 绑定没有用于 TIFF 压缩的可调参数(不像(?)C++ 绑定?),因此发现那里正在做什么 并不是很容易。使用其他库,压缩级别显然会更好,但我的目标是尽量减少依赖关系(见上文)。

BMP 编码的图像不小于 TIFF 图像。 PNG压缩在python OpenCV中是可调的,并且设置

cv2.imencode('.png', nparr, [int(cv2.IMWRITE_PNG_COMPRESSION),1])

到目前为止,已经给出了最佳的尺寸-速度折衷方案。谢谢。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-19
    • 2021-12-27
    • 2011-08-25
    • 1970-01-01
    • 2020-06-24
    • 2011-11-15
    • 2014-10-28
    • 1970-01-01
    相关资源
    最近更新 更多