欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

VLFeat中SIFT特征点检测

发布时间:2023/12/9 48 豆豆
生活随笔 收集整理的这篇文章主要介绍了 VLFeat中SIFT特征点检测 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

本代码使用VLFeat库中的函数对一幅图像进行了SIFT检测

需要事先配置好VLFeat和OpenCV,VLFeat的配置参考前一篇博文,OpenCV的配置网上一大堆,自己去百度

#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,不能不填,因为是单通道,灰度空间IplImage* img = cvLoadImage("1.jpg", 0);// 此处这三个变量的定义看下面vl_sift_new函数中的解释int noctaves = 4, nlevels = 2, o_min = 0;// vl_sift_pix 就是float型数据vl_sift_pix *imgdata = new vl_sift_pix[img->height * img->width];// 将原图像复制到float型的vl_sift_pix数组中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.// 这个过滤器实现了SIFT检测器和描述符VlSiftFilt *siftfilt = NULL;// vl_sift_new(int width, int height, int noctaves, int nlevels, int o_min)// noctaves: numbers of octaves 组数// nlevels: numbers of levels per octave 每组的层数// o_min: first octave index 第一组的索引号siftfilt = vl_sift_new(img->width, img->height, noctaves, nlevels, o_min);float Descri[1000][128]; //记录每个特征点的描述符,一个特征点有可能有多个描述符,最多有4个int area[1000][4]; //0~3分别记录每个特征点的坐标x,y,圆的半径大小r,该特征点的方向个数,或者说描述符个数int keypoint = 0;int idx_point = 0; //特征点的个数int idx_descri = 0; //特征点描述符的个数 >= 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.// 这个函数开始处理一幅新图像,通过计算它在低层的高斯尺度空间// 它还清空内部记录关键点的缓冲区if (vl_sift_process_first_octave(siftfilt, imgdata) != VL_ERR_EOF){while (1){// 计算每组中的关键点 vl_sift_detect(siftfilt);// 遍历每个特征点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;// 计算并遍历每个点的方向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.// 计算每个极值点的方向,包括主方向和辅方向,最多4个方向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]);// 计算每个方向的描述符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.// 这个函数计算高斯尺度空间中的下一组尺度空间图像// 这个函数会清除在前一层空间中检测到的特征点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; }

 

转载于:https://www.cnblogs.com/pakfahome/p/3605285.html

总结

以上是生活随笔为你收集整理的VLFeat中SIFT特征点检测的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。