天天看點

c語言霍夫變換圓檢測,Hough Transform(霍夫變換)檢測Circle(圓)的幾種方法

比如檢測直線中,直線方程y = k * x + b  ,   直線上的所有點都對應着參數( k , b),

給定一個點(x0 , y0)我們能夠得到通過這個點的所有直線的參數(k , b),易知同一條直線上的點對應的參數(k , b)是相同的

利用此資訊,我們建立k , b 的累加器,依次計算圖像中提取出的邊界點,計算每個點可能對應的k , b 把相應的累加器項加一

最後求出累加器中的局部峰值,若峰值大于給定的門檻值就得到一條(k , b)所确定的直線。

為了便于計算我們可以使用直線公式:

P = x *cos(thea) + y * sin(thea) ;

P :圖像左上角(原點)到直線的距離

thea:原點到直線的垂線和X軸正向的夾角(沿着順時針方向)

注意:圖像中X軸從左向右增加Y軸從上向下增加

檢測圓也使用相同的原理:

圓的公式為:

x = x0 + r * cos(thea) ;

y = y0 + r*sin(thea) ;

1、标準霍夫變換:

标準霍夫變換需要把點(x ,y )投射到三維空間内(x0 , y0 , r)  , 是以累加器需要很大的空間,運算量巨大,不适用實時性的要求。

2、随機霍夫變換

随機選擇三個點,三個點可以确定一個圓實作多對一,減少了記憶體的消耗 ,節約了大量時間

步驟:

1、構造邊緣點集D ,初始化參數連結清單P= NULL ,循環控制k = 0

2、 從D中随機選擇三個點d1 , d2 , d3

3、計算由d1 , d2 , d3 三點确定的圓 ,若能确定一個圓  參數為p ,轉第4步 ;否則轉

4、檢查連結清單P,若有一項||pc-p|| < 給定的最小誤差,轉6;否則,轉5

5、把p插傳入連結表,其值value 置1

6、把pc 的value值加1 , 若小于門檻值轉7 ; 否則,轉8

7、k = k + 1  ,若k > Kmax,退出,否則轉2

8、pc作為候選圓參數,若其确定的圓上對應的邊界點數 > 最小值Votes ,則pc所确定的為真圓 , 轉9 ;否則,為假圓,把pc從連結清單P中剔除 , 轉2 ;

9、判定已經檢測到的圓是否達到規定數目,若是,退出,否則 , 将落在pc對應圓上的點從D中剔除 , P置空 , k = 0 ,轉2 ;

3、随機霍夫變換的改進

利用提取邊界時得到的梯度資訊檢測圓 ,方法二中利用随機的三個點确定的圓有許多是假圓,這造成了許多無效的累積,增長了連結清單,多消耗了記憶體。使用梯度資訊進一步增加準确性,減少無效累積,縮短了連結清單。

1、建構邊緣點集D及梯度資訊,  參數連結清單P= NULL, 循環控制 k = 0 ;

2、随機從D中選取兩個點(x0 , y0 ) , (x1 , y1)

3、計算兩點梯度方向分别和兩點連線的中垂線的交點(x3 , y3) , (x4 ,y4)

判斷兩點是否重合(注意誤差),重合就算參數p,轉4 ,否則 , 轉7

4、在P中尋找滿足||pc-p|| < 指定誤差 ,轉6  , 否則,轉5

5、把p 插傳入連結表P中,其Value置1

6、把pc對應的value加1 , 若大于門檻值,轉8 ,否則,轉7

7、 k = k + 1 ,若k > Kmax ,程式退出,否則轉2

8、pc 所确定的圓作為候選圓 , 候選圓上對應的點 > 指定的最小點數,轉9 ; 否則,為假圓 , 從P中出去pc ,轉2

9、pc 為真圓,看檢測的圓數目是否達到要求, 若是,退出; 否則,把pc圓上對應的點從D中剔除,P置NULL, k = 0 ,轉2