Opencv中fast角點檢測原始碼分析

2021-08-08 09:50:49 字數 2970 閱讀 5943

fast是edward rosten和tom drummond兩位大神在《features from accelerated segment test》提出的一種特徵點檢測的方法,相對於其他的角點檢測方法,該方法以快著稱。

在兩位大神的文章中定義角點為

與其周圍鄰域內足夠多的畫素點相差較大的畫素

。一般取畫素點周圍乙個圓圈上的點作比較,圓圈的半徑可以為1、2或3,分別對應的圓圈上畫素是8、12和16,獻上一張經典的圖。

一、fast檢測步驟:

1)給定比較的圓圈大小size以及閾值threshold(可調);

2)假定給定的圓大小size=16,首先比較畫素1和9,如果其和中心畫素的差的絕對值均小於threshold,則該點肯定不是角點,我們直接跳過它,繼續檢測其他點,否則將它作為候選的角點,進入下乙個檢測步驟;

3)再比較畫素1、5、9和13與中心畫素的差的絕對值,如果其中有三個絕對值大於threshold,則該點繼續作為候選點,進入下乙個檢測步驟,否則捨棄它;

4)比較畫素1到16與中心畫素的差,如果連續大於或小於閾值的畫素超過8(可調)個,則該點為特徵點,否則捨棄它。

5)該方法檢測出來的角點可能會出現角點群,不能較好的定位特徵點的位置,所以最後還需要使用極大值抑制的方法對檢測到的特徵點進行篩選。opencv中使用得分函式作為極大值抑制的條件,得分定義為:由特徵點與圓周上16個畫素點的絕對差值中所有連續10個畫素中大於閾值的最小值的最大值,把該值作為特徵點的得分。聽起來很繞口有沒有。分解開來就是計算

特徵點與圓周上16個畫素點的絕對差值,然後每連續的10個為一組,得到每組差值的最小值,再得到這些值中的最大值,當然還要保證該值大於給定的閾值。然後在每個特徵點3*3的鄰域範圍內選擇得分最大的點作為最終的特徵點。

二、opencv的fast角點檢測原始碼分析:

(原始碼路徑:\opencv\sources\modules\features2d\src)

下面的函式是opencv的fast角點檢測中最熟悉不過的函式:

void fast(inputarray _img, std::vector& keypoints, int threshold, bool nonmax_suppression)
從原始碼中可以看到它呼叫了乙個16點圓圈的fastx角點檢測,繼續深入fastx函式可以看到,函式最終呼叫了乙個叫fast_t的類,該類就是fast檢測的核心所在,以下主要分析該類的一些核心演算法。

templatevoid fast_t(inputarray _img, std::vector& keypoints, int threshold, bool nonmax_suppression)

}else

count = 0;}}

if(d & 2)//--如果d==2,滿足第二種情況,判斷圓圈畫素是否有連續k個畫素大於中心畫素

}else

count = 0;}}

}} cornerpos[-1] = ncorners;

//--第一行不需要進行極大值抑制

if(i == 3)

continue;

//--極大值抑制

const uchar* prev = buf[(i - 4 + 3) % 3];//--當前行

const uchar* pprev = buf[(i - 5 + 3) % 3];//--前一行

cornerpos = cpbuf[(i - 4 + 3) % 3];

ncorners = cornerpos[-1];

for(k = 0; k < ncorners; k++)}}}

其中的鄰域圓圈畫素的相對位置建構函式以及特徵點得分函式如下所示:

//--鄰域圓圈畫素的相對位置

void makeoffsets(int pixel[25], int rowstride, int patternsize)

, , , , , , , ,

, , , , , , ,

}; static const int offset12[2] =

, , , , , ,

, , , , ,

}; static const int offset8[2] =

, , , ,

, , ,

}; const int (*offset)[3] = patternsize == 16 ? offset16 :

patternsize == 12 ? offset12 :

patternsize == 8 ? offset8 : 0;

assert(pixel && offsets);

//--記錄了圓圈畫素相對中心畫素的相對位置,存放在pixel陣列中

int k = 0;

for(; k < patternsize; k++)

pixel[k] = offset[k][0] + offset[k][1] * rowstride;

for(; k < 25; k++)

pixel[k] = pixle[k - patternsize];

}templateint cornerscore(const uchar* ptr, const int pixel, int threshold)

int b0 = -a0;

for(k = 0; k < 16; k+=2)

threshold = -b0 - 1;

return threshold;

}

通過對opencv源**的分析,讓我對fast角點檢測的認識更加深刻,同時也學習到了一些程式設計的小技巧,謹以此篇作為自己在計算機視覺上的開始。

OpenCV學習筆記 角點檢測的FAST演算法

features from accelerated segment test 由於不涉及尺度,梯度,等複雜運算,fast檢測器速度非常快。它使用一定鄰域內像元的灰度值與中心點比較大小去判斷是否為乙個角點。但它的缺點是不具有方向性,尺度不變性。1 在影象中選取乙個畫素點,來判斷它是不是關鍵點。ip等於...

OpenCv學習筆記12 FAST角點檢測

在前面我們已經陸續介紹了許多特徵檢測運算元,我們可以根據影象區域性的自相關函式求得harris角點,後面又提到了兩種十分優秀的特徵點以及他們的描述方法sift特徵和surf特徵。surf特徵是為了提高運算效率對sift特徵的一種近似,雖然在有些實驗環境中已經達到了實時,但是我們實踐工程應用中,特徵點...

opencv角點檢測

什麼叫角點呢?如果某一點在任意方向的乙個微小變化都會造成影象灰度很大的變化,那麼這個點就是角點 我們可以把角落看成是角點的現實體現,對於牆角來說,牆角是所有平面的開始點,只要這個點變化,就會引起所有從這個點出發的平面的變化,這就是角點。下面是幾個角點的具體描述 1 一階導數,也就是影象灰度的梯度的區...