Python计算机视觉(三)—— 全景图像拼接
文章目錄
- 一、創建全景圖
- 1.1 圖像拼接整體流程
- 1.2 RANSAC算法
- 1.3 圖像配準
- 1.4 圖割方法
- 1.5 圖像融合
- 1.6 APAP算法
- 1.7 multi-band bleing算法
- 二、代碼
一、創建全景圖
同一位置(即圖像的照相機位置相同)拍攝的兩幅或者多幅圖像是單應性相關的。
我們經常使用該約束將很多圖像縫補起來,拼成一個大的圖像來創建全景圖。
1.1 圖像拼接整體流程
- 根據給定圖像/集,實現特征匹配
- 通過匹配特征計算圖像之間的變換結構
- 利用圖像變換結構,實現圖像映射
- 針對疊加后的圖像,采用APAP之類的算法,對齊特征點
- 通過圖割方法,自動選取拼接縫
- 根據multi-band blending策略實現融合
1.2 RANSAC算法
RANSAC(隨機抽樣一致)是一種迭代算法,該算法從一組包含“外點(outlier)”的觀測數據中估計數學模型的參數。“外點”指觀測數據中的無效數據,通常為噪聲或錯誤數據,比如圖像匹配中的誤匹配點和曲線擬合中的離群點。與“外點”相對應的是“內點(inlier)”,即用來估計模型參數的有效數據。因此,RANSAC也是一種“外點”檢測算法。此外,RANSAC算法是一種非確定算法,它只能在一定概率下產生可信的結果,當迭代次數增加時,準確的概率也會增加。
RANSAC算法是用來找到正確模型來擬合帶有噪聲數據的迭代方法。
基本思想:數據中包含正確的點和噪聲點,合理的模型應該能夠在描述正確數據點的同時擯棄噪聲點。
RANSAC流程如下:
隨機采樣K個點,K是求解模型參數的最少點個數;
使用K個點估計模型參數;
計算剩余點到估計模型的距離,距離小于閾值則為內點,統計內點的數目;
重復步驟1~3,重復次數M且保留數目最多的內點;
使用所有的內點重新估計模型。
1.3 圖像配準
圖像配準是對圖像進行變換,使變換后的圖像能夠在常見的坐標系中對齊。為了能夠進行圖像對比和更精細的圖像分析,圖像配準是一步非常重要的操作。圖像配準的方法有很多,這里以APAP算法為例:
1.提取兩張圖片的sift特征點
2.對兩張圖片的特征點進行匹配
3.匹配后,仍有很多錯誤點,此時用RANSAC進行特征點對的篩選。篩選后的特征點基本能夠一一對應。
4.使用DLT算法,將剩下的特征點對進行透視變換矩陣的估計。
5.因為得到的透視變換矩陣是基于全局特征點對進行的,即一個剛性的單應性矩陣完成配準。為提高配準的精度,APAP將圖像切割成無數多個小方塊,對每個小方塊的變換矩陣逐一估計。
1.4 圖割方法
最大流最小割算法原理,
1.最小割問題
一個有向圖,并有一個源頂點(source vertex)和目標頂點(target vertex).邊的權值為正,又稱之為容量(capacity)。如下圖
一個st-cut(簡稱割cut)會把有向圖的頂點分成兩個不相交的集合,其中s在一個集合中,t在另外一個集合中。
這個割的容量(capacity of the cut)就是A到B所有邊的容量和。注意這里不包含B到A的。最小割問題就是要找到割容量最小的情況。
2.最大流問題
跟最小割問題類似,最大流問題要處理的情況也是一個有向圖,并有一個原頂點(source vertex)和目標(target vertex),邊的權值為正,又稱之為容量(capacity)。
(1)初始化,所有邊的flow都初始化為0。
(2)沿著增廣路徑增加flow。增廣路徑是一條從s到t的無向路徑,但也有些條件,可以經過沒有滿容量的前向路徑(s到t)或者是不為空的反向路徑(t->s)。
1.5 圖像融合
圖像拼接之后可以發現,在拼接的交界處有明顯的銜接痕跡,存在邊緣效應,因為光照色澤的原因使得圖片交界處的過渡很糟糕,所以需要特定的處理解決這種不自然。那么這時候可以采用blending方法。multi-band blending是目前圖像融和方面比較好的方法。
原理:
1.建立兩幅圖像的拉普拉斯金字塔
2.求高斯金字塔(掩模金字塔-為了拼接左右兩幅圖像)因為其具有尺度不變性
3. 進行拼接blendLapPyrs() ; 在每一層上將左右laplacian圖像直接拼起來得結果金字塔resultLapPyr
4.重建圖像: 從最高層結果圖
將左右laplacian圖像拼成的resultLapPyr金字塔中每一層,從上到下插值放大并和下一層相加,即得blend圖像結果(reconstructImgFromLapPyramid)
且我們可以將拉普拉斯金字塔理解為高斯金字塔的逆形式。
1.6 APAP算法
在圖像拼接融合的過程中,受客觀因素的影響,拼接融合后的圖像可能會存在“鬼影現象”以及圖像間過度不連續等問題。下圖就是圖像拼接的一種“鬼影現象”。
解決鬼影現象可以采用APAP算法。
算法流程:
1.SIFT得到兩幅圖像的匹配點對
2.通過RANSAC剔除外點,得到N對內點
3.利用DLT和SVD計算全局單應性
4.將源圖劃分網格,取網格中心點,計算每個中心點和源圖上內點之間的歐式距離和權重
5.將權重放到DLT算法的A矩陣中,構建成新的W*A矩陣,重新SVD分解,自然就得到了當前網格的局部單應性矩陣
6.遍歷每個網格,利用局部單應性矩陣映射到全景畫布上,就得到了APAP變換后的源圖
7.最后就是進行拼接線的加權融合
APAP雖然能夠較好地完成配準,但非常依賴于特征點對。若圖像高頻信息較少,特征點對過少,配準將完全失效,并且對大尺度的圖像進行配準,其效果也不是很好,一切都決定于特征點對的數量。
1.7 multi-band bleing算法
在找完拼接縫后,由于圖像噪聲、光照、曝光度、模型匹配誤差等因素,直接進行圖像合成會在圖像重疊區域的拼接處出現比較明顯的邊痕跡。
這些邊痕跡需要使用圖像融合算法來消除。multi-band bleing算法便可解決問題
multi-band bleing算法思想:
采用的方法是直接對帶拼接的兩個圖片進行拉普拉斯金字塔分解,后一半對前一半進行融合
步驟:
首先計算當前待拼接圖像和已合成圖像的重疊部分。并對圖像A、B 重疊部分進行高斯金字塔和拉普拉斯金字塔分解
G0為原始圖像,G1表示對G0做reduce操作。Reduce操作定義如下:
Gl(i,j)=∑∑m,n=15w(m,n)Gl?1(2i+m,2j+n)G_l(i,j) = \sum\sum^5_{m,n=1}w(m,n)G_{l-1}(2i+m, 2j+n) Gl?(i,j)=∑m,n=1∑5?w(m,n)Gl?1?(2i+m,2j+n)
對G1進行擴展后與G0相減,可以得到拉普拉斯金字塔的第一層L0。同理,拉普拉斯金字塔的L2、L3等層也可以按照這種方法來計算。
兩幅圖像的融合過程:分別構建圖像A、B的高斯金字塔和拉普拉斯金字塔,然后進行加權融合。
對加權后的拉普拉斯金字塔進行重構
二、代碼
from pylab import * from numpy import * from PIL import Image# If you have PCV installed, these imports should work from PCV.geometry import homography, warp from PCV.localdescriptors import sift np.seterr(invalid='ignore') """ This is the panorama example from section 3.3. """# 設置數據文件夾的路徑 # F:\PyCharm 2021.2.1\project\ComputerVision\ImageMap\img featname = ['img/joint/' + str(i + 1) + '.sift' for i in range(5)] imname = ['img/joint/' + str(i + 1) + '.jpg' for i in range(5)]# 提取特征并匹配使用sift算法 l = {} d = {} for i in range(5):sift.process_image(imname[i], featname[i])l[i], d[i] = sift.read_features_from_file(featname[i])matches = {} for i in range(4):matches[i] = sift.match(d[i + 1], d[i])# 可視化匹配 for i in range(4):im1 = array(Image.open(imname[i]))im2 = array(Image.open(imname[i + 1]))figure()sift.plot_matches(im2, im1, l[i + 1], l[i], matches[i], show_below=True)# 將匹配轉換成齊次坐標點的函數 def convert_points(j):ndx = matches[j].nonzero()[0]fp = homography.make_homog(l[j + 1][ndx, :2].T)ndx2 = [int(matches[j][i]) for i in ndx]tp = homography.make_homog(l[j][ndx2, :2].T)# switch x and y - TODO this should move elsewherefp = vstack([fp[1], fp[0], fp[2]])tp = vstack([tp[1], tp[0], tp[2]])return fp, tp# 估計單應性矩陣 model = homography.RansacModel()fp, tp = convert_points(1) H_12 = homography.H_from_ransac(fp, tp, model)[0] # im 1 to 2fp, tp = convert_points(0) H_01 = homography.H_from_ransac(fp, tp, model)[0] # im 0 to 1tp, fp = convert_points(2) # NB: reverse order H_32 = homography.H_from_ransac(fp, tp, model)[0] # im 3 to 2tp, fp = convert_points(3) # NB: reverse order H_43 = homography.H_from_ransac(fp, tp, model)[0] # im 4 to 3# 扭曲圖像 delta = 2000 # for padding and translation用于填充和平移im1 = array(Image.open(imname[1]), "uint8") im2 = array(Image.open(imname[2]), "uint8") im_12 = warp.panorama(H_12, im1, im2, delta, delta)im1 = array(Image.open(imname[0]), "f") im_02 = warp.panorama(dot(H_12, H_01), im1, im_12, delta, delta)im1 = array(Image.open(imname[3]), "f") im_32 = warp.panorama(H_32, im1, im_02, delta, delta)im1 = array(Image.open(imname[4]), "f") im_42 = warp.panorama(dot(H_32, H_43), im1, im_32, delta, 2 * delta)figure() imshow(array(im_42, "uint8")) axis('off') show()效果展示:
原照片集:
全景拼接效果:
總結
以上是生活随笔為你收集整理的Python计算机视觉(三)—— 全景图像拼接的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【BLE】CC2541之SNV
- 下一篇: 利用好模拟器