天天看點

opencv練習14圖像金字塔

一般情況下,我們要處理是一副具有固定分辨率的圖像。但是有些情況下,我們需要對同一圖像的不同分辨率的子圖像進行處理。比如,我們要在一幅圖像中查找某個目标,比如臉,我們不知道目标在圖像中的尺寸大小。這種情況下,我們需要建立建立一組圖像,這些圖像是具有不同分辨率的原始圖像。我們把這組圖像叫做圖像金字塔(簡單來說就是同一圖像的不同分辨率的子圖集合)。如果我們把最大的圖像放在底部,最小的放在頂部,看起來像一座金字塔,故而得名圖像金字塔。有兩類圖像金字塔:高斯金字塔和拉普拉斯金字塔。高斯金字塔的頂部是通過将底部圖像中的連續的行和列去除得到的。頂部圖像中的每個像素值等于下一層圖像中 5 個像素的高斯權重平均值。這樣操作一次一個 MxN 的圖像就變成了一個 M/2xN/2 的圖像。是以這幅圖像的面積就變為原來圖像面積的四分之一。這被稱為 Octave。連續進行這樣的操作我們就會得到一個分辨率不斷下降的圖像金字塔。我們可以使用函數cv2.pyrDown() 和 cv2.pyrUp() 建構圖像金字塔。函數 cv2.pyrDown() 從一個高分辨率大尺寸的圖像向上建構一個金子塔(尺寸變小,分辨率降低)。

img = cv2.imread('messi5.jpg')
lower_reso = cv2.pyrDown(higher_reso)      

下圖是一個四層的圖像金字塔。

opencv練習14圖像金字塔

函數 cv2.pyrUp() 從一個低分辨率小尺寸的圖像向下建構一個金子塔(尺寸變大,但分辨率不會增加)。

opencv練習14圖像金字塔

拉普拉斯金字塔可以有高斯金字塔計算得來,公式如下:Li = Gi − PyrU p (Gi+1)

拉普拉金字塔的圖像看起來就像邊界圖,其中很多像素都是 0。他們經常被用在圖像壓縮中。下圖就是一個三層的拉普拉斯金字塔:

opencv練習14圖像金字塔

.2 使用金字塔進行圖像融合

圖像金字塔的一個應用是圖像融合。例如,在圖像縫合中,你需要将兩幅圖疊在一起,但是由于連接配接區域圖像像素的不連續性,整幅圖的效果看起來會很差。這時圖像金字塔就可以排上用場了,他可以幫你實作無縫連接配接。這裡的一個經典案例就是将兩個水果融合成一個,看看下圖也許你就明白我在講什麼了。

opencv練習14圖像金字塔
opencv練習14圖像金字塔
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
#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]
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)      

繼續閱讀