Python圖像處理之圖像拼接
一、前言
圖像拼接技術就是將數張有重疊部分的圖像(可能是不同時間、不同視角或者不同傳感器獲得的)拼成一幅無縫的全景圖或高分辨率圖像的技術。
二、特征點匹配
特征點具有局部差異性
動機:特征點具有局部差異性
圖像梯度
Harris矩陣
以每個點為中心取一個窗口,窗口大小為55或者77,如果這個點具有差異性,往周圍任意方向移動,周圍的環境變化都是會比較大的,如果滿足這個特性,我們就認為這個特征點具有明顯的局部差異性。在工事中,I表示像素,如果是 彩色圖像就是RGB,灰色圖像就是灰度。(u,v)表示方向。然後對上式進行一階泰勒展開。
Harris矩陣H的特征值分析:
矩陣特征值反應瞭兩個垂直方向的變化情況,一個事變化最快的方向,一個事變化最慢的方向
興趣點位於光滑區域,不是特征點
興趣點位於邊緣區域
興趣點位於角點區域
所以檢測特征的任務轉化為計算Harris矩陣,判斷特征值大小。
在實際操作中,很少通過計算特征值來判斷,因為計算特征值計算量比較大,取而代之的是Harris角點準則。
三、匹配錯誤的特征點幹擾
在進行圖像匹配過程中,如果圖像的噪聲太大,就會使得特征點的匹配發生瞭偏差,匹配到瞭錯誤的點,這種不好的匹配效果,會對後面的圖像拼接產生很大的影響,如下圖
四、消除幹擾
為瞭進一步提升匹配精度,可以采用隨機樣本一致性(RANSAC)方法。
因為我們是使用一幅圖像(一個平面物體),我們可以將它定義為剛性的,可以在pattern image和query image的特征點之間找到單應性變換(homography transformation )。使用cv::findHomography找到這個單應性變換,使用RANSAC找到最佳單應性矩陣。(由於這個函數使用的特征點同時包含正確和錯誤匹配點,因此計算的單應性矩陣依賴於二次投影的準確性)
五、RANSAC進行圖像匹配
RANSAC是“RANdom SAmple Consensus(隨機抽樣一致)”的縮寫。它可以從一組包含“局外點”的觀測數據集中,通過迭代方式估計數學模型的參數。它是一種不確定的算法——它有一定的概率得出一個合理的結果;為瞭提高概率必須提高迭代次數。
RANSAC的基本假設是:
(1)數據由“局內點”組成,例如:數據的分佈可以用一些模型參數來解釋;
(2)“局外點”是不能適應該模型的數據;
(3)除此之外的數據屬於噪聲。
局外點產生的原因有:噪聲的極值;錯誤的測量方法;對數據的錯誤假設。
RANSAC也做瞭以下假設:給定一組(通常很小的)局內點,存在一個可以估計模型參數的過程;而該模型能夠解釋或者適用於局內點。
RANSAC原理
OpenCV中濾除誤匹配對采用RANSAC算法尋找一個最佳單應性矩陣H,矩陣大小為3×3。RANSAC目的是找到最優的參數矩陣使得滿足該矩陣的數據點個數最多,通常令h3=1來歸一化矩陣。由於單應性矩陣有8個未知參數,至少需要8個線性方程求解,對應到點位置信息上,一組點對可以列出兩個方程,則至少包含4組匹配點對。
其中(x,y)表示目標圖像角點位置,(x’,y’)為場景圖像角點位置,s為尺度參數。
RANSAC算法從匹配數據集中隨機抽出4個樣本並保證這4個樣本之間不共線,計算出單應性矩陣,然後利用這個模型測試所有數據,並計算滿足這個模型數據點的個數與投影誤差(即代價函數),若此模型為最優模型,則對應的代價函數最小。
RANSAC算法步驟:
1.隨機從數據集中隨機抽出4個樣本數據 (此4個樣本之間不能共線),計算出單應矩陣H,記為模型M;
2.計算數據集中所有數據與模型M的投影誤差,若誤差小於閾值,加入內點集 I ;
3.如果當前內點集 I 元素個數大於最優內點集 I_best , 則更新 I_best = I,同時更新迭代次數k ;
4.如果迭代次數大於k,則退出 ; 否則迭代次數加1,並重復上述步驟;
註:迭代次數k在不大於最大迭代次數的情況下,是在不斷更新而不是固定的;
其中,p為置信度,一般取0.995;w為”內點”的比例 ; m為計算模型所需要的最少樣本數=4;
使用RANSAC圖片匹配
from numpy import * from matplotlib.pyplot import * from PIL import Image import warp import homography from PCV.localdescriptors import sift featname = ['img/' + str(i + 1) + '.sift' for i in range(5)] imname = ['img/' + str(i + 1) + '.jpg' for i in range(5)] 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]) # visualize the matches (Figure 3-11 in the book) 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 elsewhere fp = 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 2 fp, tp = convert_points(0) H_01 = homography.H_from_ransac(fp, tp, model)[0] # im 0 to 1 tp, fp = convert_points(2) # NB: reverse order H_32 = homography.H_from_ransac(fp, tp, model)[0] # im 3 to 2 tp, fp = convert_points(3) # NB: reverse order H_43 = homography.H_from_ransac(fp, tp, model)[0] # im 4 to 3 # 扭曲圖像 delta = 100 # 用於填充和平移 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圖像處理之圖像拼接的文章就介紹到這瞭,更多相關Python圖像拼接內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- 基於Python和openCV實現圖像的全景拼接詳細步驟
- OpenCV-Python 實現兩張圖片自動拼接成全景圖
- python圖像處理基本操作總結(PIL庫、Matplotlib及Numpy)
- 如何基於python實現單目三維重建詳解
- python opencv實現圖像配準與比較