在二值影象中如何檢測圓
進演算法。最基本的霍夫變換是從黑白影象中檢測直線(線段)。
我們先看這樣一個問題:設已知一黑白影象上畫了一條直線,要求出這條直線所在的位置
。我們知道,直線的方程可以用y=k*x+b 來表示,其中k和b是引數,分別是斜率和截距。過某一點
(x0,y0)的所有直線的引數都會滿足方程y0=kx0+b。即點(x0,y0)確定了一族直線。方程y0=kx0+b在
引數k--b平面上是一條直線,(你也可以是方程b=-x0*k+y0對應的直線)。這樣,影象x--y平面上的
一個前景畫素點就對應到引數平面上的一條直線。我們舉個例子說明解決前面那個問題的原理。設
影象上的直線是y=x, 我們先取上面的三個點:A(0,0), B(1,1), C(22)。可以求出,過A點的直線
的引數要滿足方程b=0, 過B點的直線的引數要滿足方程1=k+b, 過C點的直線的引數要滿足方程
2=2k+b, 這三個方程就對應著引數平面上的三條直線,而這三條直線會相交於一點(k=1,b=0)。 同
理,原影象上直線y=x上的其它點(如(3,3),(4,4)等) 對應引數平面上的直線也會通過點(k=1,b=0)
。這個性質就為我們解決問題提供了方法:
首先,我們初始化一塊緩衝區,對應於引數平面,將其所有資料置為0.
對於影象上每一前景點,求出引數平面對應的直線,把這直線上的所有點的值都加1。
最後,找到引數平面上最大點的位置,這個位置就是原影象上直線的引數。
上面就是霍夫變換的基本思想。就是把影象平面上的點對應到引數平面上的線,最後通過
統計特性來解決問題。假如影象平面上有兩條直線,那麼最終在引數平面上就會看到兩個峰值點,
依此類推。
在實際應用中,y=k*x+b形式的直線方程沒有辦法表示x=c形式的直線(這時候,直線的斜
率為無窮大)。所以實際應用中,是採用引數方程p=x*cos(theta)+y*sin(theta)。這樣,影象平面
上的一個點就對應到引數p---theta平面上的一條曲線上。其它的還是一樣。
在看下面一個問題:我們要從一副影象中檢測出半徑以知的圓形來。這個問題比前一個還
要直觀。我們可以取和影象平面一樣的引數平面,以影象上每一個前景點為圓心,以已知的半徑在
引數平面上畫圓,並把結果進行累加。最後找出引數平面上的峰值點,這個位置就對應了影象上的
圓心。在這個問題裡,影象平面上的每一點對應到引數平面上的一個圓。
把上面的問題改一下,假如我們不知道半徑的值,而要找出影象上的圓來。這樣,一個辦
法是把引數平面擴大稱為三維空間。就是說,引數空間變為x--y--R三維,對應圓的圓心和半徑。
影象平面上的每一點就對應於引數空間中每個半徑下的一個圓,這實際上是一個圓錐。最後當然還
是找引數空間中的峰值點。不過,這個方法顯然需要大量的記憶體,執行速度也會是很大問題。
有什麼更好的方法麼?我們前面假定的影象都是黑白影象(2值影象),實際上這些2值影象
多是彩色或灰度影象通過邊緣提取來的。我們前面提到過,影象邊緣除了位置資訊,還有方向資訊
也很重要,這裡就用上了。根據圓的性質,圓的半徑一定在垂直於圓的切線的直線上,也就是說,
在圓上任意一點的法線上。這樣,解決上面的問題,我們仍採用2維的引數空間,對於影象上的每
一前景點,加上它的方向資訊,都可以確定出一條直線,圓的圓心就在這條直線上。這樣一來,問
題就會簡單了許多。
接下來還有許多類似的問題,如檢測出橢圓,正方形,長方形,圓弧等等。這些方法大都
類似,關鍵就是需要熟悉這些幾何形狀的數學性質。霍夫變換的應用是很廣泛的,比如我們要做一
個支票識別的任務,假設支票上肯定有一個紅顏色的方形印章,我們可以通過霍夫變換來對這個印
章進行快速定位,在配合其它手段進行其它處理。霍夫變換由於不受影象旋轉的影響,所以很容易
的可以用來進行定位。
霍夫變換有許多改進方法,一個比較重要的概念是廣義霍夫變換,它是針對所有曲線的,
用處也很大。就是針對直線的霍夫變換也有很多改進演算法,比如前面的方法我們沒有考慮影象上的
這一直線上的點是否連續的問題,這些都要隨著應用的不同而有優化的方法。
順便說一句,搞影象處理這一行,在理論方面,有幾本雜誌是要看的,自然是英文雜誌,
中文期刊好象沒有專門的影象處理期刊,當然也有不少涉及這方面的期刊,但事實求是來說,的確
比英文雜誌水平差很多。
‘IEEE Transactions on Pattern And Machine Intelligence’
‘IEEE Transactions on Image Processing’
是最重要的兩本,其它的如ICIP等的會議文章也非常好。不過,要不想很偏理論,
這些玩藝兒也沒什麼要看的。