VLFeat中SIFT特征点检测
生活随笔
收集整理的這篇文章主要介紹了
VLFeat中SIFT特征点检测
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
本代碼使用VLFeat庫中的函數(shù)對一幅圖像進(jìn)行了SIFT檢測
需要事先配置好VLFeat和OpenCV,VLFeat的配置參考前一篇博文,OpenCV的配置網(wǎng)上一大堆,自己去百度
#include "stdafx.h" #include <stdio.h> #include <tchar.h> #include <opencv2/opencv.hpp> #include <stdio.h>using namespace cv; using namespace std;extern "C"{ #include <vl/generic.h> #include <vl/stringop.h> #include <vl/sift.h> #include <vl/getopt_long.h> };int _tmain(int argc, _TCHAR* argv[]) {// 注意此處一定是0,不能不填,因?yàn)槭菃瓮ǖ?#xff0c;灰度空間IplImage* img = cvLoadImage("1.jpg", 0);// 此處這三個(gè)變量的定義看下面vl_sift_new函數(shù)中的解釋int noctaves = 4, nlevels = 2, o_min = 0;// vl_sift_pix 就是float型數(shù)據(jù)vl_sift_pix *imgdata = new vl_sift_pix[img->height * img->width];// 將原圖像復(fù)制到float型的vl_sift_pix數(shù)組中unsigned char *Pixel;for (int i=0;i<img->height;i++){for (int j=0;j<img->width;j++){Pixel=(unsigned char*)(img->imageData+i*img->width+j);imgdata[i*img->width+j]=*(Pixel);}}// VlSiftFilt: This filter implements the SIFT detector and descriptor.// 這個(gè)過濾器實(shí)現(xiàn)了SIFT檢測器和描述符VlSiftFilt *siftfilt = NULL;// vl_sift_new(int width, int height, int noctaves, int nlevels, int o_min)// noctaves: numbers of octaves 組數(shù)// nlevels: numbers of levels per octave 每組的層數(shù)// o_min: first octave index 第一組的索引號(hào)siftfilt = vl_sift_new(img->width, img->height, noctaves, nlevels, o_min);float Descri[1000][128]; //記錄每個(gè)特征點(diǎn)的描述符,一個(gè)特征點(diǎn)有可能有多個(gè)描述符,最多有4個(gè)int area[1000][4]; //0~3分別記錄每個(gè)特征點(diǎn)的坐標(biāo)x,y,圓的半徑大小r,該特征點(diǎn)的方向個(gè)數(shù),或者說描述符個(gè)數(shù)int keypoint = 0;int idx_point = 0; //特征點(diǎn)的個(gè)數(shù)int idx_descri = 0; //特征點(diǎn)描述符的個(gè)數(shù) >= idx_point// vl_sift_process_first_octave: // The function starts processing a new image by computing its Gaussian scale space at the lower octave. // It also empties the internal keypoint buffer.// 這個(gè)函數(shù)開始處理一幅新圖像,通過計(jì)算它在低層的高斯尺度空間// 它還清空內(nèi)部記錄關(guān)鍵點(diǎn)的緩沖區(qū)if (vl_sift_process_first_octave(siftfilt, imgdata) != VL_ERR_EOF){while (1){// 計(jì)算每組中的關(guān)鍵點(diǎn) vl_sift_detect(siftfilt);// 遍歷每個(gè)特征點(diǎn)keypoint += siftfilt->nkeys;VlSiftKeypoint *pkeypoint = siftfilt->keys;for (int i = 0; i < siftfilt->nkeys; i ++){VlSiftKeypoint tempkeypoint = *pkeypoint;pkeypoint++;area[idx_point][0] = tempkeypoint.x;area[idx_point][1] = tempkeypoint.y;area[idx_point][2] = tempkeypoint.sigma/2;// 計(jì)算并遍歷每個(gè)點(diǎn)的方向double angles[4];// The function computes the orientation(s) of the keypoint k. // The function returns the number of orientations found (up to four). // The orientations themselves are written to the vector angles.// 計(jì)算每個(gè)極值點(diǎn)的方向,包括主方向和輔方向,最多4個(gè)方向int angleCount = vl_sift_calc_keypoint_orientations(siftfilt, angles, &tempkeypoint);area[idx_point][3] = angleCount;idx_point ++;for (int j = 0; j < angleCount; ++ j){printf("%d: %f\n", j, angles[j]);// 計(jì)算每個(gè)方向的描述符float *descriptors = new float[128];vl_sift_calc_keypoint_descriptor(siftfilt, descriptors, &tempkeypoint, angles[j]);memcpy(Descri[idx_descri], descriptors, 128 * sizeof(float));idx_descri ++;delete []descriptors;descriptors = NULL;}}// vl_sift_process_next_octave: // The function computes the next octave of the Gaussian scale space. // Notice that this clears the record of any feature detected in the previous octave.// 這個(gè)函數(shù)計(jì)算高斯尺度空間中的下一組尺度空間圖像// 這個(gè)函數(shù)會(huì)清除在前一層空間中檢測到的特征點(diǎn)if (vl_sift_process_next_octave(siftfilt) == VL_ERR_EOF){break;}keypoint = 0;}}vl_sift_delete(siftfilt);delete []imgdata;imgdata = NULL;for (int i = 0; i < idx_point; ++ i){cvDrawCircle(img, cvPoint(area[i][0], area[i][1]), area[i][3], CV_RGB(255,0,0));}cvNamedWindow("Source Image", 1);cvShowImage("Source Image", img);cvWaitKey(0);cvReleaseImage(&img);cvDestroyAllWindows();return 0; }?
轉(zhuǎn)載于:https://www.cnblogs.com/pakfahome/p/3605285.html
總結(jié)
以上是生活随笔為你收集整理的VLFeat中SIFT特征点检测的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [react] 说出几点你认为的Reac
- 下一篇: 【TensorFlow篇】--Tenso