當初選方向時就由於從小几何就很差、缺少空間想像能力纔沒有選擇攝影測量方向而是選擇了GIS。昨天同窗找我幫他作圖像匹配,這我哪裏懂啊,無奈我是一個別人有求於我,老是很差意思開口拒絕的人。因而乎就看着他給的一章節內容開始寫程序了,今天總算給他完成了。作的比較簡單,中間也遇到了很多問題,尤爲是計算量大的問題,因爲老師給的數據是粗配準過的數據, RANSAC算法評估時就簡化了下。算法
理論內容:dom
第5章 圖像配準創建幾何變換模型優化
特徵點創建匹配關係以後,下一步就是求解圖像之間的變換關係。仿射變換可以很好的表達圖像之間的通常變換,而且最少只須要3對匹配點就能夠求解。因爲以前用的匹配算法不能保證沒有誤匹配(其實是存在誤匹配的),本文將採用RANSAC方法來估計兩幅圖像之間的仿射變換關係。若是有足夠多的圖像特徵匹配符合某一個特定的仿射變換,則咱們認爲當前匹配滿意,反之,咱們進行下一次估計。spa
5.1 RANSAC算法code
RANSAC(RandomSample Consensus),即隨機採樣一致算法,準確來講是一種從一組包含噪聲的觀測數據中經過迭代的方式估計出數據所知足的某個數學模型的參數的算法。由Fischler和Bolles於1981年提出,是目前普遍使用的一種剔除誤匹配點的方法。orm
5.2 仿射變換blog
仿射變換(Affine Transform)是一種仿射平面到自身的變換,它可以保持點的共線性(Parallelism,即保持二維圖形之間相對位置關係不變,平行還是平行,相交直線的交角不變)和直線的平行性(Straightness,即變換後圓弧仍是圓弧,直線仍是直線)。仿射變換是配準中最經常使用的一類轉換模型,在幾何學中有專門的仿射幾何分支,並將仿射變換被當作一個平行的投影鏈。圖片
仿射變換可用以個三乘三的矩陣表示,最後一行爲(0,0,1)。該變換矩陣將原座標(x,y)變爲(x`,y`)。ip
變換矩陣爲:get
咱們在空間幾何信息檢驗中,認爲若是兩幅圖像描述的是同一個物體或場景,因爲圖片大小,位置和角度的不一樣,兩幅圖像中相應的興趣點的位置信息應該知足某一個仿射變換關係。所以,咱們以兩幅圖像之間的特徵匹配做爲數據來估計仿射變換矩陣,若是能找到一個足夠多特徵匹配都服從的仿射變換,則認爲當前匹配讓人滿意。
5.3 RANSAC仿射變換空間檢驗
空間檢驗就是經過RANSAC算法,根據圖像之間的特徵匹配信息,估計出一個仿射變換模型。
咱們用下式來表示仿射變換矩陣
其中m1,m2,m3,m4體現尺度和旋轉特性,tx是x方向上的平移,ty是y方向上的平移。
則一對匹配點的座標能夠寫成
或者寫成
其中,(x,y)是變換前,(u,v)是變換後的座標。
爲了解求仿射變換參數,對上式作一下變形:
可寫成A*x=b,則模型參數x的值
要解六個參數,至少須要三對特徵匹配,所以RANSAC隨機採樣每次須要三對數據來估計仿射變換矩陣。
介紹完相關概念和理論,下面是RANSAC空間幾何信息檢驗的流程:
1. 數據準備:找到兩幅圖像(I1和I2)之間的匹配點對和座標信息。
2. 模型估計:假設有n>3對的匹配點對,隨機選取3對,根據公式解求仿射變換模型參數m1,m2,m3,m4,tx,ty。
3. 模型評估:對圖像I1中全部的已匹配的點(x,y)作上述仿射變換,獲得一系列變換後的座標(u`,v`)。將這些獲得的座標和I2中對應的匹配點(u,v)求歐氏距離,即仿射變換的估計偏差E。並用I2中相應特徵點的尺度信息作歸一化,這樣每個特徵匹配能夠求出一個歸一化的估計偏差,最終獲得一個估計偏差向量。
4. 根據估計偏差向量肯定一個偏差閾值T(該怎麼肯定閾值?),估計偏差向量中低於T的對應的特徵匹配爲Inliers。
5. 若是Inliers數目大於目前最大的Inliers數目,則當作找到了當前最好的放射變換,保存此變換(我看到網上說要對其作局部優化,將全部知足當前最好的仿射變換的Inliers匹配點對,從新作母性估計和模型評估並保存仿射變換信息。通常說來,通過局部優化的新放射變換一般會有更多Inliers,是什麼意思啊?)
6. 重複2到6步驟,最終獲得的仿射變換認爲是I1和I2之間最好的放射變換模型。
這裏記錄下作的流程:
(1)推導六參數計算公式,編寫仿射變換六參數類(因爲以前沒有檢查數據,數據中有幾組重複的,致使一直報「嘗試除以零」這個錯誤);
代碼以下:
/* * 求解仿射變換模型參數的類 * @ 劉碩編制 */ using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ImageMatching { class ParameterHelper { public int[] X_Cor { get; set; } public int[] Y_Cor { get; set; } public int[] U_Cor { get; set; } public int[] V_Cor { get; set; } //仿射變換模型六參數 public double m1 { get { return ((U_Cor[1] - U_Cor[0]) - m2 * (Y_Cor[1] - Y_Cor[0])) / (X_Cor[1] - X_Cor[0]); } } public double m2 { get { return ((U_Cor[1] - U_Cor[0])*(X_Cor[2] - X_Cor[0]) - (U_Cor[2] - U_Cor[0])*(X_Cor[1] - X_Cor[0])) / ((Y_Cor[1] - Y_Cor[0])*(X_Cor[2] - X_Cor[0]) - (Y_Cor[2]- Y_Cor[0])*(X_Cor[1] - X_Cor[0])); } } public double m3 { get { return ((V_Cor[1] - V_Cor[0]) - m4 * (Y_Cor[1] - Y_Cor[0])) / (X_Cor[1] - X_Cor[0]); } } public double m4 { get { return ((V_Cor[1] - V_Cor[0]) * (X_Cor[2] - X_Cor[0]) - (V_Cor[2] - V_Cor[0]) * (X_Cor[1] - X_Cor[0])) / ((Y_Cor[1] - Y_Cor[0]) * (X_Cor[2] - X_Cor[0]) - (Y_Cor[2] - Y_Cor[0]) * (X_Cor[1] - X_Cor[0])); } } public double tx { get { return U_Cor[0] - m1 * X_Cor[0] - m2 * Y_Cor[0]; } } public double ty { get { return V_Cor[0] - m3 * X_Cor[0] - m4 * Y_Cor[0]; } } } }(2 )對全部匹配點計算組合數,按RANSAC隨機採樣每次須要三對數據來估計仿射變換矩陣,則共有(C n 3 *C n 3)種組合狀況,計算量至關大。
(3)求解完仿射變換模型六參數後,則要進行模型評估。即計算歸一化偏差,獲得歸一化偏差向量。
(4)肯定閾值,計算Inliers數。這裏參照論文,閾值取全部歸一化偏差的均值(按說應該取自適應閾值,奈何不懂啊)。
(5)比較全部組合的Inliers數,獲得最優仿射變換,並保存。
(6)輸出仿射變換六參數及匹配後坐標
歡迎留言拍磚!