OpenCV 图像大小限制

use*_*482 6 c++ opencv

我正在尝试使用 ITK 到 openCV 桥在 openCV 和 itk 之间传递一个巨大的 Mat 图像 (98304x51968)。我有一个错误:

cvIniyImageHeader 中内存不足(imageSize 溢出),文件 opencv\modules\core\src\array.cpp 第 2961 行。

这是否意味着opencv对图像大小有限制?

Cat*_*ree 2

好消息,由于这个拉取请求:正确处理巨大的矩阵#11505,您应该能够执行类似的操作(从测试中获取的代码):

Mat m(65000, 40000, CV_8U);
ASSERT_FALSE(m.isContinuous());

uint64 i, n = (uint64)m.rows*m.cols;
for( i = 0; i < n; i++ )
    m.data[i] = (uchar)(i & 255);

cv::threshold(m, m, 127, 255, cv::THRESH_BINARY);
int nz = cv::countNonZero(m);  // FIXIT 'int' is not enough here (overflow is possible with other inputs)
ASSERT_EQ((uint64)nz, n / 2);
Run Code Online (Sandbox Code Playgroud)

由于countNonZero()返回一个int,因此可能会发生溢出。这意味着您应该能够创建巨大的矩阵,但并非所有 OpenCV 函数都可以正确处理巨大的矩阵。


ITKImageToCVMat关于您的问题,这是以下代码v5.0a02

template<typename TInputImageType>
cv::Mat
OpenCVImageBridge::ITKImageToCVMat(const TInputImageType* in, bool force3Channels)
{
  // Extra copy, but necessary to prevent memory leaks
  IplImage* temp = ITKImageToIplImage<TInputImageType>(in, force3Channels);
  cv::Mat out = cv::cvarrToMat( temp, true );
  cvReleaseImage(&temp);
  return out;
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,IplImage图像仍然被使用,并且应该是错误的根源。目前您最好的选择应该是自己进行转换。也许类似(我不知道ITK,相同的输入和输出类型,一个通道):

typename ImageType::RegionType  region = in->GetLargestPossibleRegion();
typename ImageType::SizeType    size = region.GetSize();
unsigned int w = static_cast< unsigned int >( size[0] );
unsigned int h = static_cast< unsigned int >( size[1] );
Mat m(h, w, CV_8UC1, in->GetBufferPointer());
Run Code Online (Sandbox Code Playgroud)

这里不涉及副本。如果你想复制,你可以这样做:

Mat m_copy = m.clone();
Run Code Online (Sandbox Code Playgroud)