一、resize()函数介绍
resize()函数是专门用来调整图片的大小的,其原理就是通过不同的插值方式对图像进行处理,这些插值方式将在后续介绍到,首先介绍resize()函数的原型:
resize( InputArray src, OutputArray dst,Size dsize, double fx = 0, double fy = 0,int interpolation = INTER_LINEAR );
第一个参数为输入图像;
第二个参数为输出图像,通常情况下我们并不对其进行初始化,而是利用后续的dsize参数在程序中自动计算其尺寸;
第三个参数为输出图像希望的大小,如果它设置为0,将通过后续的fx,fy参数经由下述公式计算得来:
dsize=Size(round(fx*src.cols),round(fy*src.rows))
第四个参数为沿水平方向的缩放系数,有默认值0,取零的话则通过dsize参数经由下列公式计算得来:
fx=(double)dsize.width/src.cols
第五个参数为沿竖直方向的缩放系数,有默认值0,取零的话则通过dsize参数经由下列公式计算得来:
fy=(double)dsize.height/src.rows
第六个参数为插值类型的选择,可选方案有INTER_NEAREST 、INTER_LINEAR、INTER_CUBIC、INTER_AREA 、INTER_LANCZOS4。默认值INTER_LINEAR,一般也推荐选用INTER_LINEAR。后续将介绍这就这几种插值方法的原理。
二、插值方法介绍
(具体每个插值的实现方法可参见参考文献中其他博主的思路)
1.最近邻插值
最近邻插值的原理就是将放大或者缩小后的图片相应像素点直接乘以比例系数(应该为缩放系数的倒数)对应到原图中的相应像素点,如果存在小数的话则采用四舍五入或者直接舍去小数的方法。
假设resize后的图片某像素位置为 ( i ′ , j ′ ) (i',j') (i′,j′),分别乘以比例系数之后再分成整数部分和小数部分(i、j整数,u、v小数)为 ( i + u , j + v ) (i+u,j+v) (i+u,j+v),那如果采用四舍五入的方式,则按下图判断其对应原图像素值,落在A区取 ( i , j ) (i,j) (i,j),B区取 ( i + 1 , j ) (i+1,j) (i+1,j):

如果采用直接舍去的方式则不论u、v的值,直接对应原图 ( i , j ) (i,j) (i,j),这也是opencv中采用的最近邻插值方法。
2.双线性插值
双线性插值是使用映射回原图的像素点周围4个点来对待求像素点进行拟合,距离像素点越近的权重值越大。假设resize后的图片某像素位置为 ( i ′ , j ′ ) (i',j') (i′,j′),分别乘以比例系数之后再分成整数部分和小数部分(i、j整数,u、v小数)为 ( i + u , j + v ) (i+u,j+v) (i+u,j+v),那么实际拟合出的该像素值应该满足如下关系:
f ′ ( i ′ , j ′ ) = ( 1 − u ) ( 1 − v ) f ( i , j ) + u ( 1 − v ) f ( i + 1 , j ) + ( 1 − u ) v f ( i , j + 1 ) + u v f ( i + 1 , j + 1 ) ; f'(i',j')=(1-u)(1-v)f(i,j)+u(1-v)f(i+1,j)+(1-u)vf(i,j+1)+uvf(i+1,j+1); f′(i′,j′)=(1−u)(1−v)f(i,j)+u(1−v)

本文深入解析了OpenCV中resize()函数的使用方法及其背后的插值原理。从最近邻插值到双线性插值,再到双三次插值,详细阐述了每种插值方式的计算过程,帮助读者理解如何调整图像大小。
最低0.47元/天 解锁文章
1295

被折叠的 条评论
为什么被折叠?



