我正在尝试使用 ITK 到 openCV 桥在 openCV 和 itk 之间传递一个巨大的 Mat 图像 (98304x51968)。我有一个错误:
cvIniyImageHeader 中内存不足(imageSize 溢出),文件 opencv\modules\core\src\array.cpp 第 2961 行。
这是否意味着opencv对图像大小有限制?
好消息,由于这个拉取请求:正确处理巨大的矩阵#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)