1. 程式人生 > >Harris角點及Shi-Tomasi角點檢測(轉)

Harris角點及Shi-Tomasi角點檢測(轉)

wid fast 進度 -cp 成了 out gif 角點檢測 自定義

一、角點定義

有定義角點的幾段話:

1、角點檢測(Corner Detection)是計算機視覺系統中用來獲得圖像特征的一種方法,廣泛應用於運動檢測、圖像匹配、視頻跟蹤、三維建模和目標識別等領域中。也稱為特征點檢測。


角點通常被定義為兩條邊的交點,更嚴格的說,角點的局部鄰域應該具有兩個不同區域的不同方向的邊界。而實際應用中,大多數所謂的角點檢測方法檢測的是擁有特定特征的圖像點,而不僅僅是“角點”。這些特征點在圖像中有具體的坐標,並具有某些數學特征,如局部最大或最小灰度、某些梯度特征等。


現有的角點檢測算法並不是都十分的魯棒。很多方法都要求有大量的訓練集和冗余數據來防止或減少錯誤特征的出現。角點檢測方法的一個很重要的評價標準是其對多幅圖像中相同或相似特征的檢測能力,並且能夠應對光照變化、圖像旋轉等圖像變化。

2、在我們解決問題時,往往希望找到特征點,“特征”顧名思義,指能描述物體本質的東西,還有一種解釋就是這個特征微小的變化都會對物體的某一屬性產生重大的影響。而角點就是這樣的特征。


觀察日常生活中的“角落”就會發現,“角落”可以視為所有平面的交匯處,或者說是所有表面的發起處。假設我們要改變一個墻角的位置,那麽由它而出發的平面勢必都要有很大的變化。所以,這就引出了圖像角點的定義


“如果某一點在任意方向的一個微小變動都會引起灰度很大的變化,那麽我們就把它稱之為角點”

3、

特征檢測與匹配是Computer Vision 應用總重要的一部分,這需要尋找圖像之間的特征建立對應關系。點,也就是圖像中的特殊位置,是很常用的一類特征,點的局部特征也可以叫做“關鍵特征點”(keypoint feature

),或“興趣點”(interest point),或“角點”(conrner)。

關於角點的具體描述可以有幾種:

  • 一階導數(即灰度的梯度)的局部最大所對應的像素點;
  • 兩條及兩條以上邊緣的交點;
  • 圖像中梯度值和梯度方向的變化速率都很高的點;
  • 角點處的一階導數最大,二階導數為零,指示物體邊緣變化不連續的方向。

二、角點檢測算法

1、Moravec角點檢測算法

Moravec角點檢測算法是最早的角點檢測算法之一。該算法將角點定義為具有低“自相關性”的點。算法會檢測圖像的每一個像素,將像素周邊的一個鄰域作為一個patch,並檢測這個patch和周圍其他patch的相關性。這種相關性通過兩個patch間的平方差之和(SSD)來衡量,SSD值越小則相似性越高。


如果像素位於平滑圖像區域內,周圍的patch都會非常相似。如果像素在邊緣上,則周圍的patch在與邊緣正交的方向上會有很大差異,在與邊緣平行的方向上則較為相似。而如果像素是各個方向上都有變化的特征點,則周圍所有的patch都不會很相似。


Moravec會計算每個像素patch和周圍patch的SSD最小值作為強度值,取局部強度最大的點作為特征點。

2、Harris角點檢測

轉載:http://blog.csdn.net/xiaowei_cqu/article/details/7805206
源碼及資料下載: http://download.csdn.net/detail/xiaowei_cqu/4466627

當一個窗口在圖像上移動,在平滑區域如圖(a),窗口在各個方向上沒有變化。在邊緣上如圖(b),窗口在邊緣的方向上沒有變化。在角點處如圖(c),窗口在各個方向上具有變化。Harris角點檢測正是利用了這個直觀的物理現象,通過窗口在各個方向上的變化程度,決定是否為角點。

技術分享圖片

