OpenCV單應(yīng)性矩陣發(fā)現(xiàn)參數(shù)估算方法詳解
點(diǎn)擊上方“小白學(xué)視覺(jué)”,選擇加"星標(biāo)"或“置頂”
重磅干貨,第一時(shí)間送達(dá)
本文轉(zhuǎn)自:opencv學(xué)堂
OpenCV在通過(guò)特征描述子完成描述子匹配之后,會(huì)得到一些關(guān)鍵點(diǎn)對(duì),我們會(huì)把這些關(guān)鍵點(diǎn)對(duì)分別添加到兩個(gè)vector對(duì)象中,作為輸入?yún)?shù),調(diào)用單應(yīng)性矩陣發(fā)現(xiàn)函數(shù)來(lái)發(fā)現(xiàn)一個(gè)變換矩陣H,函數(shù) findHomography 就完成了這樣的功能,常見(jiàn)的調(diào)用代碼如下:
1//-- Localize the object
2std::vector<Point2f> obj_pts;
3std::vector<Point2f> scene_pts;
4for (size_t i = 0; i < goodMatches.size(); i++)
5{
6 //-- Get the keypoints from the good matches
7 obj_pts.push_back(keypoints_obj[goodMatches[i].queryIdx].pt);
8 scene_pts.push_back(keypoints_sence[goodMatches[i].trainIdx].pt);
9}
10Mat H = findHomography(obj_pts, scene_pts, RHO);有了變換矩陣H之后,我們就可以根據(jù)輸入圖像四點(diǎn)坐標(biāo),從場(chǎng)景圖像上得到特征匹配圖像的四點(diǎn)坐標(biāo),代碼實(shí)現(xiàn)如下:
1//-- Get the corners from the image_1 ( the object to be "detected" )
2std::vector<Point2f> obj_corners(4);
3obj_corners[0] = Point(0, 0); obj_corners[1] = Point(box.cols, 0);
4obj_corners[2] = Point(box.cols, box.rows); obj_corners[3] = Point(0, box.rows);
5std::vector<Point2f> scene_corners(4);
6perspectiveTransform(obj_corners, scene_corners, H);其中scene_corners為對(duì)象在場(chǎng)景圖像中的四點(diǎn)坐標(biāo),獲得坐標(biāo)以后就可以繪制對(duì)應(yīng)的矩形,從而在場(chǎng)景圖像中繪制對(duì)象的外接矩形區(qū)域。運(yùn)行結(jié)果如下:

上述步驟中最重要的就是單應(yīng)性矩陣H的計(jì)算,這里我們首先來(lái)看一下該函數(shù)與其各個(gè)參數(shù)解釋?zhuān)?/p>
1Mat cv::findHomography (
2 InputArray srcPoints,
3 InputArray dstPoints,
4 int method = 0,
5 double ransacReprojThreshold = 3,
6 OutputArray mask = noArray(),
7 const int maxIters = 2000,
8 const double confidence = 0.995
9)
參數(shù)解釋如下:
srcPoints:特征點(diǎn)集合,一般是來(lái)自目標(biāo)圖像
dstPoints:特征點(diǎn)集合,一般是來(lái)自場(chǎng)景圖像
method:表示使用哪種配準(zhǔn)方法,支持有四種方法(后續(xù)詳細(xì)說(shuō))
0 – 使用所有的點(diǎn),比如最小二乘
RANSAC – 基于隨機(jī)樣本一致性
LMEDS – 最小中值
RHO –基于漸近樣本一致性
ransacReprojThreshold:該參數(shù)只有在method參數(shù)為RANSAC與RHO的時(shí)啟用,默認(rèn)為3
mask:遮罩,當(dāng)method方法為RANSAC 或 LMEDS可用
maxIters:最大迭代次數(shù),當(dāng)使用RANSAC方法
confidence:置信參數(shù),默認(rèn)為0.995
首先簡(jiǎn)單的解釋一下H的作用,假設(shè)在特征匹配或者對(duì)齊,視頻移動(dòng)估算中有兩張圖像image1與image2,image1上有特征點(diǎn)(x1,y1)匹配image2上的特征點(diǎn)(x2,y2),現(xiàn)在我們需要在兩者之間建立一種視圖變換關(guān)系(透視變換),圖示如下(圖二):

其中H是一個(gè)3x3的矩陣
這樣為了求出H中的參數(shù),需要兩個(gè)點(diǎn)對(duì)集合,就是findHomography函數(shù)中前兩個(gè)輸入?yún)?shù),理想情況下,通過(guò)特征提取得到特征點(diǎn)會(huì)再下一幀或者場(chǎng)景圖像中保持不變,但是實(shí)際情況下,收到各種因素的影響,會(huì)額外產(chǎn)生很多特征點(diǎn)或者干擾點(diǎn),如果正確的剔除這些干擾點(diǎn),得到正確匹配的點(diǎn),利用正確匹配點(diǎn)計(jì)算出H才是比較穩(wěn)定的方式。
01
最小二乘擬合
很明顯,圖二所示的是一個(gè)過(guò)約束問(wèn)題,如果沒(méi)有干擾點(diǎn)的話(huà),就可以通過(guò)最小二乘進(jìn)行直接擬合,求的參數(shù),其中錯(cuò)誤計(jì)算如下:

