生活随笔
收集整理的這篇文章主要介紹了
fast
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
相關(guān):SIFT原理與源碼解析
? ? ? ? ?SURF原理與源碼解析
? ?在實(shí)時(shí)的視頻流處理中,需要對(duì)每一幀特征提取,對(duì)算法處理速度上有很高的要求,傳統(tǒng)的SIFT,Harris等特征點(diǎn)提取很難滿足。由此提出Fast(Features from Accelerated Segment Test),由于不涉及尺度,梯度,等復(fù)雜運(yùn)算,Fast檢測(cè)器速度非常快。它使用一定鄰域內(nèi)像元的灰度值與中心點(diǎn)比較大小去判斷是否為一個(gè)角點(diǎn)。但它的缺點(diǎn)是不具有方向性,尺度不變性。
轉(zhuǎn)載請(qǐng)注明出處:http://blog.csdn.net/luoshixian099/article/details/48294967
Fast角點(diǎn)提取步驟(以Fast-12-16為例):
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
1.以固定半徑為圓的邊上取16個(gè)像素點(diǎn)(圖中白色框出的位置),與中心點(diǎn)像素值Ip做差。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
2.若邊上存在連續(xù)的12(N>12,若為Fast-9,只需要N>9)個(gè)點(diǎn)滿足 ?( I(x)-I(p) )>threshold 或者?( I(x)-I(p) ) < -threshold。(其中I(x)表示邊上的像素值,I(p)為中心點(diǎn)像素值,threshold為設(shè)定的閾值。)則此點(diǎn)作為一個(gè)候選角點(diǎn)。如圖上的虛線連接的位置。通常為了加速計(jì)算,直接比較1,5,9,13位置的差值,超過(guò)三個(gè)即視為一個(gè)候選點(diǎn)(存在連續(xù)的12個(gè)像元的必要條件),否則直接排除。? ? ? ? ? ? ? ? ?
3.非極大值抑制,排除不穩(wěn)定角點(diǎn)。采用強(qiáng)度響應(yīng)函數(shù):
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
即一個(gè)角點(diǎn)強(qiáng)度值定義為中心點(diǎn)與邊上的12個(gè)角點(diǎn)像素差值的絕對(duì)值累加和。
? ? ? ? ? ??
opencv源碼解析:
同上面原理部分不同,opencv中默認(rèn)采用Fast-9-16(還包括Fast-5-8,Fast-7-12).即在周圍取16個(gè)像素點(diǎn),若超過(guò)連續(xù)9個(gè)點(diǎn)與中心點(diǎn)差值大于閾值即成為候選角點(diǎn)。
角點(diǎn)強(qiáng)度計(jì)算方法不采用上面的公式所描述,而是采用最小的差值(見(jiàn)代碼分析)作為其角點(diǎn)強(qiáng)度值。
[cpp]?view plaincopy print?
#include?<stdio.h>?? #include?<iostream>?? #include?"cv.h"?? #include?"opencv2/highgui/highgui.hpp"?? #include?"opencv2/core/core.hpp"?? #include?"opencv2/features2d/features2d.hpp"?? using?namespace?std;?? using?namespace?cv;?? int?main(?int?argc,?char**?argv?)?? {?? ????Mat?img_1?=?imread(?"F:\\Picture\\hotel.jpg");?? ????if(?!img_1.data?)?? ????{??? ????????return?-1;?}?? ????FastFeatureDetector?detector(50,true);???? ????std::vector<KeyPoint>?keypoints_1;?? ????detector.detect(?img_1,?keypoints_1?);?? ????drawKeypoints(img_1,keypoints_1,img_1,Scalar::all(255));?? ????imshow("HOTEL",img_1);?? ????waitKey(0);?? ????return?0;?? }??
[cpp]?view plaincopy print?
void?FAST_t(InputArray?_img,?std::vector<KeyPoint>&?keypoints,?int?threshold,?bool?nonmax_suppression)?? {?? ????Mat?img?=?_img.getMat();?? ????const?int?K?=?patternSize/2,?N?=?patternSize?+?K?+?1;?? ?? ????int?i,?j,?k,?pixel[25];?? ????makeOffsets(pixel,?(int)img.step,?patternSize);?? ?? ????keypoints.clear();?? ?? ????threshold?=?std::min(std::max(threshold,?0),?255);?? ?? ?? ????uchar?threshold_tab[512];?? ????for(?i?=?-255;?i?<=?255;?i++?)?? ????????threshold_tab[i+255]?=?(uchar)(i?<?-threshold???1?:?i?>?threshold???2?:?0);???? ?? ????AutoBuffer<uchar>?_buf((img.cols+16)*3*(sizeof(int)?+?sizeof(uchar))?+?128);?? ????uchar*?buf[3];?? ????buf[0]?=?_buf;?buf[1]?=?buf[0]?+?img.cols;?buf[2]?=?buf[1]?+?img.cols;?? ????int*?cpbuf[3];?? ????cpbuf[0]?=?(int*)alignPtr(buf[2]?+?img.cols,?sizeof(int))?+?1;?? ????cpbuf[1]?=?cpbuf[0]?+?img.cols?+?1;?? ????cpbuf[2]?=?cpbuf[1]?+?img.cols?+?1;?? ????memset(buf[0],?0,?img.cols*3);?? ?? ????for(i?=?3;?i?<?img.rows-2;?i++)?? ????{?? ????????const?uchar*?ptr?=?img.ptr<uchar>(i)?+?3;?? ????????uchar*?curr?=?buf[(i?-?3)%3];?? ????????int*?cornerpos?=?cpbuf[(i?-?3)%3];?? ????????memset(curr,?0,?img.cols);?? ????????int?ncorners?=?0;?? ?? ????????if(?i?<?img.rows?-?3?)?? ????????{?? ????????????j?=?3;?? ????????????? ? ? ?? ????????????for(?;?j?<?img.cols?-?3;?j++,?ptr++?)?? ????????????{?? ????????????????int?v?=?ptr[0];?? ????????????????const?uchar*?tab?=?&threshold_tab[0]?-?v?+?255;?? ??????int?d?=?tab[ptr[pixel[0]]]?|?tab[ptr[pixel[8]]];?? ????????????????if(?d?==?0?)???????? ????????????????????continue;?? ?? ????????????????d?&=?tab[ptr[pixel[2]]]?|?tab[ptr[pixel[10]]];?? ????????????????d?&=?tab[ptr[pixel[4]]]?|?tab[ptr[pixel[12]]];?? ????????????????d?&=?tab[ptr[pixel[6]]]?|?tab[ptr[pixel[14]]];?? ?? ????????????????if(?d?==?0?)?????? ????????????????????continue;?? ?? ????????????????d?&=?tab[ptr[pixel[1]]]?|?tab[ptr[pixel[9]]];?? ????????????????d?&=?tab[ptr[pixel[3]]]?|?tab[ptr[pixel[11]]];?? ????????????????d?&=?tab[ptr[pixel[5]]]?|?tab[ptr[pixel[13]]];?? ????????????????d?&=?tab[ptr[pixel[7]]]?|?tab[ptr[pixel[15]]];?? ?? ????????????????if(?d?&?1?)????? ????????????????{?? ????????????????????int?vt?=?v?-?threshold,?count?=?0;?? ?? ????????????????????for(?k?=?0;?k?<?N;?k++?)????? ????????????????????{?? ????????????????????????int?x?=?ptr[pixel[k]];?? ????????????????????????if(x?<?vt)??????? ????????????????????????{?? ????????????????????????????if(?++count?>?K?)?? ????????????????????????????{?? ?????????????????????????????cornerpos[ncorners++]?=?j;?? ?????????????????????????????if(nonmax_suppression)?? ????????????????????????curr[j]?=?(uchar)cornerScore<patternSize>(ptr,?pixel,?threshold);?? ????????????????????????????break;?? ????????????????????????????}?? ????????????????????????}?? ????????????????????????else?? ????????????????????????????count?=?0;?? ????????????????????}?? ????????????????}?? ?? ????????????????if(?d?&?2?)?? ????????????????{?? ????????????????????int?vt?=?v?+?threshold,?count?=?0;?? ?? ????????????????????for(?k?=?0;?k?<?N;?k++?)????? ????????????????????{?? ????????????????????????int?x?=?ptr[pixel[k]];?? ????????????????????????if(x?>?vt)?? ????????????????????????{?? ????????????????????????????if(?++count?>?K?)?? ????????????????????????????{?? ????????????????????????????cornerpos[ncorners++]?=?j;?? ?????????????????????????????if(nonmax_suppression)?? ????????????????????????curr[j]?=?(uchar)cornerScore<patternSize>(ptr,?pixel,?threshold);?? ????????????????????????????break;?? ????????????????????????????}?? ????????????????????????}?? ????????????????????????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++?)?? ????????{?? ????????????j?=?cornerpos[k];?? ????????????int?score?=?prev[j];?? ????????????if(?!nonmax_suppression?||?????? ???????????????(score?>?prev[j+1]?&&?score?>?prev[j-1]?&&?? ????????????????score?>?pprev[j-1]?&&?score?>?pprev[j]?&&?score?>?pprev[j+1]?&&?? ????????????????score?>?curr[j-1]?&&?score?>?curr[j]?&&?score?>?curr[j+1])?)?? ????????????{?? ????????keypoints.push_back(KeyPoint((float)j,?(float)(i-1),?7.f,?-1,?(float)score));?? ????????????}?? ????????}?? ????}?? }??
角點(diǎn)的強(qiáng)度計(jì)算方法:若采用Fast-9-16,計(jì)算連續(xù)的9個(gè)位置與中心位置的差值的絕對(duì)值,取最小的一個(gè)差值作為其強(qiáng)度值。
[cpp]?view plaincopy print?
int?cornerScore<16>(const?uchar*?ptr,?const?int?pixel[],?int?threshold)?? {?? ????const?int?K?=?8,?N?=?K*3?+?1;?? ????int?k,?v?=?ptr[0];?? ????short?d[N];?? ????for(?k?=?0;?k?<?N;?k++?)?????? ????????d[k]?=?(short)(v?-?ptr[pixel[k]]);?? ????int?a0?=?threshold;?? ????for(?k?=?0;?k?<?16;?k?+=?2?)???? ????{?? ????????int?a?=?std::min((int)d[k+1],?(int)d[k+2]);?? ????????a?=?std::min(a,?(int)d[k+3]);?? ????????if(?a?<=?a0?)?? ????????????continue;?? ????????a?=?std::min(a,?(int)d[k+4]);?? ????????a?=?std::min(a,?(int)d[k+5]);?? ????????a?=?std::min(a,?(int)d[k+6]);?? ????????a?=?std::min(a,?(int)d[k+7]);?? ????????a?=?std::min(a,?(int)d[k+8]);?? ????????a0?=?std::max(a0,?std::min(a,?(int)d[k]));?? ????????a0?=?std::max(a0,?std::min(a,?(int)d[k+9]));?? ????}?? ?? ????int?b0?=?-a0;?? ????for(?k?=?0;?k?<?16;?k?+=?2?)?? ????{?? ????????int?b?=?std::max((int)d[k+1],?(int)d[k+2]);?? ????????b?=?std::max(b,?(int)d[k+3]);?? ????????b?=?std::max(b,?(int)d[k+4]);?? ????????b?=?std::max(b,?(int)d[k+5]);?? ????????if(?b?>=?b0?)?? ????????????continue;?? ????????b?=?std::max(b,?(int)d[k+6]);?? ????????b?=?std::max(b,?(int)d[k+7]);?? ????????b?=?std::max(b,?(int)d[k+8]);?? ?? ????????b0?=?std::min(b0,?std::max(b,?(int)d[k]));?? ????????b0?=?std::min(b0,?std::max(b,?(int)d[k+9]));?? ????}?? ?? ????threshold?=?-b0-1;?? ?? ????return?threshold;?? }??
參考文章:Edward Rosten et.:Machine Learning for High-Speed Corner Detection
? ? ? ? ? ? ? ? http://blog.csdn.net/kezunhai/article/details/11290749
? ? ? ? ? ? ? ? http://www.edwardrosten.com/work/fast.html
總結(jié)
以上是生活随笔為你收集整理的fast的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。