參考:圖像金字塔
:【OpenCV入門】第十五彈:圖像金字塔
通常情況下,我們使用的是固定大小的圖像,但在某種情況下,我們需要處理不同分辨率的圖像。例如。在人臉識別中,我們是無法確定人臉在圖像中的大小的。這種情況下,我們需要創建一組具備不同分辨率的相同圖像集,並且在這個圖像集中搜索對象。這個具有不同分辨率的圖像集稱爲圖像金字塔。
個人感覺是像是圖像的縮放,在opencv中,關於圖像金字塔的操作,有pyrup(),pyrdown()操作,分別完成上採樣和下采樣。
有兩種金字塔,高斯金字塔和拉普拉斯金字塔。
高斯金字塔:用於下采樣,其中高階(低分辨率)是通過去除低階(高分辨率)圖像中連續的行和列而形成的。
cv.pyrDown()效果
高斯核:
爲了獲取第 G_i+1層圖像,我們採用下列方法:
對圖像下采樣:
- 對圖像G_i進行高斯內核卷積
- 將所有偶數行和列去除
結合上圖,可看到結果圖像只有原圖像的1/4。通過對輸入圖像G_i(原始圖像)不停迭代以上步驟就會得到整個金字塔。同時我們也可以看到,向下取樣會逐漸丟失圖像的信息。即,下采樣會縮小圖像
對圖像上採樣:
- 將圖像在每個方向擴大爲原來的兩倍,新增的行和列以0填充
- 使用先前同樣的內核**(乘以4)與放大後的圖像卷積,獲得 “新增像素”的近似值( **
得到的圖像即爲放大後的圖像,但是與原來的圖像相比會發覺比較模糊,因爲在縮放的過程中已經丟失了一些信息,如果想在縮小和放大整個過程中減少信息的丟失,這些數據形成了拉普拉斯金字塔。
import cv2
import numpy as np
import matplotlib.pyplot as plt
import pylab
pylab.rcParams['figure.figsize'] = (20.0, 10.0)
img = cv2.imread('E:/a1.png')
r1 = cv2.pyrDown(img)
r2 = cv2.pyrDown(r1)
r3 = cv2.pyrDown(r2)
print(img.shape)
print(r1.shape)
print(r2.shape)
plt.subplot(1,4,1),plt.imshow(img)
plt.title('img'),plt.xticks([]),plt.yticks([])
plt.subplot(1,4,2),plt.imshow(r1)
plt.title('r1'),plt.xticks([]),plt.yticks([])
plt.subplot(1,4,3),plt.imshow(r2)
plt.title('r2'),plt.xticks([]),plt.yticks([])
plt.subplot(1,4,4),plt.imshow(r3)
plt.title('r3'),plt.xticks([]),plt.yticks([])
plt.show()
##輸出結果
(923, 1443, 3)
(462, 722, 3)
(231, 361, 3)
(116, 181, 3)
輸出結果:
可看到分辨率依次爲1/4的關係。
pyrDown()原理與pyrUp()原理
import cv2
import numpy as np
import matplotlib.pyplot as plt
import pylab
img_1 = np.random.randint(0,10,size=100,dtype=np.uint8)#數據類型要注意
img_1 = img_1.reshape(10,10)
print(img_1)
kernel = np.array([[1,4,6,4,1],
[4,16,24,16,4],
[6,24,36,24,6],
[4,16,24,16,4],
[1,4,6,4,1]])
kernel = kernel/256
dst = cv2.filter2D(img_1,-1,kernel) #與高斯核卷積
print(dst)
dst_2 = np.zeros((5,5),dtype=np.uint8)
for i in range(10): #除去偶數行和偶數列
if i%2 == 0:
for j in range(10):
if j%2 == 0:
dst_2[int(i/2),int(j/2)] = dst[i,j]
print(dst_2)
dst_3 = np.zeros((10,10),dtype=np.uint8)
for i in range(10): #偶數行和偶數列插0
if i%2 == 0:
for j in range(10):
if j%2 == 0:
dst_3[i,j] = dst_2[int(i/2),int(j/2)]
print(dst_3)
注意,PryUp和PryDown不是互逆的。得到的圖像即爲放大後的圖像,但是與原來的圖像相比會發覺比較模糊,因爲在縮放的過程中已經丟失了一些信息,如果想在縮小和放大整個過程中減少信息的丟失,這些數據形成了拉普拉斯金字塔。