图像金字塔、高斯金字塔、拉普拉斯金字塔是怎么回事?附利用拉普拉斯金字塔和高斯金字塔重构原图的Python-OpenCV代码

图像金字塔是对图像进行多分辨率表示的一种有效且简单的结构。
一个图像金字塔是一系列以金字塔形状排列的分辨率逐步降低的图像。图像金字塔的底部是待处理图像的高分辨率表示,而顶部是低分辨率表示。

图像金字塔有什么作用?
图像金字塔常用于图像缩放、图像重构、图像融合、图像增强技术中。
这里说下图像金字塔在图像融合技术中的应用:多分辨率塔式图像融合算法是现在较为常用的图像融合方法。在这类算法中,原图像被层层滤波和缩小,形成一个塔状结构。在塔的每一层都用一种融合算法对这一层的数据进行融合,从而得到一个经算法处理后的塔式结构,然后对处理后的塔式结构进行重构,从而得到合成图像。
另外,图像金字塔可以将原图像分别分解到不同的空间频带上,这样就可以针对不同分解层的不同频带上的特征与细节,采用不同的算子以达到更有针对性的算法优化处理。

高斯金字塔和拉普拉斯金字塔是最常见的两种图像金字塔。

下面详细介绍高斯金字塔和拉普拉斯金字塔。

高斯金字塔
高斯金字塔是指通过高斯模糊滤波和下采样不断地将图像的尺寸缩小,进而在金字塔中包含多个分辨率的一组图像。高斯金字塔的形式如下图所示:
图像金字塔、高斯金字塔、拉普拉斯金字塔是怎么回事?附利用拉普拉斯金字塔和高斯金字塔重构原图的Python-OpenCV代码_第1张图片
一般情况下,高斯金字塔的最底层为原图像,每向上一层就会通过高斯模糊滤波+下采样缩小一次图像的尺寸。
通常情况下,图像的长与宽会缩小为原来的一半,由于每次图像的长与宽都缩小为原来的一半,图像的缩小速度非常快,因此常见的高斯金字塔的层数为3~6。

在OpenCV中提供了函数pyrDown(),用于生成图像的上一层高斯金字塔。
函数pyrDown()的原型如下:

void cv::pyrDown(InputArray src,
                 OutputArray dst,
                 const Size & dstsize = Size(),
                 int borderType = BORDER_DEFAULT )

函数pyrDown()的参数意义如下:
src—输入图像
dst—输出图像,它的宽度和高度大致为src的1/2 ,具体精确的大小由第三个参数dstsize决定。
dstsize—目标图像的大小,默认值为Size((src.cols+1)/2, (src.rows+1)/2),自己指定时需要满足以下条件。
在这里插入图片描述
bordertype—做高斯滤波时的边界扩展标志。关于边界扩展的详细介绍可参见下面这篇博文:
https://www.hhai.cc/thread-178-1-1.html
使用函数pyrDown()生成上一层高斯金字塔包含两个过程,即高斯核卷积(用于实现高斯模糊滤波)和下采样两个过程。
G n G_{n} Gn表示第n层高斯金字塔的图像,则 G 0 G_{0} G0表示高斯金字塔的最底层,这一层实际上就是原图像。为了得到 G n + 1 G_{n+1} Gn+1,首先需要对 G n G_{n} Gn进行高斯核卷积,即做高斯低通滤波,然后删除所有的偶数行和偶数列(这是一种下采样操作),从而得到 G n + 1 G_{n+1} Gn+1
函数pyrDown()使用的高斯核如下:
图像金字塔、高斯金字塔、拉普拉斯金字塔是怎么回事?附利用拉普拉斯金字塔和高斯金字塔重构原图的Python-OpenCV代码_第2张图片
提问:为什么高斯金字塔在下采样操作之前要先进行高斯低通滤波。
答:这样做既能保证高斯金字塔低通处理的性质,又能对图像进行平滑,使下采样得到的图像不至于出现边界缝隙。
总结一下:图像高斯金字塔的上一层是对下一层进行低通滤波后再进行隔行隔列采样得到的。上一层图像的大小约为下一层图像的1/4。

拉普拉斯金字塔
拉普拉斯金字塔实际上是为了实现高斯金字塔的图像重建而存在的。它是在高斯金字塔的基础上生成的。拉普拉斯金字塔是高斯金字塔与其上一层通过上采样扩大后的差值图像,这里的上采样一般采用插值的方式进行。

