简体   繁体   English

如何从OpenCV图像中获取TIFF字节流,而不是numpy数组?

[英]How do I get a TIFF bytestream from an OpenCV image, rather than a numpy array?

In python, I want to convert an image that has been processed using OpenCV for transmission in a certain image format ( TIFF in this case, but could be: BMP, JPEG, PNG, .....). 在python中,我想转换使用OpenCV处理的图像以某种图像格式传输(在这种情况下为TIFF ,但可能是:BMP,JPEG,PNG,.....)。

For this purpose it will suffice to encode the OpenCV image into a memory buffer. 为此,将OpenCV图像编码到存储缓冲器中就足够了。 The problem is that when I use cv2.imencode() to do this the returned object still looks like a numpy array: 问题是,当我使用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 is just another numpy array - it is not at all a TIFF-encoded bytestream! im_buffer只是另一个numpy数组 - 它根本不是TIFF编码的字节流! As far as I can tell, OpenCV images in python always behave like numpy arrays, and even look like numpy arrays via type() . 据我所知,python中的OpenCV图像总是表现得像numpy数组,甚至通过type()看起来像numpy数组。

In fact, if you want to create a dummy "OpenCV image", you have to use numpy - see eg https://stackoverflow.com/a/22921648/1021819 事实上,如果你想创建一个虚拟的“OpenCV图像”,你必须使用numpy - 参见例如https://stackoverflow.com/a/22921648/1021819

Why is this, and how do I fix it? 为什么会这样,我该如何解决? That is, how do I obtain an actual TIFF-encoded bytestream rather than another numpy array? 也就是说,我如何获得实际的TIFF编码字节流而不是另一个numpy数组呢?

Now I love numpy , but in this case I need the image to be readable by non-python services, so it needs to be in a commonly-available (preferably lossless) format (see list above). 现在我喜欢numpy ,但在这种情况下,我需要非python服务可以读取图像,因此它需要采用通用(最好是无损)格式(参见上面的列表)。

(I've gone round the houses of embedding numpy within JSON and decided against it.) (我已经绕过JSON中嵌入numpy的房子并决定反对它。)

I could use PIL /pillow, scipy , and some, but I am trying to minimize dependencies (ie so far only cv2 , numpy and intrinsics). 我可以使用PIL /枕头, scipy和一些,但我试图最小化依赖性(即到目前为止只有cv2numpy和内在函数)。

Thanks! 谢谢!

Following https://stackoverflow.com/a/50630390/1021819 and building (but not very much) on the comment by Dan Masek, the required extra step is simply to use im_buffer.tobytes() , which returns a bytestring that can be sent through a stream. 关注https://stackoverflow.com/a/50630390/1021819并在Dan Masek的评论上构建(但不是很多),所需的额外步骤只是使用im_buffer.tobytes() ,它返回一个可以是字节im_buffer.tobytes()的字符串通过流发送。

Python OpenCV images do seem to be represented as pure numpy arrays. Python OpenCV图像似乎表现为纯粹的numpy数组。 As pointed out by Dan Masek, the arrays can be transformed using cv2.imencode() into TIFF, PNG, BMP, JPG etc. 正如Dan cv2.imencode()所指出的,可以使用cv2.imencode()将数组转换为TIFF,PNG,BMP,JPG等。

There is obviously some debate around choice of formats and compression. 关于格式和压缩的选择显然存在争议。 In the case above there was a preference for lossless compression, implying TIFF, BMP or PNG (still there will be debate). 在上面的例子中,有一个偏好无损压缩,暗示TIFF,BMP或PNG(仍然会有争议)。 The python bindings to OpenCV have no tunable parameters for TIFF compression (unlike(?) the C++ bindings?), so it's not very easy to discover what is being done there. Python绑定到OpenCV的有TIFF无压缩可调参数(不像(?)的C ++绑定?),所以它不是很容易发现正在做什么存在。 The compression level could apparently be better using other libraries but my aim was to minimize dependencies (see above). 使用其他库显然可以更好地压缩级别,但我的目标是最小化依赖性(见上文)。

A BMP-encoded image was no smaller than a TIFF one. BMP编码的图像不小于TIFF图像。 PNG compression is tunable in python OpenCV, and setting PNG压缩在python OpenCV和设置中是可调的

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

has given the best size-speed trade-off so far. 到目前为止,我们已经给出了最佳的速度权衡。 Thanks. 谢谢。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM