VLFeat——SIFT圖像特徵提取(VC++實現)【轉載】

VLFeat——SIFT圖像特徵提取(VC++實現)【轉載】

由於VLFeat說明文檔中只提供了matlab的調用SIFT函數的實例,沒有VC++的調用說明,本文是根據實驗,在VS2010環境下,結合opencv開源庫計算圖像的SIFT的描述子,具體實現細節如下所示:

1.配置VLFeat環境已經在之前的一篇博文VLFeat-----mean sift開源庫 中介紹了詳細的配置過程,可以參考;

2.包含頭文件:

  extern "C"{
#include <vl/generic.h>
#include <vl/stringop.h>
#include <vl/pgm.h>
#include <vl/sift.h>
#include <vl/getopt_long.h>
};

3.實現過程如下:

複製代碼
#include <stdio.h>
#include <tchar.h>
#include <opencv2/opencv.hpp>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#pragma comment(lib, "opencv_core230d.lib")
#pragma comment(lib, "opencv_imgproc230d.lib")
#pragma comment(lib, "opencv_highgui230d.lib")
#pragma comment(lib, "opencv_objdetect230d.lib")

using namespace cv;
using namespace std;

extern "C"{
#include <vl/generic.h>
#include <vl/stringop.h>
#include <vl/pgm.h>
#include <vl/sift.h>
#include <vl/getopt_long.h>
};

int _tmain(int argc, _TCHAR* argv[])
{
    VL_PRINT ("Hello world!\n") ;
    char *ImagePath="a.jpg";
    IplImage *Image=cvLoadImage(ImagePath,0);
    //  int min=0;
    //  min=Image->width>Image->height?Image->height:Image->width;
    int noctaves=4,nlevels=2,o_min=0;
    // noctaves=(int)(log(min)/log(2));
    vl_sift_pix *ImageData=new vl_sift_pix[Image->height*Image->width];
    unsigned char *Pixel;
    for (int i=0;i<Image->height;i++)
    {
        for (int j=0;j<Image->width;j++)
        {
            Pixel=(unsigned char*)(Image->imageData+i*Image->width+j);
            ImageData[i*Image->width+j]=*(Pixel);
        }
    }
    VlSiftFilt *SiftFilt=NULL;
    SiftFilt=vl_sift_new(Image->width,Image->height,noctaves,nlevels,o_min);
    int KeyPoint=0;
    int idx=0;
    if (vl_sift_process_first_octave(SiftFilt,ImageData)!=VL_ERR_EOF)
    {
        while (TRUE)
        {
            //計算每組中的關鍵點
            vl_sift_detect(SiftFilt);
            //遍歷並繪製每個點
            KeyPoint+=SiftFilt->nkeys;
            VlSiftKeypoint *pKeyPoint=SiftFilt->keys;
            for (int i=0;i<SiftFilt->nkeys;i++)
            {
                VlSiftKeypoint TemptKeyPoint=*pKeyPoint;
                pKeyPoint++;
                cvDrawCircle(Image,cvPoint(TemptKeyPoint.x,TemptKeyPoint.y),TemptKeyPoint.sigma/2,CV_RGB(255,0,0));
                idx++;
                //計算並遍歷每個點的方向
                double angles[4];
                int angleCount=vl_sift_calc_keypoint_orientations(SiftFilt,angles,&TemptKeyPoint);
                for (int j=0;j<angleCount;j++)
                {
                    double TemptAngle=angles[j];
                    printf("%d: %f\n",j,TemptAngle);
                    //計算每個方向的描述
                    float *Descriptors=new float[128];
                    vl_sift_calc_keypoint_descriptor(SiftFilt,Descriptors,&TemptKeyPoint,TemptAngle);
                    int k=0;
                    while (k<128)
                    {
                        printf("%d: %f",k,Descriptors[k]);
                        printf("; ");
                        k++;
                    }

                    printf("\n");
                    delete []Descriptors;
                    Descriptors=NULL;
                }
            }
            //下一階
            if (vl_sift_process_next_octave(SiftFilt)==VL_ERR_EOF)
            {
                break;
            }
            //free(pKeyPoint);
            KeyPoint=NULL;
        }
    }
    vl_sift_delete(SiftFilt);
    delete []ImageData;
    ImageData=NULL;
    cvNamedWindow("Source Image",1);
    cvShowImage("Source Image",Image);
    cvWaitKey(0);
    cvReleaseImage(&Image);
    cvDestroyAllWindows();
    return 0;
}
複製代碼
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章