我的图像尺寸是12000090000;我试了50005000都没问题,这就奇怪了,于是我按照提示去看opencv源码,找到sources\modules\imgproc\src\resize.cpp文件的第4045行,resize源码下:
void cv::resize( InputArray _src, OutputArray _dst, Size dsize,
double inv_scale_x, double inv_scale_y, int interpolation )
{
CV_INSTRUMENT_REGION()
Size ssize = _src.size();
CV_Assert( ssize.width > 0 && ssize.height > 0 );
CV_Assert( dsize.area() > 0 || (inv_scale_x > 0 && inv_scale_y > 0) );
if( dsize.area() == 0 )
{
dsize = Size(saturate_cast<int>(ssize.width*inv_scale_x),
saturate_cast<int>(ssize.height*inv_scale_y));
CV_Assert( dsize.area() > 0 );
}
else
{
inv_scale_x = (double)dsize.width/ssize.width;
inv_scale_y = (double)dsize.height/ssize.height;
}
if (interpolation == INTER_LINEAR_EXACT && (_src.depth() == CV_32F || _src.depth() == CV_64F))
interpolation = INTER_LINEAR; // If depth isn't supported fallback to generic resize
CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat() && _src.cols() > 10 && _src.rows() > 10,
ocl_resize(_src, _dst, dsize, inv_scale_x, inv_scale_y, interpolation))
Mat src = _src.getMat();
_dst.create(dsize, src.type());
Mat dst = _dst.getMat();
if (dsize == ssize)
{
// Source and destination are of same size. Use simple copy.
src.copyTo(dst);
return;
}
hal::resize(src.type(), src.data, src.step, src.cols, src.rows, dst.data, dst.step, dst.cols, dst.rows, inv_scale_x, inv_scale_y, interpolation);
}
可以看到是**CV_Assert( dsize.area() > 0 || (inv_scale_x > 0 && inv_scale_y > 0) );这行代码抛出的错误,inv_scale_x 和inv_scale_y 默认是0,这里应该没问题,那就是dsize.area()出现问题,再定位area()**的实现:
template<typename _Tp> inline
_Tp Size_<_Tp>::area() const
{
const _Tp result = width * height;
CV_DbgAssert(!std::numeric_limits<_Tp>::is_integer
|| width == 0 || result / width == height); // make sure the result fits in the return value
return result;
}
看到返回的是行和列的乘积,这是突然就想到难道返回值超出范围了?于是马上去看cv::resize的第三个参数cv::Size dsize.再看cv::Size的定义:
typedef Size_<int> Size2i;
typedef Size_<int64> Size2l;
typedef Size_<float> Size2f;
typedef Size_<double> Size2d;
typedef Size2i Size;
其实就是int型的,我们都知道int类型占 4byte * 8bit = 32比特,因此int范围是 -231——231-1,即-2147483648——2147483647,再看我图像尺寸乘积120000*90000=10800000000,果然超出范围了,dsize.area()得到的是一个负数,因此CV_Assert抛出了异常。
修改opencv源码,重新编译!
将opencV3.4.0\opencv\sources\modules\imgproc\src\resize.cpp文件中**void cv::resize( InputArray _src, OutputArray _dst, Size dsize,double inv_scale_x, double inv_scale_y, int interpolation )**函数实现修改为如下:
void cv::resize( InputArray _src, OutputArray _dst, Size dsize,
double inv_scale_x, double inv_scale_y, int interpolation )
{
CV_INSTRUMENT_REGION()
Size ssize = _src.size();
CV_Assert(!ssize.empty());
if (dsize.empty())
{
CV_Assert(inv_scale_x > 0); CV_Assert(inv_scale_y > 0);
dsize = Size(saturate_cast<int>(ssize.width*inv_scale_x),
saturate_cast<int>(ssize.height*inv_scale_y));
CV_Assert(!dsize.empty());
}
else
{
inv_scale_x = (double)dsize.width / ssize.width;
inv_scale_y = (double)dsize.height / ssize.height;
CV_Assert(inv_scale_x > 0); CV_Assert(inv_scale_y > 0);
}
if (interpolation == INTER_LINEAR_EXACT && (_src.depth() == CV_32F || _src.depth() == CV_64F))
interpolation = INTER_LINEAR; // If depth isn't supported fallback to generic resize
CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat() && _src.cols() > 10 && _src.rows() > 10,
ocl_resize(_src, _dst, dsize, inv_scale_x, inv_scale_y, interpolation))
// Fake reference to source. Resolves issue 13577 in case of src == dst.
UMat srcUMat;
if (_src.isUMat())
srcUMat = _src.getUMat();
Mat src = _src.getMat();
_dst.create(dsize, src.type());
Mat dst = _dst.getMat();
if (dsize == ssize)
{
// Source and destination are of same size. Use simple copy.
src.copyTo(dst);
return;
}
hal::resize(src.type(), src.data, src.step, src.cols, src.rows, dst.data, dst.step, dst.cols, dst.rows, inv_scale_x, inv_scale_y, interpolation);
}