图像金字塔 图像金字塔是同一图像不同分辨率的子图集合,是通过对原图像不断地下采样而产生的,即由高分辨率的图像(大尺寸)产生低分辨率的近似图像(小尺寸)。
导入基本软件包和库 1 2 3 import cv2import matplotlib.pyplot as pltimport numpy as np
读取图像 1 2 A = cv2.imread('apple.jpg' ) B = cv2.imread('orange.jpg' )
(360, 360, 3)
(360, 360, 3)
查看图像 1 2 3 4 5 plt.subplot(1 ,2 ,1 ) plt.imshow(A[:, :, ::-1 ]) plt.subplot(1 ,2 ,2 ) plt.imshow(B[:, :, ::-1 ]) plt.show()
图像拼接 1 cols, rows, channle = A.shape
1 res = np.hstack((A[:, :cols//2 ], B[:, cols//2 :]))
1 2 plt.imshow(res[:, :, ::-1 ]) plt.show()
下采样 1 2 img = cv2.imread('dog.jpg' ) img = cv2.resize(img, (460 , 460 ))
1 2 img1 = cv2.pyrDown(img) img2 = cv2.pyrDown(img1)
1 2 3 4 5 6 7 8 plt.figure(figsize=(30 , 10 )) plt.subplot(1 ,3 ,1 ) plt.imshow(img[:, :, ::-1 ]) plt.subplot(1 ,3 ,2 ) plt.imshow(img1[:, :, ::-1 ]) plt.subplot(1 ,3 ,3 ) plt.imshow(img2[:, :, ::-1 ]) plt.show()
1 2 3 print (img.shape)print (img1.shape)print (img2.shape)
(460, 460, 3)
(230, 230, 3)
(115, 115, 3)
上采样 1 2 image1 = cv2.pyrUp(img2) image2 = cv2.pyrUp(image1)
1 2 3 4 5 6 7 8 plt.figure(figsize=(30 , 10 )) plt.subplot(1 ,3 ,1 ) plt.imshow(img2[:, :, ::-1 ]) plt.subplot(1 ,3 ,2 ) plt.imshow(image1[:, :, ::-1 ]) plt.subplot(1 ,3 ,3 ) plt.imshow(image2[:, :, ::-1 ]) plt.show()
1 2 3 print (img2.shape)print (image1.shape)print (image2.shape)
(115, 115, 3)
(230, 230, 3)
(460, 460, 3)
采样可逆性研究 将下采样后的图像上采样回原来的像素大小,图像的清晰度没有还原,说明下采样和上采样不是互逆的,即使达到了同样的像素大小,但是像素值无法还原。
1 2 3 down = cv2.pyrDown(img) up = cv2.pyrUp(down) diff = img - up
1 2 print (img.shape)print (diff.shape)
(460, 460, 3)
(460, 460, 3)
1 2 3 4 5 6 7 8 plt.figure(figsize=(30 , 10 )) plt.subplot(1 ,3 ,1 ) plt.imshow(img[:, :, ::-1 ]) plt.subplot(1 ,3 ,2 ) plt.imshow(up[:, :, ::-1 ]) plt.subplot(1 ,3 ,3 ) plt.imshow(diff[:, :, ::-1 ]) plt.show()
1 2 3 up = cv2.pyrUp(img) down = cv2.pyrDown(up) diff = img - down
1 2 print (img.shape)print (diff.shape)
(460, 460, 3)
(460, 460, 3)
1 2 3 4 5 6 7 8 plt.figure(figsize=(30 , 10 )) plt.subplot(1 ,3 ,1 ) plt.imshow(img[:, :, ::-1 ]) plt.subplot(1 ,3 ,2 ) plt.imshow(down[:, :, ::-1 ]) plt.subplot(1 ,3 ,3 ) plt.imshow(diff[:, :, ::-1 ]) plt.show()
拉普拉斯金字塔 为了恢复原始图像就需要获取在采样中丢失的信息,这些丢失的信息被称为拉普拉斯金字塔
例如下采样2次构成的拉普拉斯金字塔和高斯金字塔如下
1 2 3 4 5 6 down1 = cv2.pyrDown(img) down2 = cv2.pyrDown(down1) up1 = cv2.pyrUp(down1) up2 = cv2.pyrUp(down2) diff1 = img - up1 diff2 = down1 - up2
高斯金字塔 1 2 3 4 5 6 7 8 plt.figure(figsize=(20 , 10 )) plt.subplot(1 ,3 ,1 ) plt.imshow(img[:, :, ::-1 ]) plt.subplot(1 ,3 ,2 ) plt.imshow(down1[:, :, ::-1 ]) plt.subplot(1 ,3 ,3 ) plt.imshow(down2[:, :, ::-1 ]) plt.show()
拉普拉斯金字塔 1 2 3 4 5 6 plt.figure(figsize=(10 , 5 )) plt.subplot(1 ,3 ,1 ) plt.imshow(diff1[:, :, ::-1 ]) plt.subplot(1 ,3 ,2 ) plt.imshow(diff2[:, :, ::-1 ]) plt.show()
使用拉普拉斯金字塔恢复分辨率 1 lp = cv2.pyrUp(down1) + diff1
1 2 plt.imshow(lp[:, :, ::-1 ]) plt.show()
1 lp = cv2.pyrUp(down2) + diff2
1 2 plt.imshow(lp[:, :, ::-1 ]) plt.show()
使用拉普拉斯平滑进行图像融合 图像金字塔的一个应用是图像融合。例如,在图像缝合中,你需要将两幅图叠在一起,但是由于连接区域图像像素的不连续性,整幅图的效果看起来会很差。这时图像金字塔就可以排上用场了,他可以帮你实现无缝连接。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 import cv2 as cvimport numpy as npA = cv2.imread('apple.jpg' ) A = cv2.resize(A,(256 ,256 )) B = cv2.imread('orange.jpg' ) B = cv2.resize(B,(256 ,256 )) G = A.copy() gpA = [G] for i in range (6 ): G = cv2.pyrDown(G) gpA.append(G) G = B.copy() gpB = [G] for i in range (6 ): G = cv2.pyrDown(G) gpB.append(G) lpA = [gpA[5 ]] for i in range (5 , 0 , -1 ): GE = cv2.pyrUp(gpA[i]) L = cv2.subtract(gpA[i-1 ], GE) lpA.append(L) lpB = [gpB[5 ]] for i in range (5 , 0 , -1 ): GE = cv2.pyrUp(gpB[i]) L = cv2.subtract(gpB[i-1 ], GE) lpB.append(L) LS = [] for la, lb in zip (lpA, lpB): rows, cols, dpt = la.shape ls = np.hstack((la[:, 0 :int (cols/2 )], lb[:, int (cols/2 ):])) LS.append(ls) ls_ = LS[0 ] for i in range (1 , 6 ): ls_ = cv2.pyrUp(ls_) ls_ = cv2.add(ls_, LS[i])
1 2 plt.imshow(ls_[:, :, ::-1 ]) plt.show()