Fast角點檢測演算法
1.角點定義
角點是一種區域性特徵,具有旋轉不變性和不隨光照條件變化而變化的特點,一般將影象中曲率足夠高或者曲率變化明顯的點作為角點。檢測得到的角點特徵通常用於影象匹配、目標跟蹤、運動估計等方面。
2.Fast檢測角點
1)基本思想
E.Rosten和T.Drummond兩位大佬在06年一篇文章中提出了FAST特徵演算法,基本思想十分簡單:以某個畫素點為圓心,某半徑的圓周上其他畫素點與圓心畫素點特性差異達到某種標準時即認為該點就是角點。
2)數學模型
經過測試發現,選取的圓形半徑為3時可以兼顧檢測結果和效率。如上圖所示,點p與半徑為3的圓周上的16個畫素點比較其灰度差,若灰度差絕對值大於某閾值的點數超過設定數目(一般可以取9/10/11/12),則認為該點是角點。
使用小技巧加速該演算法,這裡取設定數目為12。
(1)判斷點1和點9灰度值與點p差值絕對值是否都大於閾值,如果是則繼續;否則pass該點
(2)判斷點1、點5、點9、點13四點與點p灰度值差值大於閾值的數目是否大於2,如果是則繼續;否則pass該點
(3)判斷圓周上16點與點p灰度值差值大於閾值的數目是否不小於12,如果是則認為該點是候選點;否則pass該點
對影象中所有畫素點進行上述操作後,得到候選點點集。通常使用非極大值抑制過濾區域性非極大值點,在這之前需要先計算各候選點的score,score就定義為16個點與中心點灰度值差值的絕對值總和
3.opencv實現
個人使用vs2012+opencv2.4.13作為開發環境,具體實現如下
#include <iostream>
#include <core/core.hpp>
#include <highgui/highgui.hpp>
#include <imgproc/imgproc.hpp>
#include <features2d/features2d.hpp>
using namespace std;
using namespace cv;
int getSum(uchar *p, int length)
{
int sum = 0;
for(int i=0;i<length; i++)
{
sum += *(p+i);
}
return sum;
}
int main(int argc, char* argv[])
{
/* 1.讀入影象 */
Mat image = imread("../church01.jpg", 0);
if(!image.data)
return 0;
namedWindow("Original Image");
imshow("Original Image", image);
Mat fastImg(image.size(), CV_8U, Scalar(0));//用於儲存Fast特徵點候選點
Mat fastScore(image.size(), CV_32F, Scalar(0));//用於計算候選點score
vector<Point> points;
int rows, cols, threshold;
rows = image.rows;
cols = image.cols;
threshold = 50;
/* 2.檢測Fast特徵點 */
for(int x = 3; x < rows - 3; x++)
{
for(int y = 3; y < cols - 3; y++)
{
uchar delta[16] = {0};
uchar diff[16] = {0};
delta[0] = (diff[0] = abs(image.at<uchar>(x,y) - image.at<uchar>(x, y-3))) > threshold;
delta[8] = (diff[8] = abs(image.at<uchar>(x,y) - image.at<uchar>(x, y+3))) > threshold;
if(getSum(delta, 16) == 0)
continue;
else
{
delta[12] = (diff[12] = abs(image.at<uchar>(x,y) - image.at<uchar>(x-3, y))) > threshold;
delta[4] = (diff[4] = abs(image.at<uchar>(x,y) - image.at<uchar>(x+3, y))) > threshold;
if(getSum(delta, 16) < 3)
continue;
else
{
delta[1] = (diff[1] = abs(image.at<uchar>(x,y) - image.at<uchar>(x+1, y-3))) > threshold;
delta[2] = (diff[2] = abs(image.at<uchar>(x,y) - image.at<uchar>(x+2, y-2))) > threshold;
delta[3] = (diff[3] = abs(image.at<uchar>(x,y) - image.at<uchar>(x+3, y-1))) > threshold;
delta[5] = (diff[5] = abs(image.at<uchar>(x,y) - image.at<uchar>(x+3, y+1))) > threshold;
delta[6] = (diff[6] = abs(image.at<uchar>(x,y) - image.at<uchar>(x+2, y+2))) > threshold;
delta[7] = (diff[7] = abs(image.at<uchar>(x,y) - image.at<uchar>(x+1, y+3))) > threshold;
delta[9] = (diff[9] = abs(image.at<uchar>(x,y) - image.at<uchar>(x-1, y+3))) > threshold;
delta[10] = (diff[10] = abs(image.at<uchar>(x,y) - image.at<uchar>(x-2, y+2))) > threshold;
delta[11] = (diff[11] = abs(image.at<uchar>(x,y) - image.at<uchar>(x-3, y+1))) > threshold;
delta[13] = (diff[13] = abs(image.at<uchar>(x,y) - image.at<uchar>(x-3, y-1))) > threshold;
delta[14] = (diff[14] = abs(image.at<uchar>(x,y) - image.at<uchar>(x-2, y-2))) > threshold;
delta[15] = (diff[15] = abs(image.at<uchar>(x,y) - image.at<uchar>(x-1, y-3))) > threshold;
if(getSum(delta, 16) >= 12)
{
points.push_back(Point(y,x));
fastScore.at<float>(x,y) = getSum(diff, 16);
fastImg.at<uchar>(x,y) = 255;
}
}
}
}
}
vector<Point>::const_iterator itp = points.begin();
while(itp != points.end())
{
circle(image, *itp, 3, Scalar(255), 1);
++itp;
}
//未進行非極大值抑制之前的特徵點檢測結果
namedWindow("Fast Image");
imshow("Fast Image", image);
/* 3.對特徵點候選點進行非極大值抑制 */
image = imread("../church01.jpg", 0);
Mat dilated(fastScore.size(), CV_32F, Scalar(0));
Mat localMax;
Mat element(7, 7, CV_8U, Scalar(1));
dilate(fastScore, dilated, element);
compare(fastScore, dilated, localMax, CMP_EQ);
bitwise_and(fastImg, localMax, fastImg);
for(int x = 0;x < fastImg.cols; x++)
{
for(int y = 0; y < fastImg.rows; y++)
{
if(fastImg.at<uchar>(y,x))
{
circle(image, Point(x,y), 3, Scalar(255), 1);
}
}
}
//進行非極大值抑制之後的特徵點檢測結果
namedWindow("Fast Image2");
imshow("Fast Image2", image);
waitKey();
return 0;
}
程式碼執行結果如下,比較第2/3張圖可以發現,非極大值抑制具有過濾掉區域性區域中非極大值角點的作用。
4.演算法小結
該演算法思想簡單,運算量很小,適合實時檢測方面的應用。不過也有缺點,主要表現為對於邊緣點與噪點區分能力不強,當然後面也有很多人在此基礎上加以改進提高演算法的穩定性。
5.參考文獻
[1]《opencv2計算機視覺程式設計手冊》
[2]【特徵檢測】FAST特徵檢測演算法(http://blog.csdn.net/hujingshuang/article/details/46898007)
相關文章
- openCV - 角點檢測快速演算法 FASTOpenCV演算法AST
- 【OpenCV】角點檢測:Harris角點及Shi-Tomasi角點檢測OpenCV
- 2.Harris角點檢測
- OpenCV計算機視覺學習(13)——影像特徵點檢測(Harris角點檢測,sift演算法)OpenCV計算機視覺特徵演算法
- 【目標檢測】Fast R-CNN演算法實現ASTCNN演算法
- OpenCV學習筆記-Harris角點檢測OpenCV筆記
- Shi-Tomas檢測和SHIF角點匹配
- Python計算機視覺——Harris角點檢測Python計算機視覺
- [Computer Vision]Harris角點檢測的詳細推導
- 異常點檢測演算法小結演算法
- 目標檢測演算法盤點(最全)演算法
- 【火爐煉AI】機器學習048-Harris檢測影像角點AI機器學習
- 排序檢測演算法排序演算法
- 賈佳亞等提出Fast Point R-CNN,利用點雲快速高效檢測3D目標ASTCNN3D
- opencv關鍵點檢測OpenCV
- i角檢驗
- PFLD:簡單高效的實用人臉關鍵點檢測演算法演算法
- PFLD:簡單、快速、超高精度人臉特徵點檢測演算法特徵演算法
- Opencv中goodFeaturesToTrack函式(Harris角點、Shi-Tomasi角點檢測)運算元速度的進一步最佳化(1920*1080測試圖11ms處理完成)。OpenCVGoREST函式
- ICLR 2024 | 無需訓練,Fast-DetectGPT讓文字檢測速度提升340倍ICLRASTGPT
- 目標檢測入門系列手冊三:Fast R-CNN 訓練教程ASTCNN
- 自動化測試新視角:以SaaS模式檢測內網安全模式內網
- 社群發現演算法 - Fast Unfolding(Louvian)演算法初探演算法AST
- 目標檢測演算法學習演算法
- 裸土覆蓋檢測演算法演算法
- 並行Louvain社群檢測演算法並行AI演算法
- 大盤點 | 2019年4篇目標檢測演算法最佳綜述演算法
- iOS 人臉關鍵點檢測iOS
- 筆記-圓角四種方法的對比以及效能檢測筆記
- SSD物體檢測演算法詳解演算法
- Miller-Rabin素數檢測演算法演算法
- MIMO OFDM 常用訊號檢測演算法演算法
- Python機器學習筆記:異常點檢測演算法——LOF(Local Outiler Factor)Python機器學習筆記演算法
- 無監督多視角行人檢測 Unsupervised Multi-view Pedestrian DetectionView
- [譯] 時間序列異常檢測演算法演算法
- 白話異常檢測演算法Isolation Forest演算法REST
- 圖資料探勘:社群檢測演算法(一)演算法
- 基於harris角點和RANSAC演算法的影像拼接matlab模擬演算法Matlab