將圖像窗口平移[u,v]產生灰度變化E(u,v)

技術分享圖片

由:技術分享圖片, 得到:

技術分享圖片

對於局部微小的移動量 [u,v],近似表達為:

技術分享圖片

其中M是 2*2 矩陣,可由圖像的導數求得:

技術分享圖片

E(u,v)的橢圓形式如下圖:

技術分享圖片

定義角點響應函數 R 為:

技術分享圖片

Harris角點檢測算法就是對角點響應函數R進行閾值處理:R > threshold,即提取R的局部極大值。

【相關代碼】

OpenCV中定義了 cornerHarris 函數:

[cpp] view plaincopy
  1. voidint intdouble int borderType=BORDER_DEFAULT );

可以結合 convertScaleAbs 函數,通過閾值取角點:

[cpp] view plaincopy
  1. voidintvoid
  2. int int double
  3. forint forint ifintfloat
  4. }

另一篇對Harris的講解(http://www.cnblogs.com/ztfei/archive/2012/05/07/2487123.html)

觀察日常生活中的“角落”就會發現,“角落”可以視為所有平面的交匯處,或者說是所有表面的發起處。假設我們要改變一個墻角的位置,那麽由它而出發的平面勢必都要有很大的變化。所以,這就引出了圖像角點的定義

技術分享圖片,其中,I(x,y)表示像素的灰度值

技術分享圖片

技術分享圖片

技術分享圖片

技術分享圖片

技術分享圖片,其中M即為上面的矩陣,但是為什麽會有這個算子呢,我試著給一點解釋。

技術分享圖片,這個矩陣先擺在這裏,我們先看一下協方差矩陣。


  協方差矩陣的作用為什麽比方差和均值要大呢?顯而易見方差和均值只是一維隨機變量的統計值,而協方差就不一樣了,它可以表示多維隨機變量之間的相關性信息。協方差矩陣的一個很出色的應用就是在PCA中,選擇主方向。協方差矩陣的對角線的元素表示的是各個維度的方差,而非對角線上的元素表示的是各個維度之間的相關性,因此,在PCA中,我們盡量將非對角線上的元素化為0,即將矩陣對角化,選特征值較大的維度,去掉特征值較小的維度,來獲得主方向,並且使主方向與其他方向的相關性盡量小。那現在看看這個矩陣M,通過上面對協方差的描述,我們完全可以把這個矩陣看做一個二維隨機分布的協方差矩陣,那麽我們要做的就是將其對角化,求矩陣的兩個特征值,然後根據這兩個特征值來判斷是不是角點(兩個特征值都大代表角點)。


而對於Harris算子來說,我們也可以寫成下式的形式:

,單單從這個式子中我們無法與上面聯系起來,上面是說要讓兩個特征值都大的點,而這個式子是要求使R最大的點,而也沒有辦法一眼看出R與兩個特征值之間的單調性關系。


下面我只是去驗證此式的正確性,至於它到底是根據什麽構造的,我還不清楚,如果有人知道,請告訴我一下~~

,進而可以設技術分享圖片,所以技術分享圖片,現在我們對技術分享圖片求導,整理後可得下式:

,對於k值,我們一般取0.04~0.06,所以對於角點,導數是正的,且隨著特征值的增大,導數呈上升的趨勢。也就是說這個算子是符合上面的理論分析的。


所以,我們在進行運算的開始先將圖像轉化到尺度空間表示,即將原圖像進行尺度變換,而尺度變換的方式就是問題的輸入信號與尺度核函數做卷積運算:

,其中這裏的運算為卷積運算,不是乘運算。即

,其中sigma表示尺度。然後,我們就使用L代替原圖像去進行運算,而尺度成了我們運算的參數了。


我們知道Harris角點本身就不受光照,旋轉的影響,現在我們又使其滿足尺度不變性,所以,Harris角點可以作為一個優秀的特征來幫助我們解決問題。

還有一段對Harris的計算步驟描述:


3、Shi-Tomasi 算法

Shi-Tomasi 算法是Harris 算法的改進。Harris 算法最原始的定義是將矩陣 M 的行列式值與 M 的跡相減,再將差值同預先給定的閾值進行比較。後來Shi 和Tomasi 提出改進的方法,若兩個特征值中較小的一個大於最小閾值,則會得到強角點。

如上面第二幅圖中,對自相關矩陣 M 進行特征值分析,產生兩個特征值技術分享圖片和兩個特征方向向量。因為較大的不確定度取決於較小的特征值,也就是技術分享圖片,所以通過尋找最小特征值的最大值來尋找好的特征點也就解釋的通了。
Shi 和Tomasi 的方法比較充分,並且在很多情況下可以得到比使用Harris 算法更好的結果。

【相關代碼】

由於這種Shi-Tomasi算子與1994年在文章 Good Features to Track [1]中提出,OpenCV 實現的算法的函數名定義為 goodFeaturesToTrack:

[cpp] view plaincopy
  1. void intdoubledouble int boolfalsedouble k=0.04 );