昊虹君在网上找到了一幅示意图,很形象具体地解释了拉普拉斯金字塔是怎么回事,
这幅示意图请大家访问本博文的原文查看,
本博文的原文链接:

https://www.hhai.cc/thread-198-1-1.html

从上面昊虹君找到的那幅示意图我们可以清晰地看出:第n层拉普拉斯图像实际上是第n层高斯图像与第n+1层高斯图像经上采样后的差值,由于高斯滤波器是一种低通滤波器,所以我们可以说某一级的拉普拉斯金字塔可以反映出其同级的高斯金字塔的高频分量。有些文献把拉普拉斯金字塔反映其同级高斯金字塔的高频分量的性质称为拉普拉斯金字塔的预测残差作用。

从上面拉普拉斯图像的生成过程我们可以看出,在利用高斯金字塔生成拉普拉斯金字塔的过程中,假设高斯金字塔为N层,则在计算第N层的拉普拉斯金字塔时我们还要额外计算出第N+1层的高斯金字塔才能进而计算出第N层的拉普拉斯金字塔。

OpenCV提供了函数pyrUp()用于帮助计算出拉普拉斯金字塔。通过它可以把第n层的高斯金字塔图像进行上采样后再进行高斯卷积模糊滤波操作。
OpenCV官方文档中对其功能的描述如下:
The function performs the upsampling step of the Gaussian pyramid construction, though it can actually be used to construct the Laplacian pyramid. First, it upsamples the source image by injecting even zero rows and columns and then convolves the result with the same kernel as in pyrDown multiplied by 4
从上面的描述中我们可知,函数pyrUp()的上采样操作是均匀地隔行隔列加0值。上采样完成之后用下面这个卷积核进行高斯卷积模糊滤波操作。
图像金字塔、高斯金字塔、拉普拉斯金字塔是怎么回事?附利用拉普拉斯金字塔和高斯金字塔重构原图的Python-OpenCV代码_第3张图片
请注意:上面这个卷积核与函数pyrDown()的卷积核有所不同,具体是函数pyrDown()高斯卷积核需要乘以四才得到函数pyrUp()的卷积核,至于为什么要这样做,博主昊虹君目前没有搞清楚,猜想应该是与其上采样时隔行隔列插0值有关。知道原因的朋友可以与昊虹君说一说,先谢谢了。

函数pyrDown()的的原型如下:

void cv::pyrUp(InputArray src,
               OutputArray dst,
               const Size & dstsize = Size(),
               int borderType = BORDER_DEFAULT )

各参数的意义和函数pyrDown()的一样,这里就不再赘述了。

这里要特别注意:函数pyrDown()的dst参数中得到的并不是拉普拉斯金字塔图像。
如果要得到拉普拉斯金字塔图像,还需要按下面的公式进行运算。
L n L_{n} Ln表示第n层拉普拉斯金字塔, G n G_{n} Gn表示第n层高斯金字塔,则有:

L n = G n − P y r u p ( G n + 1 ) L_{n}=G_{n}-Pyrup(G_{n+1}) Ln=GnPyrup(Gn+1)

显然我们可以利用下面的公式重构第n层高斯金字塔图像:
G n ′ = L n + P y r u p ( G n + 1 ) G_{n}^{'} =L_{n}+Pyrup(G_{n+1}) Gn=Ln+Pyrup(Gn+1)

接下来上基于Python-OpenCV的示例代码,
该示例代码是对函数pyrDown()和pyrUp()的综合使用,
该示例代码先对图像进行高斯金字塔下采样处理,
再利用某一层的拉普拉普金字塔和高斯金字塔还原上一层图像。
代码写了详细的注释,大家应该能够很容易理解。

具体的代码请大家访问本博文的原文获取,
本博文的原文链接:

https://www.hhai.cc/thread-198-1-1.html

代码运行结果如下图所示:
图像金字塔、高斯金字塔、拉普拉斯金字塔是怎么回事?附利用拉普拉斯金字塔和高斯金字塔重构原图的Python-OpenCV代码_第4张图片
图像金字塔、高斯金字塔、拉普拉斯金字塔是怎么回事?附利用拉普拉斯金字塔和高斯金字塔重构原图的Python-OpenCV代码_第5张图片
从上面的结果中我们可以看出,利用某一层的高斯金字塔和拉普拉斯金字塔重构出的图像与原图相比在细节上(高频分量上)并没有多少缺失。

你可能感兴趣的:(图像处理原理,工具,代码,图像金字塔,高斯金字塔,拉普拉斯金字塔,图像重构)