0 引言
在图像处理中,经常需要改变图像的尺寸,比如在图像识别时需要将图像归一化到某一标准尺寸,在目标检测中需要在不同尺度的图像上进行检测,以应对尺度变化。OpenCV提供了如下两种方式来改变图像尺寸:
- resize()函数。最直接的方法,只要给定输入输出图像,以及目标尺寸和插值方式就可以完成。
- pyrUp(),pyrDown()函数。即图像金字塔相关的两个函数,对图像进行向上采样,向下采样的操作。
这篇文章中,首先介绍图像金字塔的原理,接着介绍resize()函数,然后是pyrUP()和pyrDown()函数,最后是一个综合实例程序。
1 图像金字塔原理
一般情况下,有两种常用的金字塔,他们分布是
- 高斯金字塔(Gaussian Pyramid):用来向下采样,主要是图像金字塔
- 拉普拉斯金字塔(Laplacian Pyramid):用来从金字塔底层图像重建上层未采样图像,在数字图像处理中也即是预测残差,可以对图像进行最大程度的还原,配合高斯金字塔一起使用
1.1 高斯金字塔
高斯金字塔是通过高斯平滑和亚采样获得一系列下采样图像,也就是第K层高斯金字塔通过平滑、亚采样就可以获得K+1层高斯图像。示意图如下:
对高斯金字塔从下到上进行编号,序号从小到大,尺寸从大到小。为了获取层级为$G_{i+1}$的金字塔图像,采用如下方法
- 对图像$G_i$进行高斯内核卷积,卷积核如下
$$
\frac{1}{16} \left [
\begin{matrix}
1&4&6&4&1\\
4&16&24&16&4\\
6&24&36&24&6\\
4&16&24&16&4\\
1&4&6&4&1
\end{matrix}
\right ]
$$ - 将所有的偶数行和列去除
显而易见,结果图像只有原图的四分之一。通过对输入图像$G_0$(原始图像)不停迭代以上步骤就会得到整个金字塔。
上述过程描述了如何对图像进行下采样,那么如何将图像变大呢?
- 将图像在每个方向扩大为原来的两倍,新增的行和列以0填充
- 使用先前同样的内核(乘以4)与放大后的图像卷积,获得“新增像素”的近似值。
这两个步骤(向下和向上采样)分别通过OpenCV函数pyrUp和pyrDown实现。
1.2 拉普拉斯金字塔
拉普拉斯金字塔第i层的数学定义为:
$$
L_i=G_i-UP(G_{i+1})\otimes G_{5\times 5}=G_i-PyrUp(G_{i+1})
$$
其中,$G_{5\times 5}$表示$5\times 5$的高斯内核,$\otimes$表示卷积。
也就是说,拉普拉斯金字塔的第i层是通过高斯金字塔第i层减去高斯金字塔第i层先缩小后放大的图像得到的。
整个拉普拉斯金字塔的的求解过程可以用下图表示:
关于图像金字塔非常重要的一个应用就是实现图像分割。图像分割的话,先要建立一个图像金字塔,然后在$G_i$和$G_{i+1}的像素直接依照对应关系,建立起“父与子”的关系。而快速初始分割可以先在金字塔高层的低分辨率图像上完成,然后逐层对分割加以优化。
2 resize()函数解析
首先看一下它的函数原型:
- 第一个参数:输入图像,Mat类型的对象即可。
- 第二个参数:输出图像,当其非0时,有着dsize的尺寸,或者通过src.size()来计算。
- 第三个参数:输出图像的大小;如果它等于零,则由下式进行计算
$$
dsize=Size(round(fxsrc.cols),round(fysrc.rows))
$$
其中,dsize,fx,fy不能同时为0. - 第四个参数:沿水平轴的缩放系数,有默认值0,当其等于0时,由下式进行计算
$$
(double)dsize.width/src.cols
$$ - 第五个参数:沿垂直轴的缩放系数,有默认值0,当其等于0时,由下式进行计算
$$
(double)dsize.height/src.rows
$$ - 第六个参数:用于指定插值方式,默认为线性插值(INTER_LINEAR)
可选的插值方式有:
- INTER_NEAREST-最近邻插值
- INTER_LINEAR-线性插值
- INTER_AREA-区域插值(利用像素区域关系的重采样插值)
- INTER_CUBIC-三次样条插值(超过4*4像素领域内的双三次插值)
- INTER_LANCZOS4-Lanczos插值(超过8*8像素领域内的Lanczos插值)
若要缩小图像,一般情况下最好使用CV_INTER_AREA来插值;
若要放大图像,一般情况下最好用INTER_CUBIC(效率不高)或INTER_LINEAR(效率较高)