【问题标题】:OpenCV will not load a big image (~4GB)OpenCV 不会加载大图像(~4GB)
【发布时间】:2016-06-10 13:21:29
【问题描述】:

我正在开发一个程序,该程序用于从相当大的图像中检测彩色地面控制点。 TIFF 图像约为 3 - 4 GB(约 35 000 x 33 000 像素)。 我正在使用 Python 2 和 OpenCV 进行图像处理。

import cv2
img = 'ortho.tif'
I = cv2.imread(img, cv2.IMREAD_COLOR)

这部分不会(总是)产生错误消息。显示图像时:

cv2.imshow('image', I)

我也尝试过使用 matplotlib 显示图像:

plt.imshow(I[:, :, ::-1])  # Hack to change BGR to RGB

OpenCV 或 Python 对大图像有什么限制吗? 你会建议什么来加载这个 iamge?

PS:我做这项工作的计算机是 Windows 10“工作站”(它有足够的马力来处理图像)。

提前感谢您的帮助:)

【问题讨论】:

  • 错误信息是什么意思?
  • 对于 matplotlib plt.imshow(self.image[:, :, ::-1]) TypeError: 'NoneType' object has no attribute '__getitem__' OpenCV sais: OpenCV Error: Assertion failed (size .width>0 && size.height>0) 在 cv::imshow,文件 ..\..\..\modules\highgui\src\window.cpp,第 261 行 cv2.imshow('image', self.image ) cv2.error: ..\..\..\modules\highgui\src\window.cpp:261: error: (-215) size.width>0 && size.height>0 in function cv::imshow 本质上,表示图像大小为 0 x 0 像素。
  • ...您肯定这些东西(当我说这些东西时,我指的是 OpenCV 和 Python)已经编译为 64 位?
  • 它是使用 64 位安装程序的 continuum 中的 anaconda 安装的,因此应编译为 64 位。另外,当我运行python时,它说它是64位版本。
  • 您能否确认您可以编写一个简单的 C++ 程序,该程序可以进行 malloc (35000*35000*3*sizeof(unsigned char)) 并向每个位置写入一些内容,并且该程序可以正常运行。

标签: python opencv image-processing matplotlib large-files


【解决方案1】:

imread()的实现:

Mat imread( const string& filename, int flags )
{
    Mat img;
    imread_( filename, flags, LOAD_MAT, &img );
    return img;
}

这会将与加载图像对应的矩阵分配为连续数组。所以这取决于(至少部分地)你的硬件性能:你的机器必须能够分配 4 GB 的连续 RAM 阵列(如果你在 Debian 发行版上,你可以通过运行来检查你的 RAM 大小,例如,vmstat -s -SM )。

出于好奇,我尝试使用ascontiguousarray 获得一个连续的内存阵列(一个很大,但小于 比您的 4 GB 图像所需的那个),但在此之前,我已经偶然发现内存分配问题:

>>> img = numpy.zeros(shape=(35000,35000))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
MemoryError
>>>

在实践中,即使您有足够的 RAM,也不宜处理 4 GB RAM 图像的像素,无论如何您都需要将其拆分为 regions of interests ,较小的区域,也可能是 channels,具体取决于您要对像素执行的操作的性质。

编辑 1:

正如我在您的回答下方的评论中所说,如果您有 16GB 的 RAM,并且您可以使用 scikit 读取该图像,那么您没有理由不能对 OpenCV 做同样的事情。

请试一试:

import numpy as np # Do not forget to import numpy
import cv2    
img = cv2.imread('ortho.tif')

您忘记在原始代码中导入 Numpy,这就是 OpenCV 显然无法加载图像的原因。所有 OpenCV 数组结构都与 Numpy 数组相互转换,并且您读取的图像由 OpenCV 表示为内存中的数组。

编辑 2:

OpenCV 可以处理最大为 10 GB 的图像。但是当涉及到cv2.imwrite() 函数时,情况确实如此。然而,对于cv2.imread(),要读取的图像大小要小得多:这是 2013 年 9 月 (Issue3258 #1438) 宣布的一个错误,AFAIK 仍然没有修复。

【讨论】:

  • 感谢您的提示。该程序的目标之一是自动找到感兴趣的区域。因此,整个图像必须在内存中,尽管不必同时存在。我听说h5py 应该做与你的建议类似的事情。不过我对这个库没有任何经验。
  • 你的机器有多少内存? @cLupus
  • 计算机有 16 GB RAM (DDR3)。
  • 实际上,我已经尝试使用import numpy as np,但我得到了同样的错误。
  • 好的。虽然,您的回答和 cmets 确实让我找到了一个可行的解决方案,尽管没有使用 OpenCV,这对于这个项目来说不是必须的。感谢您的时间和回复:)
【解决方案2】:

原来是scikit-image来救场的,我是从here发现的。

下面让我将图像加载到 python 会话中:

import numpy as np
from skimage.io import imread

img = imread(path_to_file)

加载大约需要半分钟左右。

【讨论】:

  • 它运行没有错误,但是变量 img 是空的(np.size(img) 给出输出 1),而 scikit 的 imread 给出一个带有数据的图像(大约 40 亿位)。跨度>
  • 我猜你做了正确的决定,不依赖 OpenCV 来处理这个特定的图像:我花时间环顾四周,因为你的问题引起了我的兴趣。最后我发现这是一个bug。您可以检查我的答案的编辑并...接受它,因为这是对您所面临问题的解释。最后,这是库本身的问题,而不是硬件或其他问题。
【解决方案3】:

使用这个帖子无济于事.... Remove OpenCV image size limitation 总之, pip install tifffile 它将 tif 文件加载到 numpy 数组中,然后可以照常与 OpenCV 一起使用(但使用如此大的文件需要您自担风险...... OpenCV 的设计假设图像小于1 千兆像素)

【讨论】:

    【解决方案4】:

    这可能是使用的 tiff 库的限制。 需要将 bigTIFF 与 64 位表一起使用。 从源代码构建 openCV 时,也许 USE_WIN32_FILEIO=OFF 会有所帮助。 使用一个使用大型 tiff 库的 python 包也有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-11
      • 1970-01-01
      • 1970-01-01
      • 2021-05-25
      • 2017-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多