一、什么是resize 函数:
resize函数opencv中专门用来调整图像大小的函数;
opencv 提供五种方法供选择分别是:
a.最近邻插值——INTER_NEAREST;
b.线性插值 ——INTER_LINEAR;(默认值)
c.区域插值 ——INTER_AREA;(利用像素区域关系的重采样插值)
d.三次样条插值——INTER_CUBIC(超过4*4像素邻域内的双三次插值)
e.Lanczos插值——INTER_LANCZOS4(超过8*8像素邻域的Lanczos插值)
一般来说要缩小图像用区域插值(INTER_AREA);要放大图像一般用三次样条插值(INTER_CUBIC)或者线性插值(INTER_LINEAR);
二、resize 5类算法的公式:
以下图来说明假设下图的大小为m*n ,想通过resize 函数把尺度变化为m1*n1;
a.最近邻插值:
b.线性插值(双线性插值):
其中:u v 是相当于放缩后的图像Dst相对于原图像Src中对应位置的小数部分;用的是最近邻插的公式;
c.区域插值: 当放大图像时类似最近邻插值,当缩小图像时候有不同的结果;能有效避免波纹出现;
d.三次样条插值(双三次插值):使用的是4*4邻域的像素双3次插值 从(i-1,j-1)到(i+2,j+2)所有点的插值运算结果公式如下图:
其中S(x)是对 sin(x*pi)/x 的逼近,为插值核;
e.Lanczos插值:
其中:i,j 为缩放前的位置,水平相位值PH0 、PH1、PH2、PH3,垂直相位值PV0、PV1、PV2、PV3。具体如下图所示
三、函数申明格式:
C++:void resize (InputArray src, OutputArray dst,Size dsize,double fx=0;double fy=0,int interpolation=INTER_LINEAR);
第一个参数:为输入图像;
第二个参数:为输出图像;
第三个参数:输出图像的大小;
第四个参数:沿着水平轴的缩放系数;
第五个参数:沿着垂直轴的缩放系数;
第六个参数:插值方式默认为 INTER_LINEAR 线性插值;
四、具体的实验数据结果:
选取图像的数据为3*3矩阵[5,3,1,1,1,1,0,1,0];扩大到6*6的矩阵结果图
选取图像的数据为6*6矩阵缩小到3*3矩阵的结果图
结论:对于放大图像来说方法越复杂,求出来的数据效果越好,同样的计算时间也会提高(后面会验算时间),区域插值结果与最近邻插结果一样;
对于缩小图像来说方法越复杂,求出来的数据效果越好,同样的计算时间也会提高(后面会验算时间),区域插值结果与线性插值结果一样;
五、具体图像运算结果
缩小图像用区域插值;放大图像用三次样条插值(速度慢);线性插值(速度快);
六、算法的具体时间测试,用一张400*400的图像进行测试: 单位是 MS 用的clock_t 函数测试 循环100次然后 折算成MS
缩小成200*200像素图像的测试结果
最近邻插
双插线性 区域插值 双三插值 LANCZOS4
扩大成为 800*800像素图像的测试结果
最近邻插
双插线性 区域插值双三插值 LANCZOS4
PS:如果自己计算会发现结果不正确,根源在于图像中心opencv修正过;修正公式为:
void resize(InputArray src, OutputArray dst, Size dsize, double fx=0, double fy=0, int interpolation=INTER_LINEAR)
。src 输入图
。dst 输出图,形态和输入图相同,当dsize不等于0,输出图尺寸会和dsize相同,当dsize等于0,输出图尺寸会由输入图尺寸、fx、fy计算而得
。dsize 输出尺寸,当输入为0时,fx、fy皆不可为0,dsize = Size(round(fxsrc.cols),round(fysrc.rows))
。fx 水平缩放比例,当输入为0时,fx=(double)dsize.width/src.cols
。fy 垂直缩放比例,当输入为0时,fy=(double)dsize.height/src.rows
。interpolation 内插方式 内插方式有
a). CV_INTER_NEAREST 最邻近插值点法
b). CV_INTER_LINEAR 双线性插值法
c).CV_INTER_AREA 邻域像素再取样插补
d).CV_INTER_CUBIC 双立方插补,4*4大小的补点
e).
當我們縮小影像時,使用CV_INTER_AREA會有比較好的效果,當我們放大影像,CV_INTER_CUBIC會有最好的效果,但是計算花費時間較多,CV_INTER_LINEAR能在影像品質和花費時間上取得不錯的平衡。 CV_INTER_LANCZOS4 Lanczos插补,8*8大小的补点
此篇主要记录下因为本人使用的环境是Qt5.9.1+MSV2015编译器,因Qt中有自己的resize()函数,所以开始的时候始终不对
因为前面有using namespace cv; 所以忘记当有重名函数时要加作用域下调用,所以记得cv::resize();
————————————————
版权声明:本文为CSDN博主「落寞的雪」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_41424481/article/details/96975616