OpenCV不会加载大图像(~4GB)

cLu*_*pus 7 python opencv image-processing matplotlib large-files

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

import cv2
img = 'ortho.tif'
I = cv2.imread(img, cv2.IMREAD_COLOR)
Run Code Online (Sandbox Code Playgroud)

此部分不会(始终)生成错误消息.在显示图像的同时:

cv2.imshow('image', I)
Run Code Online (Sandbox Code Playgroud)

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

plt.imshow(I[:, :, ::-1])  # Hack to change BGR to RGB
Run Code Online (Sandbox Code Playgroud)

对于大型图像,OpenCV或Python有任何限制吗?你有什么建议让这个iamge加载?

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

提前,谢谢你的帮助:)

Bil*_*adj 7

的实施imread()

Mat imread( const string& filename, int flags )
{
    Mat img;
    imread_( filename, flags, LOAD_MAT, &img );
    return img;
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

实际上,即使您有足够的 RAM,操作 4 GB RAM 图像的像素也不是一个好主意,无论如何您都需要根据兴趣区域、较小区域和可能是通道来分割它,具体取决于关于要对像素执行的操作的性质。

编辑 1:

正如我在答案下方的评论中所说,如果您有 16GB 的 RAM 并且您能够使用scikit读取该图像,那么您没有理由不能使用 OpenCV 执行相同操作。

请试一试:

import numpy as np # Do not forget to import numpy
import cv2    
img = cv2.imread('ortho.tif')
Run Code Online (Sandbox Code Playgroud)

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

编辑2:

OpenCV 可以处理大小高达 10 GB 的 imaes。但是,当涉及到cv2.imwrite()功能时,情况确实如此。cv2.imread()然而,对于,要读取的图像大小要小得多:这是 2013 年 9 月宣布的错误(问题3258 #1438),AFAIK 仍未修复。