OpenCV图像大小限制
OpenCV image size limit
我正试图使用itk-openCV桥在openCV和itk之间传递一个巨大的Mat图像(98304x51968(。我有一个错误:
cvIniyImageHeader内存不足(图像大小溢出(,文件opencv\modules\core\src\array.cpp第2961行。
这是否意味着opencv对图像的大小有限制?
好消息,既然这个pull请求:正确处理巨大的矩阵#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);
由于countNonZero()
返回一个int
,所以可能会发生溢出。这意味着你应该能够创建巨大的矩阵,但并不是所有的OpenCV函数都能正确处理巨大的矩阵。
关于您的问题,这是v5.0a02
:中ITKImageToCVMat
的代码
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;
}
正如您所看到的,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());
此处不涉及任何副本。如果你想复制,你可以做:
Mat m_copy = m.clone();
IplImage中似乎有一个带符号的int(通常为32位(限制:从命名的.cpp文件中,以下是导致错误的代码片段:
const int64 imageSize_tmp = (int64)image->widthStep*(int64)image->height;
image->imageSize = (int)imageSize_tmp;
if( (int64)image->imageSize != imageSize_tmp )
CV_Error( CV_StsNoMem, "Overflow for imageSize" );
看起来(没有检查(image->imageSize
是一个32位有符号的int,这部分代码将检测和处理溢出。根据你在评论中发布的链接,IplImage"错误"可能已经修复(我没有检查(,所以也许你可以在更新的IplImage版本的OpenCV代码中删除这个溢出检测步骤,但这只是猜测,必须得到确认。您必须检查image->imageSize
的类型。如果是64位类型,您可能可以更改openCV代码以支持大于2147483647字节的Mats。
编辑:备注:我检查了OpenCV 3.4中的代码,但代码行是正确的,所以在4.0版本中可能还没有更改。
如果你确定IplImage的限制已经修复,你可以试试这个:
const int64 imageSize_tmp = (int64)image->widthStep*(int64)image->height;
image->imageSize = imageSize_tmp; // imageSize isn't 32 bit signed int anymore!
//if( (int64)image->imageSize != imageSize_tmp ) // no overflow detection necessary anymore
// CV_Error( CV_StsNoMem, "Overflow for imageSize" ); // no overflow detection necessary anymore
但最好确保IplImage的imageSize现在是64位;(
UPDATE:中的链接修复程序https://github.com/opencv/opencv/pull/7507/commits/a89aa8c90a625c78e40f4288d145996d9cda3599添加了溢出检测,所以PROABLY IplImage仍然有32位int imageSize限制!这里要小心!
- C++,OpenCV,尝试显示图像时"OpenCV(4.3.0) Error: Assertion failed (size.width>0 && size.height>0)"此错误
- 如何使用OpenCV将RBG图像转换为HSV,并将H、S和V值保存为C++中的3个独立图像
- OpenCV EqualizeHist()从彩色图像创建黑白图像
- 如何使用 OpenCV 解码在两个 UWP 应用之间发送的图像字节?
- 如果不在窗口 10 中声明名为 openCV 的 openCV namedWindow,QT 图像显示将无法正常工作
- 在本地网络中通过OpenCV(C++)实时流式传输图像
- 如何在 OpenCV 中将图像与另一个图像相关联
- 如何在 OpenCV c++ 中压缩 TIFF 格式的图像?
- OpenCV - 如何在灰度图像上应用 Kmeans?
- 阅读和处理图像(OpenCV/C )
- cv::findContours 正在修改源图像 OpenCV 2.3
- 将图像替换为更大尺寸的图像 (OpenCV)
- 显示像素值已更改的图像openCV
- 具有积分图像的快速模糊图像(OpenCV)
- 扫描图像OpenCV上的文档检测
- 使用cv::Mat图像(opencv)如何检测对象
- 写作和展示图像OpenCV
- 从文件夹中读取图像(OpenCV)
- 无法保存从网络摄像头捕获的图像(OpenCV 2.3 的 imwrite 编译错误)
- 旋转不变的多个模板出现在图像Opencv