基于過(guò)約束方程計(jì)算得到錯(cuò)誤,反向傳播不斷更新參數(shù),直到兩次錯(cuò)誤差值滿(mǎn)足要求閾值為止。
02
RANSAC
最小二乘方法在描述子匹配輸出的點(diǎn)對(duì)質(zhì)量很好,理想情況下是圖像沒(méi)有噪聲污染與像素遷移與光線恒定,但是實(shí)際情況下圖像特別容易受到光線、噪聲導(dǎo)致像素遷移,從而產(chǎn)生額外的多余描述子匹配,這些點(diǎn)對(duì)可以分為outlier跟inlier兩類(lèi),基于RANSAC(Random Sample Consensus)可以很好的過(guò)濾掉outlier點(diǎn)對(duì),使用合法的點(diǎn)對(duì)得到最終的變換矩陣H。RANSAC算法基本思想是,它會(huì)從給定的數(shù)據(jù)中隨機(jī)選取一部分進(jìn)行模型參數(shù)計(jì)算,然后使用全部點(diǎn)對(duì)進(jìn)行計(jì)算結(jié)果評(píng)價(jià),不斷迭代,直到選取的數(shù)據(jù)計(jì)算出來(lái)的錯(cuò)誤是最小,比如低于0.5%即可,完整的算法流程步驟如下:
選擇求解模型要求的最少要求的隨機(jī)點(diǎn)對(duì)
根據(jù)選擇隨機(jī)點(diǎn)對(duì)求解/擬合模型得到參數(shù)
根據(jù)模型參數(shù),對(duì)所有點(diǎn)對(duì)做評(píng)估,分為outlier跟inlier
如果所有inlier的數(shù)目超過(guò)預(yù)定義的閾值,則使用所有inlier重新評(píng)估模型參數(shù),停止迭代
如果不符合條件則繼續(xù)1~4循環(huán)。
通常迭代次數(shù)N會(huì)選擇一個(gè)比較高的值,OpenCV中默認(rèn)迭代次數(shù)為200,確保有一個(gè)隨機(jī)選擇點(diǎn)對(duì)不會(huì)有outlier數(shù)據(jù),
03
PROSAC(RHO)
注意有時(shí)候RANSAC方法不會(huì)收斂,導(dǎo)致圖像對(duì)齊或者配準(zhǔn)失敗,原因在于RANSAC是一種全隨機(jī)的數(shù)據(jù)選取方式,完全沒(méi)有考慮到數(shù)據(jù)質(zhì)量不同。對(duì)RANSAC算法的改進(jìn)算法就是PROSAC(Progressive Sampling Consensus)即漸近樣本一致性,該方法采用半隨機(jī)方法,對(duì)所有點(diǎn)對(duì)進(jìn)行質(zhì)量評(píng)價(jià)計(jì)算Q值,然后根據(jù)Q值降序排列,每次只在高質(zhì)量點(diǎn)對(duì)中經(jīng)驗(yàn)?zāi)P图僭O(shè)與驗(yàn)證,這樣就大大降低了計(jì)算量,在RANSAC無(wú)法收斂的情況下,PROSAC依然可以取得良好的結(jié)果。OpenCV中的RHO方法就是基于PROSAC估算。
04
LMEDS
最小中值方法擬合,該方法可以看成是最小二乘法的改進(jìn),原因在于計(jì)算機(jī)視覺(jué)的輸入數(shù)據(jù)是圖像,一般都是各自噪聲,這種情況下最小二乘往往無(wú)法正確擬合數(shù)據(jù),所以采用最小中值方法可以更好實(shí)現(xiàn)擬合,排除outlier數(shù)據(jù)。但是它是對(duì)高斯噪聲敏感算法。它的最主要步驟描述如下:
隨機(jī)選取很多個(gè)子集從整個(gè)數(shù)據(jù)集中
根據(jù)各個(gè)子集數(shù)據(jù)計(jì)算參數(shù)模型
使用計(jì)算出來(lái)的參數(shù)對(duì)整個(gè)數(shù)據(jù)集計(jì)算中值平方殘差
最終最小殘差所對(duì)應(yīng)的參數(shù)即為擬合參數(shù)。
05
對(duì)比測(cè)試
最后看一下OpenCV中使用單應(yīng)性矩陣發(fā)現(xiàn)對(duì)相同的特征點(diǎn)對(duì),分別使用RANSAC、PROSAC、LMEDS進(jìn)行參數(shù)矩陣H的求解結(jié)果對(duì)比,顯示如下:

總數(shù)446個(gè)匹配點(diǎn)對(duì),三種評(píng)估方式生成的H矩陣(3x3)很明顯值都不盡相同。
一般情況下在,推薦大家使用RANSAC或者RHO。默認(rèn)的0表示最小二乘方法,對(duì)圖像匹配在實(shí)際應(yīng)用中一般都是翻車(chē)!LMEDS方法只有在inlier超過(guò)50%以上情況下才會(huì)擬合生成比較好的H參數(shù),而RANSAC或者RHO不管outlier跟inlier比率是多少都會(huì)可以適用,可以大家也都注意到h33總是等于1,因?yàn)閔33在這里作用是保持標(biāo)準(zhǔn)化尺度。在OpenCV中如果無(wú)法正確估算參數(shù)H,會(huì)返回空Mat對(duì)象。
圖像透視變換與對(duì)象匹配

圖像拼接

交流群
歡迎加入公眾號(hào)讀者群一起和同行交流,目前有SLAM、三維視覺(jué)、傳感器、自動(dòng)駕駛、計(jì)算攝影、檢測(cè)、分割、識(shí)別、醫(yī)學(xué)影像、GAN、算法競(jìng)賽等微信群(以后會(huì)逐漸細(xì)分),請(qǐng)掃描下面微信號(hào)加群,備注:”昵稱(chēng)+學(xué)校/公司+研究方向“,例如:”張三 + 上海交大 + 視覺(jué)SLAM“。請(qǐng)按照格式備注,否則不予通過(guò)。添加成功后會(huì)根據(jù)研究方向邀請(qǐng)進(jìn)入相關(guān)微信群。請(qǐng)勿在群內(nèi)發(fā)送廣告,否則會(huì)請(qǐng)出群,謝謝理解~

