隨機抽樣一致性算法(RANSAC)示例及源代碼作者:王先榮 大約在兩年前翻譯了《隨機抽樣一致性算法RANSAC》,在文章的最后承諾寫該算法的C#示例程序。可惜光陰似箭,轉(zhuǎn)眼許久才寫出來,實在抱歉。本文將使用隨機抽樣一致性算法來來檢測直線和圓,并提供源代碼下載。 一、RANSAC檢測流程 在這里復述下RANSAC的檢測流程,詳細的過程見上一篇翻譯文章: RANSAC算法的輸入是一組觀測數(shù)據(jù),一個可以解釋或者適應于觀測數(shù)據(jù)的參數(shù)化模型,一些可信的參數(shù)。 RANSAC通過反復選擇數(shù)據(jù)中的一組隨機子集來達成目標。被選取的子集被假設為局內(nèi)點,并用下述方法進行驗證: 二、得到觀測數(shù)據(jù) 我們沒有實驗(測試)數(shù)據(jù),這里用手工輸入的數(shù)據(jù)來替代——記錄您在PictureBox中的點擊坐標,作為觀測數(shù)據(jù)。 ![]()
三、檢測直線 3.1 直線的相關知識 (1)平面上的任意兩點可以確定一條直線; (2)直線的通用數(shù)學表達形式為:ax+by+c=0。這種表達形式有三個未知數(shù),需要提供三個點才能解出a,b,c三個參數(shù)。由于隨機選擇的三個點不一定在一條直線上,所以程序中放棄這種方式。 (3)直線可以用y=ax+b及x=c這兩個式子來表示。這兩種形式只有一個或者兩個未知數(shù),只需兩個點就能解出a,b,c三個參數(shù)。隨機選擇的兩個點即可得到直線,我們采用這種形式。 3.2 直線類 直線類(Line)封裝了跟直線相關的一些屬性及方法,列表如下: (1)屬性 A——y=ax+b中的a B——y=ax+b中的b C——x=c中的c (2)構(gòu)造函數(shù) public Line(PointF p1, PointF p2) 提供兩個點p1及p2,計算出直線的屬性A,B,C。 (3)方法 GetDistance——獲取點到直線之間的距離; GetY——根據(jù)x坐標,獲取直線上點的y坐標; ToString——獲取直線的方程式。 ![]()
3.3 檢測直線的過程 (1)隨機從觀測點中選擇兩個點,得到通過該點的直線; (2)用(1)中的直線去測試其他觀測點,由點到直線的距離確定觀測點是否為局內(nèi)點或者局外點; (3)如果局內(nèi)點足夠多,并且局內(nèi)點多于原有“最佳”直線的局內(nèi)點,那么將這次迭代的直線設為“最佳”直線; (4)重復(1)~(3)步直到找到最佳直線。 細心的您估計已經(jīng)發(fā)現(xiàn)我省略了標準RANSAC檢測過程中重新估計模型的步驟,我是故意的,我覺得麻煩且沒什么用處,所以咔嚓了,O(∩_∩)O~。 ![]() 四、檢測圓 4.1 圓的相關知識 (1)平面內(nèi)不在同一直線上的三個點可以確定一個圓; (2)圓的數(shù)學表達形式為:(x-a)2+(y-b)2=r2 其中,(a,b)為圓心,r為半徑。 4.2 圓類 圓類(Circle)封裝了跟圓有關的屬性及方法,列表如下: (1)屬性 A——圓心的x坐標 B——圓心的y坐標 R——圓的半徑 (2)構(gòu)造函數(shù) public Circle(PointF p1, PointF p2, PointF p3) 提供三個點p1,p2和p3,計算出圓的屬性A,B,R。 (3)方法 GetDistance——獲取點到圓(周)之間的距離,表示點接近或者遠離圓; ToString——獲取圓的方程式。 ![]()
3.3 檢測圓的過程 (1)隨機從觀測點中選擇三個點,嘗試得到通過這三個點的圓; (2)用(1)中的圓去測試其他觀測點,由點到圓的距離確定觀測點是否為局內(nèi)點或者局外點; (3)如果局內(nèi)點足夠多,并且局內(nèi)點多于原有“最佳”圓的局內(nèi)點,那么將這次迭代的圓設為“最佳”圓; (4)重復(1)~(3)步直到找到最佳圓。 ![]() 五、本文源代碼 感謝您閱讀本文,希望對您有所幫助。 標簽: RANSAC 隨機抽樣一致性算法 |
|