如何在Python中使用OpenCV处理大图像?

4 投票
2 回答
2152 浏览
提问于 2025-04-18 05:15

我正在处理一个非常大的numpy数组,最后想把它写成一张JPEG图片,使用的是cv2.imwrite(numpy.array)这个方法。可惜的是,我的这个数组太大了,放不进我的内存里,尽管最终的JPEG图片大约只有200MB。

我该如何处理这么大的数据而不让我的内存崩溃呢?

有没有其他方法可以在不一次性把整个数组都放进内存的情况下写出图片?我可以分批加载数组的一小部分,但我不知道该用哪个模块或函数来写图片,而不需要一次性把整个数组都放在内存里。

目前为止,我把整个图片分成了4个小图片(四分之一),因为这是我在有限内存下能做到的最好方法。但我还是想把它们拼接成一张完整的图片。目标图片是一个有3个通道,大小为26112 x 20480的图片。

2 个回答

1

如果你要处理很大的图像,使用稀疏矩阵可能会很有帮助。一个可以试试的库是Eigen。这里有一个关于如何使用稀疏矩阵的教程,可以帮助你了解这个库。

另外,OpenCV也支持稀疏矩阵。

2

如果一张图片的大小是26112 x 20480像素,并且有三个颜色通道,每个通道占用1个字节,那么这张未压缩的图片数据就需要3 x 26112 x 20480字节,差不多是1.5个吉字节(GB)。而JPEG格式的文件通常会小很多,因为它使用了一种有损压缩的方法,但在OpenCV中,图片的表示方式是未压缩的。

有些操作(比如在块边界上裁剪)可以在压缩的图片上进行,像是Jpegtran这个工具就能做到。不过在OpenCV中,你大多数情况下还是需要先解压缩数据。如果你的算法正好能直接用8x8块的DCT系数来写,那就不需要解压缩,但OpenCV在这方面的支持不太够。

我不确定在OpenCV中是否可行,但numpy支持内存映射输入输出,可以处理原始数组数据。当你读取一页不在内存中的数据时,操作系统会从映射的文件中读取数据,如果内存不够用,它会把一些页面移除。是否能高效运行取决于你访问数据的方式。原则上,你应该可以直接在一个已经解压缩并且内存布局正确的文件上调用mmap,然后将指针包装成OpenCV数组,不过我自己还没有尝试过。

撰写回答