opencv中resize函数的源码
时间: 2023-09-07 12:14:06 浏览: 413
利用openCV实现图像缩放的C++程序源代码
3星 · 编辑精心推荐
下面是OpenCV中`resize`函数的源码:
```cpp
void cv::resize(InputArray src, OutputArray dst, Size dsize, double fx, double fy, int interpolation)
{
CV_INSTRUMENT_REGION();
CV_Assert( (src.depth() == CV_8U || src.depth() == CV_32F) && src.channels() <= 4 );
if( interpolation == INTER_AREA && fx > 1 && fy > 1 )
{
fx = 1./fx;
fy = 1./fy;
std::swap(dsize.width, dsize.height);
interpolation = INTER_AREA_RESCALE;
}
if( interpolation == INTER_CUBIC || interpolation == INTER_LANCZOS4 )
{
fx = saturate_cast<double>(dsize.width)/src.cols;
fy = saturate_cast<double>(dsize.height)/src.rows;
}
if( fx == 0 || fy == 0 )
{
dst.release();
return;
}
CV_Assert( (dsize.width > 0 || dsize.height > 0) && (fx > 0 || fy > 0) );
Mat srcMat = src.getMat();
if( srcMat.data == dst.getMat().data )
{
Mat temp;
resize(srcMat, temp, dsize, fx, fy, interpolation);
dst.assign(temp);
return;
}
dst.create(_resize(srcMat, dsize, fx, fy, interpolation));
}
```
这个函数的实现比较简单,主要是对输入参数进行检查,然后调用了`_resize`函数完成实际的图像缩放操作。在调用`_resize`函数之前,还对一些特殊情况进行了处理,比如当插值方法为`INTER_AREA`时,会先对图像进行缩小再进行放大,以提高放大效果。当插值方法为`INTER_CUBIC`或`INTER_LANCZOS4`时,会根据目标大小和原始图像大小计算出缩放比例`fx`和`fy`。
下面是`_resize`函数的源码:
```cpp
static Mat _resize(InputArray _src, Size dsize, double fx, double fy, int interpolation)
{
CV_INSTRUMENT_REGION()
int depth = _src.depth(), cn = _src.channels();
if( _src.isContinuous() && !(dsize.width == 0 && dsize.height == 0) )
{
dsize.width = dsize.width > 0 ? dsize.width : cvRound(_src.cols*fx);
dsize.height = dsize.height > 0 ? dsize.height : cvRound(_src.rows*fy);
if( (dsize.width == _src.cols && dsize.height == _src.rows) ||
(dsize.width == 0 && dsize.height == 0) )
{
return _src.getMat().clone();
}
if( cn == 1 || cn == 3 || cn == 4 )
{
Mat src = _src.getMat();
Mat dst(dsize, CV_MAKETYPE(depth, cn));
if( interpolation == INTER_NEAREST )
{
resize_nn<uchar, Vec3b, ResizeNoVec>(src, dst, fx, fy);
}
else if( interpolation == INTER_LINEAR || interpolation == INTER_CUBIC || interpolation == INTER_LANCZOS4 )
{
if( interpolation == INTER_LINEAR )
resize_<uchar, Vec3b, INTER_LINEAR>(src, dst, fx, fy);
else if( interpolation == INTER_CUBIC )
resize_<uchar, Vec3b, INTER_CUBIC>(src, dst, fx, fy);
else if( interpolation == INTER_LANCZOS4 )
resize_<uchar, Vec3b, INTER_LANCZOS4>(src, dst, fx, fy);
}
else if( interpolation == INTER_AREA || interpolation == INTER_AREA_RESCALE )
{
if( interpolation == INTER_AREA )
resize_area<uchar, Vec3b, ResizeNoVec>(src, dst, fx, fy);
else
resize_area<uchar, Vec3b, ResizeNoVec, AreaFast>(src, dst, fx, fy);
}
else if( interpolation == INTER_CUBIC2P_LINEAR )
resize_<uchar, Vec3b, INTER_CUBIC2P_LINEAR>(src, dst, fx, fy);
else if( interpolation == INTER_CUBIC2P )
resize_<uchar, Vec3b, INTER_CUBIC2P>(src, dst, fx, fy);
else if( interpolation == INTER_NEAREST_NEIGHBOUR_EX )
resize_nn<uchar, Vec3b, ResizeExpanse>(src, dst, fx, fy);
else if( interpolation == INTER_LINEAR_EX )
resize_<uchar, Vec3b, INTER_LINEAR_EX>(src, dst, fx, fy);
else if( interpolation == INTER_CUBIC_EX )
resize_<uchar, Vec3b, INTER_CUBIC_EX>(src, dst, fx, fy);
else if( interpolation == INTER_LANCZOS4_EX )
resize_<uchar, Vec3b, INTER_LANCZOS4_EX>(src, dst, fx, fy);
else
CV_Error(Error::StsUnsupportedFormat, "");
return dst;
}
}
Mat src = _src.getMat();
return resizeGeneric(src, dsize, fx, fy, interpolation);
}
```
这个函数根据输入参数的不同,选择不同的缩放方法进行图像缩放。具体而言,它包含了多个重载函数`resize_`和`resize_area`,分别对应了不同的插值方法。其中`resize_`函数是实现了线性、双三次和Lanczos插值方法的通用缩放函数;`resize_nn`函数是实现了最近邻插值方法的通用缩放函数;`resize_area`函数是实现了像素面积关系插值方法的通用缩放函数。这些函数的具体实现可以参考OpenCV源码。
阅读全文