图像金字塔介绍
- 图像金字塔是多尺度表达的一种,是一种以多分辨率来解释图像的有效但概念简单的结构。。一幅图像的金字塔是一系列以金字塔形状排列的分辨率逐渐降低并且来源于同一张原始图像的集合。通过梯次向下采样获得,直到某个终止条件才停止采样。
- 图像金字塔说白了就是披着金字塔外衣的图像缩放。一般有高斯图像金字塔、拉普拉斯图像金字塔。
两种金字塔介绍
高斯金字塔(低通)
高斯金字塔:用于下采样
。高斯金字塔是最基本的图像塔。
原理:首先将原图像作为最底层图像G0(高斯金字塔的第0层),利用高斯核(5*5)对其进行卷积(高斯平滑),然后对卷积后的图像进行下采样(去除偶数行和列)得到上一层图像G1,将此图像作为输入,重复卷积和下采样操作得到更上一层图像,反复迭代多次,形成一个金字塔形的图像数据结构,即高斯金字塔。
由于上采样和下采样是非线性处理,是不可逆的有损处理,因此下采样后的图像想要还原回原来的尺寸的话会丢失很多信息,使图片变模糊。
上图就是使用高斯金字塔之后的结果。
拉普拉斯金字塔(带通金字塔)
拉普拉斯金字塔:用于重建图像,也就是预测残差,对图像进行最大程度的还原
。
一幅小图像重建为一幅大图原理:用高斯金字塔的每一层图像减去其上一层图像上采样并高斯卷积之后的预测图像,得到一系列的差值图像即为 LP 分解图像。
拉普拉斯金字塔实际上是通过计算图片先下采样再上采样后的结果和原图片的残差来保存缺失信息的,公式为:L(i)=G(i)−PyrUp(G(i+1))L(i) = G(i) - PyrUp(G(i + 1))L(i)=G(i)−PyrUp(G(i+1))
也就是说,拉普拉斯金字塔实际上是由上面的残差图片组成的金字塔,它为还原图片做准备。
求得每个图像的拉普拉斯金字塔后需要对相应层次的图像进行融合,最终还原图像。
拉普拉斯金字塔可以精确还原图片信息。
还原图像的过程就是重构的过程。
上图能够比较好的理解拉普拉斯金字塔的计算过程。
图像金字塔应用
图像金字塔非常重要的一个应用就是实现图像分割。图像分割的话,先要建立一个图像金字塔,然后在Gi和Gi+1的像素直接依照对应的关系,建立起”父与子“关系。而快速初始分割可以先在金字塔高层的低分辨率图像上完成,然后逐层对分割加以优化。
实例1 高斯金字塔和拉普拉斯金字塔显示:
代码:
import cv2 as cv
def pyramid_demo(image):level = 3 temp = image.copy() pyramid_images = [] for i in range(level):dst = cv.pyrDown(temp) pyramid_images.append(dst) cv.imshow("pyramid"+str(i+1), dst)temp = dst.copy()return pyramid_images
def lapalian_demo(image):pyramid_images &#61; pyramid_demo(image) level &#61; len(pyramid_images)for i in range(level-1, -1, -1):if (i-1) < 0:expand &#61; cv.pyrUp(pyramid_images[i], dstsize &#61; image.shape[:2])lpls &#61; cv.subtract(image, expand)cv.imshow("lapalian_down_"&#43;str(i&#43;1), lpls)else:expand &#61; cv.pyrUp(pyramid_images[i], dstsize &#61; pyramid_images[i-1].shape[:2])lpls &#61; cv.subtract(pyramid_images[i-1], expand)cv.imshow("lapalian_down_"&#43;str(i&#43;1), lpls)
src &#61; cv.imread(&#39;F:/test.jpg&#39;)
cv.namedWindow(&#39;input_image&#39;)
cv.imshow(&#39;input_image&#39;, src)
lapalian_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()
显示结果&#xff1a;
高斯金字塔&#xff1a;
拉普拉斯金字塔&#xff1a;
融合
图像融合的目的就是使两幅图像的重叠区域过渡自然且平滑。
常见融合方法&#xff1a;
- 1&#xff09;加权平均法。这个很好理解&#xff0c;即简单的使用加权的方式从左边过渡到右边。这种方法效果一般&#xff0c;但算法实现极其简单&#xff0c;速度快。
- 2&#xff09;羽化算法 。这种方法过渡会比加权平均法自然&#xff0c;但会造成不好的模糊效果。
- 3&#xff09;拉普拉斯金字塔融合。有的地方也称为多分辨率融合算法。这种方法是将图像建立一个拉普拉斯金字塔&#xff0c;其中金字塔的每一层都包含了图像不同的频段。分开不同频段进行融合效果出奇的好。
图像拉普拉斯金字塔分解的目的是将源图像分别分解到不同的空间频带上&#xff0c;融合过程是在各空间频率层上分别进行的&#xff0c;这样就可以针对不同分解层的不同频带上的特征与细节&#xff0c;采用不同的融合算子以达到突出特定频带上特征与细节的目的。即有可能将来自不同图像的特征与细节融合在一起。
实例2&#xff1a;利用拉普拉斯金字塔实现融合
代码&#xff1a;
import cv2
import numpy as np,sys
A &#61; cv2.imread(&#39;F:/ninny.jpg&#39;)
B &#61; cv2.imread(&#39;F:/nero.jpg&#39;)
G &#61; A.copy()
gpA &#61; [G]
for i in range(6):G &#61; cv2.pyrDown(G)gpA.append(G)
G &#61; B.copy()
gpB &#61; [G]
for i in range(6):G &#61; cv2.pyrDown(G)gpB.append(G)
lpA &#61; [gpA[5]]
for i in range(5,0,-1):GE &#61; cv2.pyrUp(gpA[i])L &#61; cv2.subtract(gpA[i-1],GE)lpA.append(L)
lpB &#61; [gpB[5]]
for i in range(5,0,-1):GE &#61; cv2.pyrUp(gpB[i])L &#61; cv2.subtract(gpB[i-1],GE)lpB.append(L)
LS &#61; []
for la,lb in zip(lpA,lpB):rows,cols,dpt &#61; la.shapels &#61; np.hstack((la[:,:cols//2], lb[:,cols//2:]))LS.append(ls)
ls_ &#61; LS[0]
for i in range(1,6):ls_ &#61; cv2.pyrUp(ls_)ls_ &#61; cv2.add(ls_, LS[i])
real &#61; np.hstack((A[:,:cols//2],B[:,cols//2:]))
cv2.imwrite(&#39;F:/ninny_nero.jpg&#39;,ls_)
cv2.imwrite(&#39;F:/nini_chaochao.jpg&#39;,real)
结果&#xff1a;
使用拉普拉斯融合后的图片&#xff1a;
直接拼接的照片&#xff1a;
问题和解决&#xff1a;
- 金字塔输入的图像大小必须是2的n次方。
- 调试程序的时候遇到这个报错&#xff1a;
File "H:/pycharm_pro/pyramid/pyr.py", line 39, in ls &#61; np.hstack((la[:, :cols / 4], lb[:, cols // 4: cols//2], la[:, cols//2:3 * cols//4], lb[:, 3*cols//4: ]))
TypeError: slice indices must be integers or None or have an __index__ method
因为单纯的使用除法得到的可能不是整数&#xff0c;但是在索引过程中必须要使用整数索引&#xff0c;所以只取整数部分即可。