自定義使用函數(以方便createTrackbar的響應)如下:

[cpp] view plaincopy
  1. voidintvoid if
  2. double double int boolfalse double
  3. forint
  4. }


實踐

在主函數中定義兩個進度條方便調整閾值:

[cpp] view plaincopy
  1. namedWindow( source_window, CV_WINDOW_AUTOSIZE );
  2. cornerShiTomasi_demo( 0, 0 );


這裏還需要說的是OpenCV 2.4.2中給的角點檢測跟蹤的示例代碼有些問題,是應為SURF等不再定義在 feature2d模塊中,而是legacy和nonfree,所以需要加入引用:

[cpp] view plaincopy
  1. #include "opencv2/legacy/legacy.hpp" #include "opencv2/nonfree/nonfree.hpp"

角點檢測結果:

技術分享圖片

藍色實心點為Harris檢測結果,綠色空心圈為goodFeaturetoTrack檢測結果。

M特征值分解後每個像素點相減的圖(也就是Harris閾值判斷的圖)如下:

技術分享圖片

黑色實心點為Harris閾值檢測結果,白色空心圈為閾值為27時Shi-Tomasi檢測結果。

4、FAST角點檢測算法

Smith 和 Brady在1997年提出了一種完全不同的角點提取方法,即“SUSAN (Smallest UnivalueSegment AssimilatingNucleus)”提取算子。SUSAN 提取算子的基本原理是,與每一圖像點相關的局部區域具有相同的亮度。如果某一窗口區域內的每一像元亮度值與該窗口中心的像元亮度值相同或相似,這一窗口區域將被稱之為“USAN”。計算圖像每一像元的“USAN”,為我們提供了是否有邊緣的方法。位於邊緣上的像元的“USAN”較小,位於角點上的像元的“USAN”更小。因此,我們僅需尋找最小的“USAN”,就可確定角點。該方法由於不需要計算圖像灰度差,因此,具有很強的抗噪聲的能力。


Edward Rosten and TomDrummond 在2006年提出了一種簡單快速的角點探測算法,該算法檢測的角點定義為在像素點的周圍鄰域內有足夠多的像素點與該點處於不同的區域。應用到灰度圖像中,即有足夠多的像素點的灰度值大於該點的灰度值或者小於該點的灰度值。

技術分享圖片
考慮下圖中p點附近半徑為3的圓環上的16個點,一個思路是若其中有連續的12個點的灰度值與p點的灰度值差別超過某一閾值,則可以認為p點為角點。
技術分享圖片
這一思路可以使用機器學習的方法進行加速。對同一類圖像,例如同一場景的圖像,可以在16個方向上進行訓練,得到一棵決策樹,從而在判定某一像素點是否為角點時,不再需要對所有方向進行檢測,而只需要按照決策樹指定的方向進行2-3次判定即可確定該點是否為角點。 轉自:http://blog.csdn.net/xw20084898/article/details/21180729

Harris角點及Shi-Tomasi角點檢測(轉)