某些情况下,我们需要处理同一图像的不同分辨率的图像。例如,当搜索图像中的某个对象(如人脸)时,我们不确定该对象在图像中的大小。在这种情况下,我们需要创建一组具有不同分辨率的图像,并在所有图像中搜索对象。这些具有不同分辨率的图像集称为图像金字塔(因为当它们被放在一个底部图像最大、顶部图像最小的堆栈中时,看起来像金字塔)。
有两种图像金字塔,高斯金字塔 和 拉普拉斯金字塔。
高斯金字塔中的高阶(低分辨率)是通过删除低阶(高分辨率)图像中的连续行和列而形成的。然后,在高一级中的每一个像素都是由5个像素的高斯权重贡献形成的。这样,m 乘以 n的图像变成 m/2 乘以 n/2 的图像。所以面积减少到原来面积的四分之一。我们可以使用cv2.pyrdown() 和 cv2.pyrup() 函数找到高斯金字塔。
img = cv2.imread('messi5.jpg')
lower_reso = cv2.pyrDown(higher_reso)

现在可以使用 cv2.pyrup() 函数沿着图像金字塔向下移动。
higher_reso2 = cv2.pyrUp(lower_reso)
一旦降低分辨率,就会释放信息。下图是从前面的最小图像创建的金字塔向下3层。将其与原始图像进行比较:

拉普拉斯金字塔是由高斯金字塔形成的。拉普拉斯金字塔图像只是边缘图像。它的大部分元素都是零。它们用于图像压缩。拉普拉斯金字塔中的一个层次是由高斯金字塔中的这个层次与其在高斯金字塔中上层的扩展版本之间的差异形成的。拉普拉斯层面的三个层面如下(对比度调整以增强内容):

使用金字塔对图像混合
金字塔的一个应用是图像混合。例如,在图像拼接中,需要将两个图像堆叠在一起,但由于图像之间的不连续性,可能看起来不太好。在这种情况下,图像与棱锥体的混合可以让您无缝地混合,而不会在图像中留下太多数据。其中一个经典的例子是两种水果,橘子和苹果的混合。

简单来说,它是如下所示:
1、加载苹果和橘子的两个图像
2、找到苹果和橘子的高斯金字塔(在本例中,级别数为6)
3、从高斯金字塔找到拉普拉斯金字塔
4、现在把苹果的左半部分和橘子的右半部分连接到拉普拉斯金字塔的每一层。
5、最后从这个联合图像金字塔,重建原始图像。
以下是完整代码。(为了简单起见,每一步都是单独完成的,这可能需要更多的内存。如果你愿意的话,你可以优化它)。
import cv2
import numpy as np,sys
A = cv2.imread('apple.jpg')
B = cv2.imread('orange.jpg')
# generate Gaussian pyramid for A
G = A.copy()
gpA = [G]
for i in xrange(6):
G = cv2.pyrDown(G)
gpA.append(G)
# generate Gaussian pyramid for B
G = B.copy()
gpB = [G]
for i in xrange(6):
G = cv2.pyrDown(G)
gpB.append(G)
# generate Laplacian Pyramid for A
lpA = [gpA[5]]
for i in xrange(5,0,-1):
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 xrange(5,0,-1):
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
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]
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)
网友评论