python+opencv图像金字塔融合 (超详细讲解原理及代码讲解)

本篇内容参考《Opencv官方教程中文版(Python)》的内容进行讲解和分析,其下载网址为 http://download.csdn.net/download/dengxf01/9692646

由于书中代码所使用版本问题,所以,不少读者将其代码复制后,运行时出现错误,在这里我将以Python3.6.1,Opencv 3.2版本进行代码展示和讲解。

图像金字塔主要涉及两个函数:cv2.pyrUp()(图像尺寸变小),cv2.pyrDown()(图像尺寸变大,但会模糊)

图像金字塔有两类类型:高斯金字塔和拉普拉斯金字塔。

高斯金字塔的顶部是通过将底部图像中的连续的行和列去除得到的。顶部图像中的每个像素值等于下一层图像中 5 个像素的高斯加权平均值。这样操作一次一个 MxN 的图像就变成了一个 M/2xN/2 的图像。所谓的5个元素是指:前后左右+自身。下图为高斯金字塔cv2.pyrUp() 的效果

python+opencv图像金字塔融合 (超详细讲解原理及代码讲解)_第1张图片

高斯金字塔将小图变大图用,cv2.pyrDown(),但是图像会模糊,如下图,从小图变大后的图像

python+opencv图像金字塔融合 (超详细讲解原理及代码讲解)_第2张图片

对于拉普拉斯金字塔,其计算公式与高斯金字塔相关,具体为

Li=Gi-pyrUp(Gi+1), 其中i和i+1为下角标

拉普拉斯金字塔的图像效果为:

python+opencv图像金字塔融合 (超详细讲解原理及代码讲解)_第3张图片

图像融合的两个重要作用为:

1.实现两个图像的无缝连接,下面用苹果和橘子的例子说明

2.图像压缩,从苹果和橘子的例子中,读者可以体会如何利用小图像(被高斯金字塔变换后的图像)和几层拉普拉斯金字塔表示大图像信息(拉普拉斯金字塔即使图像很大,由于大部分为黑色,可认为是0,因此压缩后数量很小)

苹果和橘子的例子的原始图像和融合后效果如图所示:

python+opencv图像金字塔融合 (超详细讲解原理及代码讲解)_第4张图片

对于读者,实施苹果和橘子的数据准备阶段:

苹果和橘子的图片,但是要注意!!!!!!!!!!!由于程序采用六层金字塔,一次其图片像素的行数和列数要能够被(2X2X2X2X2X2)整除哦,否则计算过程中像素矩阵对不上就麻烦了。

程序:

import cv2
import numpy as np
A = cv2.imread('apple.jpg')
B = cv2.imread('orange.jpg')
# generate Gaussian pyramid for A
G = A.copy()
gpA = [G]
for i in np.arange(6):     #将苹果进行高斯金字塔处理,总共六级处理
    G = cv2.pyrDown(G)
    gpA.append(G)
# generate Gaussian pyramid for B
G = B.copy()
gpB = [G]
for i in np.arange(6):  # #将橘子进行高斯金字塔处理,总共六级处理
    G = cv2.pyrDown(G)
    gpB.append(G)
# generate Laplacian Pyramid for A
lpA = [gpA[5]]               
for i in np.arange(5,0,-1):    #将苹果进行拉普拉斯金字塔处理,总共5级处理
    GE = cv2.pyrUp(gpA[i])
    L = cv2.subtract(gpA[i-1],GE)
    lpA.append(L)
# generate Laplacian Pyramid for B
lpB = [gpB[5]]
for i in np.arange(5,0,-1):    #将橘子进行拉普拉斯金字塔处理,总共5级处理
    GE = cv2.pyrUp(gpB[i])
    L = cv2.subtract(gpB[i-1],GE)
    lpB.append(L)
# Now add left and right halves of images in each level
#numpy.hstack(tup)
#Take a sequence of arrays and stack them horizontally
#to make a single array.
LS = []
for la,lb in zip(lpA,lpB):
    rows,cols,dpt = la.shape
    ls = np.hstack((la[:,0:cols//2], lb[:,cols//2:]))    #将两个图像的矩阵的左半部分和右半部分拼接到一起
    LS.append(ls)
# now reconstruct
ls_ = LS[0]   #这里LS[0]为高斯金字塔的最小图片
for i in xrange(1,6):                        #第一次循环的图像为高斯金字塔的最小图片,依次通过拉普拉斯金字塔恢复到大图像
    ls_ = cv2.pyrUp(ls_)
    ls_ = cv2.add(ls_, LS[i])                #采用金字塔拼接方法的图像
# image with direct connecting each half
real = np.hstack((A[:,:cols/2],B[:,cols/2:]))   #直接的拼接
cv2.imwrite('Pyramid_blending2.jpg',ls_)
cv2.imwrite('Direct_blending.jpg',real)

对于读者进行程序调试时,可通过cv2.imshow()和cv2.waitKey()函数进行查看各个过程的输出。


完!




你可能感兴趣的:(python+opencv图像金字塔融合 (超详细讲解原理及代码讲解))