官方参考资料:
sift.h File Reference
kd-tree forest from FLANN
Scale Invariant Feature Transform (SIFT)
Tutorials>SIFT detector and descriptor
原文链接如下(请参考原文):
图像检索(1): 再论SIFT-基于vlfeat实现(c++实现)
https://www.cnblogs.com/wangguchangqing/p/4853263.html
// 初始化
const string file = "../0.jpg";
Mat img = imread(file,IMREAD_GRAYSCALE);
Mat color_img = imread(file);
Mat float_img;
img.convertTo(float_img,CV_32F);
int rows = img.rows;
int cols = img.cols;
VlSiftFilt* vl_sift = vl_sift_new(cols,rows,4,3,0);
vl_sift_set_peak_thresh(vl_sift,0.04);
vl_sift_set_edge_thresh(vl_sift,10);
vl_sift_pix *data = (vl_sift_pix*)(float_img.data);
vector<VlSiftKeypoint> kpts;
vector<float*> descriptors;
vl_sift_extract(vl_sift,data,kpts,descriptors);
/*
Extract sift using vlfeat
parameters:
vl_sfit, VlSiftFilt*
data , image pixel data ,to be convert to float
kpts, keypoint list
descriptors, descriptor. Need to free the memory after using.
*/
void vl_sift_extract(VlSiftFilt *vl_sift, vl_sift_pix* data,
vector<VlSiftKeypoint> &kpts,vector<float*> &descriptors) {
// Detect keypoint and compute descriptor in each octave
if(vl_sift_process_first_octave(vl_sift,data) != VL_ERR_EOF){
while(true){
vl_sift_detect(vl_sift);
VlSiftKeypoint* pKpts = vl_sift->keys;
for(int i = 0; i < vl_sift->nkeys; i ++) {
double angles[4];
// 计算特征点的方向,包括主方向和辅方向,最多4个
int angleCount = vl_sift_calc_keypoint_orientations(vl_sift,angles,pKpts);
// 对于方向多于一个的特征点,每个方向分别计算特征描述符
// 并且将特征点复制多个
for(int i = 0 ; i < angleCount; i ++){
float *des = new float[128];
vl_sift_calc_keypoint_descriptor(vl_sift,des,pKpts,angles[0]);
descriptors.push_back(des);
kpts.push_back(*pKpts);
}
pKpts ++;
}
// Process next octave
if(vl_sift_process_next_octave(vl_sift) == VL_ERR_EOF) {
break ;
}
}
}
}