(I)直線篇
1 直線是如何表示的?
對於平面中的一條直線,在笛卡爾座標系中,常見的有點斜式,兩點式兩種表示方法。然而在hough變換中,考慮的是另外一種表示方式:使用(r,theta)來表示一條直線。其中r爲該直線到原點的距離,theta爲該直線的垂線與x軸的夾角。如下圖所示。
使用hough變換來檢測直線的思想就是:爲每一個點假設n個方向的直線,通常n=180,此時檢測的直線的角度精度爲1°,分別計算這n條直線的(r,theta)座標,得到n個座標點。如果要判斷的點共有N個,最終得到的(r,theta)座標有N*n個。有關這N*n個(r,theta)座標,其中theta是離散的角度,共有180個取值。
最重要的地方來了,如果多個點在一條直線上,那麼必有這多個點在theta=某個值theta_i時,這多個點的r近似相等於r_i。也就是說這多個點都在直線(r_i,theta_i)上。
3 下面拿個例子說明:
通過 r0theta 座標系可以更直觀表示這種關係,如下圖:圖中三個點的(r,theta)曲線彙集在一起,該交點就是同時經過這三個點的直線。
在實際的直線檢測情況中,如果超過一定數目的點擁有相同的(r,theta)座標,那麼就可以判定此處有一條直線。在r0theta 座標系圖中,明顯的交匯點就標示一條檢測出的直線。
如下圖,可以判定出平面上的點共構成了兩條直線,即檢測出兩條直線。
4 代碼:
(II)圓篇
繼使用hough變換檢測出直線之後,順着座標變換的思路,提出了一種檢測圓的方法。
1 如何表示一個圓?
與使用(r,theta)來表示一條直線相似,使用(a,b,r)來確定一個圓心爲(a,b)半徑爲 r 的圓。
2 如何表示過某個點的所有圓?
某個圓過點(x1,y1),則有:(x1-a1)^2 + (y1-b1)^2 = r1^2 。
那麼過點(x1,y1)的所有圓可以表示爲(a1(i),b1(i),r1(i)),其中r1∈(0,無窮),每一個 i 值都對應一個不同的圓,(a1(i),b1(i),r1(i))表示了無窮多個過點(x1,y1)的圓。
3 如何確定多個點在同一個圓上?
如(2)中說明,過點(x1,y1)的所有圓可以表示爲(a1(i),b1(i),r1(i)),過點(x2,y2)的所有圓可以表示爲(a2(i),b2(i),r2(i)),過點(x3,y3)的所有圓可以表示爲(a3(i),b3(i),r3(i)),如果這三個點在同一個圓上,那麼存在一個值(a0,b0,r0),使得 a0 = a1(k)=a2(k)=a3(k) 且b0 = b1(k)=b2(k)=b3(k) 且r0 = r1(k)=r2(k)=r3(k),即這三個點同時在圓(a0,b0,r0)上。
從下圖可以形象的看出:
三個圓錐面的交點A 既是同時過這三個點的圓。
4 怎樣用代碼實現檢測圓的過程?
上面的分析雖然很簡單,但是用代碼實現起來就麻煩了,首先過每一個點的(a(i),b(i),r(i))都有無窮多個,若是要檢測的點很多,要兩兩比較所有的(a,b,r)值是否相等實在是一個巨大的運算量。