目錄
- 一、前言
- 二、特征點(diǎn)匹配
- 三、匹配錯(cuò)誤的特征點(diǎn)干擾
- 四、消除干擾
- 五、RANSAC進(jìn)行圖像匹配
- 六、總結(jié)
一、前言
圖像拼接技術(shù)就是將數(shù)張有重疊部分的圖像(可能是不同時(shí)間、不同視角或者不同傳感器獲得的)拼成一幅無(wú)縫的全景圖或高分辨率圖像的技術(shù)。
二、特征點(diǎn)匹配
特征點(diǎn)具有局部差異性
動(dòng)機(jī):特征點(diǎn)具有局部差異性
圖像梯度
Harris矩陣
以每個(gè)點(diǎn)為中心取一個(gè)窗口,窗口大小為55或者77,如果這個(gè)點(diǎn)具有差異性,往周?chē)我夥较蛞苿?dòng),周?chē)沫h(huán)境變化都是會(huì)比較大的,如果滿(mǎn)足這個(gè)特性,我們就認(rèn)為這個(gè)特征點(diǎn)具有明顯的局部差異性。在工事中,I表示像素,如果是 彩色圖像就是RGB,灰色圖像就是灰度。(u,v)表示方向。然后對(duì)上式進(jìn)行一階泰勒展開(kāi)。
Harris矩陣H的特征值分析:
矩陣特征值反應(yīng)了兩個(gè)垂直方向的變化情況,一個(gè)事變化最快的方向,一個(gè)事變化最慢的方向
興趣點(diǎn)位于光滑區(qū)域,不是特征點(diǎn)
興趣點(diǎn)位于邊緣區(qū)域
興趣點(diǎn)位于角點(diǎn)區(qū)域
所以檢測(cè)特征的任務(wù)轉(zhuǎn)化為計(jì)算Harris矩陣,判斷特征值大小。
在實(shí)際操作中,很少通過(guò)計(jì)算特征值來(lái)判斷,因?yàn)橛?jì)算特征值計(jì)算量比較大,取而代之的是Harris角點(diǎn)準(zhǔn)則。
三、匹配錯(cuò)誤的特征點(diǎn)干擾
在進(jìn)行圖像匹配過(guò)程中,如果圖像的噪聲太大,就會(huì)使得特征點(diǎn)的匹配發(fā)生了偏差,匹配到了錯(cuò)誤的點(diǎn),這種不好的匹配效果,會(huì)對(duì)后面的圖像拼接產(chǎn)生很大的影響,如下圖
四、消除干擾
為了進(jìn)一步提升匹配精度,可以采用隨機(jī)樣本一致性(RANSAC)方法。
因?yàn)槲覀兪鞘褂靡环鶊D像(一個(gè)平面物體),我們可以將它定義為剛性的,可以在pattern image和query image的特征點(diǎn)之間找到單應(yīng)性變換(homography transformation )。使用cv::findHomography找到這個(gè)單應(yīng)性變換,使用RANSAC找到最佳單應(yīng)性矩陣。(由于這個(gè)函數(shù)使用的特征點(diǎn)同時(shí)包含正確和錯(cuò)誤匹配點(diǎn),因此計(jì)算的單應(yīng)性矩陣依賴(lài)于二次投影的準(zhǔn)確性)
五、RANSAC進(jìn)行圖像匹配
RANSAC是“RANdom SAmple Consensus(隨機(jī)抽樣一致)”的縮寫(xiě)。它可以從一組包含“局外點(diǎn)”的觀測(cè)數(shù)據(jù)集中,通過(guò)迭代方式估計(jì)數(shù)學(xué)模型的參數(shù)。它是一種不確定的算法——它有一定的概率得出一個(gè)合理的結(jié)果;為了提高概率必須提高迭代次數(shù)。
RANSAC的基本假設(shè)是:
(1)數(shù)據(jù)由“局內(nèi)點(diǎn)”組成,例如:數(shù)據(jù)的分布可以用一些模型參數(shù)來(lái)解釋?zhuān)?br />
(2)“局外點(diǎn)”是不能適應(yīng)該模型的數(shù)據(jù);
(3)除此之外的數(shù)據(jù)屬于噪聲。
局外點(diǎn)產(chǎn)生的原因有:噪聲的極值;錯(cuò)誤的測(cè)量方法;對(duì)數(shù)據(jù)的錯(cuò)誤假設(shè)。
RANSAC也做了以下假設(shè):給定一組(通常很小的)局內(nèi)點(diǎn),存在一個(gè)可以估計(jì)模型參數(shù)的過(guò)程;而該模型能夠解釋或者適用于局內(nèi)點(diǎn)。
RANSAC原理
OpenCV中濾除誤匹配對(duì)采用RANSAC算法尋找一個(gè)最佳單應(yīng)性矩陣H,矩陣大小為3×3。RANSAC目的是找到最優(yōu)的參數(shù)矩陣使得滿(mǎn)足該矩陣的數(shù)據(jù)點(diǎn)個(gè)數(shù)最多,通常令h3=1來(lái)歸一化矩陣。由于單應(yīng)性矩陣有8個(gè)未知參數(shù),至少需要8個(gè)線性方程求解,對(duì)應(yīng)到點(diǎn)位置信息上,一組點(diǎn)對(duì)可以列出兩個(gè)方程,則至少包含4組匹配點(diǎn)對(duì)。
其中(x,y)表示目標(biāo)圖像角點(diǎn)位置,(x',y')為場(chǎng)景圖像角點(diǎn)位置,s為尺度參數(shù)。
RANSAC算法從匹配數(shù)據(jù)集中隨機(jī)抽出4個(gè)樣本并保證這4個(gè)樣本之間不共線,計(jì)算出單應(yīng)性矩陣,然后利用這個(gè)模型測(cè)試所有數(shù)據(jù),并計(jì)算滿(mǎn)足這個(gè)模型數(shù)據(jù)點(diǎn)的個(gè)數(shù)與投影誤差(即代價(jià)函數(shù)),若此模型為最優(yōu)模型,則對(duì)應(yīng)的代價(jià)函數(shù)最小。
RANSAC算法步驟:
1.隨機(jī)從數(shù)據(jù)集中隨機(jī)抽出4個(gè)樣本數(shù)據(jù) (此4個(gè)樣本之間不能共線),計(jì)算出單應(yīng)矩陣H,記為模型M;
2.計(jì)算數(shù)據(jù)集中所有數(shù)據(jù)與模型M的投影誤差,若誤差小于閾值,加入內(nèi)點(diǎn)集 I ;
3.如果當(dāng)前內(nèi)點(diǎn)集 I 元素個(gè)數(shù)大于最優(yōu)內(nèi)點(diǎn)集 I_best , 則更新 I_best = I,同時(shí)更新迭代次數(shù)k ;
4.如果迭代次數(shù)大于k,則退出 ; 否則迭代次數(shù)加1,并重復(fù)上述步驟;
注:迭代次數(shù)k在不大于最大迭代次數(shù)的情況下,是在不斷更新而不是固定的;
其中,p為置信度,一般取0.995;w為"內(nèi)點(diǎn)"的比例 ; m為計(jì)算模型所需要的最少樣本數(shù)=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)
# 將匹配轉(zhuǎn)換成齊次坐標(biāo)點(diǎn)的函數(shù)
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
# 估計(jì)單應(yīng)性矩陣
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()
進(jìn)行匹配的圖片
匹配后的圖片
六、總結(jié)
本次的拼接效果比較好,原因是因?yàn)槲以谕粫r(shí)刻差不多角度拍攝的照片,噪聲比較小,之前一組圖片拍攝的噪聲太大,導(dǎo)致最后出現(xiàn)不了結(jié)果。
由圖片這部分可得,在不同時(shí)刻下拍攝照片導(dǎo)致天空顏色不同,在拼接的時(shí)候也會(huì)有明顯的分割線。
在實(shí)驗(yàn)過(guò)程中,剛開(kāi)始使用了一組照片,但運(yùn)行不出結(jié)果,后來(lái)經(jīng)過(guò)查詢(xún)找到原因是因?yàn)閳D片匹配度太低,沒(méi)辦法進(jìn)行匹配,后來(lái)重新拍攝了一組圖片最終才完成。
到此這篇關(guān)于Python圖像處理之圖像拼接的文章就介紹到這了,更多相關(guān)Python圖像拼接內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
您可能感興趣的文章:- Python圖像處理之圖片拼接和堆疊案例教程
- python圖片灰度化處理的幾種方法
- Python圖片檢索之以圖搜圖
- python圖片合成的示例
- Python圖片處理之圖片裁剪教程
- 昨晚我用python幫隔壁小姐姐P證件照然后發(fā)現(xiàn)