robhess的sift源码
‘壹’ Rob Hess给出的sift代码运行出现如下错误:error C2198: “cvKMeans2”: 用于调用的参数太少,请大侠指教
这是源码里针对找到图像特征点进行聚类的函数,运行到这里sift算法已经结束了。可以试着吧调用kmeans算法的部分注释掉,只执行sift算法然后打出来特征点看一下效果。我也不明白在一张图像上对特征点聚类的意义何在。对多张图像聚类还有意义。
‘贰’ SIFT高斯金字塔问题
SIFT特征提取前首先要进行预处理,预处理包含对原始图像进行高斯模糊,SIGMA即是首次进行高斯模糊的系数,后续计算中也是通过它计算每一层图像所使用的模糊系数,具体公式可以查查高斯核和高斯卷积的计算。
由于对原图进行高斯模糊会丢失一部分的信息,所以我们首先对图像进行了一次插值(Rob Hess源码中使用的是双三次插值),以弥补信息的损失。而对原图进行放大一倍的处理,也会导致高斯核的计算过程中需要多乘以4,这部分内容你可以找源码出来看看。
‘叁’ 跪求OPENCV的SIFT程序!小女子感激不尽啊!呜呜…[email protected]
已发送
里面有rob hess的c版本sift 还有个和sift差不多的matlab版本opensurf
surf比sift更快,两者原理类似,个人更推荐surf
‘肆’ sift特征点正确匹配率是怎么计算出来的
一、特征点(角点)匹配
图像匹配能够应用的场合非常多,如目标跟踪,检测,识别,图像拼接等,而角点匹配最核心的技术就要属角点匹配了,所谓角点匹配是指寻找两幅图像之间的特征像素点的对应关系,从而确定两幅图像的位置关系。
角点匹配可以分为以下四个步骤:
1、提取检测子:在两张待匹配的图像中寻找那些最容易识别的像素点(角点),比如纹理丰富的物体边缘点等。
2、提取描述子:对于检测出的角点,用一些数学上的特征对其进行描述,如梯度直方图,局部随机二值特征等。检测子和描述子的常用提取方法有:sift,harris,surf,fast,agast,brisk,freak,brisk,brief/orb等。
3、匹配:通过各个角点的描述子来判断它们在两张图像中的对应关系,常用方法如 flann等。
4、消噪:去除错误匹配的外点,保留正确的匹配点。常用方法有KDTREE,BBF,Ransac,GTM等。
二、SIFT匹配方法的提出
为了排除因为图像遮挡和背景混乱而产生的无匹配关系的关键点,SIFT的作者Lowe提出了比较最近邻距离与次近邻距离的SIFT匹配方式:取一幅图像中的一个SIFT关键点,并找出其与另一幅图像中欧式距离最近的前两个关键点,在这两个关键点中,如果最近的距离除以次近的距离得到的比率ratio少于某个阈值T,则接受这一对匹配点。因为对于错误匹配,由于特征空间的高维性,相似的距离可能有大量其他的错误匹配,从而它的ratio值比较高。显然降低这个比例阈值T,SIFT匹配点数目会减少,但更加稳定,反之亦然。
Lowe推荐ratio的阈值为0.8,但作者对大量任意存在尺度、旋转和亮度变化的两幅图片进行匹配,结果表明ratio取值在0. 4~0. 6 之间最佳,小于0. 4的很少有匹配点,大于0. 6的则存在大量错误匹配点,所以建议ratio的取值原则如下:
ratio=0. 4:对于准确度要求高的匹配;
ratio=0. 6:对于匹配点数目要求比较多的匹配;
ratio=0. 5:一般情况下。
三、常见的SIFT匹配代码
1、vlfeat中sift toolbox中的vl_ubcmatch.c使用的是普通的欧氏距离进行匹配(该SIFT代码贡献自Andrea
Vedaldi)。
2、Lowe的C++代码中使用的是欧氏距离,但是在matlab代码中为了加速计算,使用的是向量夹角来近似欧氏距离:先将128维SIFT特征向量归一化为单位向量(每个数除以平方和的平方根),然后点乘来得到向量夹角的余弦值,最后利用反余弦(acos函数)求取向量夹角。实验证明Lowe的办法正确率和耗时都很不错。
同样,也可以采用knnsearch函数求最近点和次近点:knnsearch采用euclidean距离时得到的结果与lowe采用的近似方法结果几乎一致,正好印证了模拟欧氏距离的效果。
3、Rob Hess的OpenSIFT采用了KDTREE来对匹配进行优化。
4、CSDN大神v_JULY_v实现了KDTREE+BBF对SIFT匹配的优化和消除错误匹配:从K近邻算法、距离度量谈到KD树、SIFT+BBF算法
- 结构之法 算法之道 - 博客频道 - CSDN.NET。
5、OpenCV中features2d实现的SIFT匹配有多种matcher:VectorDescriptorMatcher,BFMatcher(Brute-force descriptor matcher),FernDescriptorMatcher,OneWayDescriptorMatcher,FlannBasedMatcher 等等。目前只知道采用knnsearch,提供了多种距离度量方式,具体区别不懂。
‘伍’ RobHess sift用opencv编译时出现如下,是怎么回事
应该是依赖的某些lib没有添加,把opencv有关的lib比如features2d / flann / contrib 什么的都填进去试试
‘陆’ 求在vs2010和opencv 2.2环境下 sift匹配图像源码,求大神。
#include<ctime>
#include<iostream>
#include"opencv2/core/core.hpp"
#include"opencv2/features2d/features2d.hpp"
#include"opencv2/highgui/highgui.hpp"
#include"opencv2/calib3d/calib3d.hpp"
usingnamespacecv;
usingnamespacestd;
voidreadme();
//主函数
intmain(intargc,char*argv[])
{
if(argc>3)
{
readme();
return-1;
}
//默认参数
if(argc<3)
{
argv[1]="box.png";
argv[2]="box_in_scene.png";
}
//加载图像
Matimg_object=imread(argv[1],CV_LOAD_IMAGE_GRAYSCALE);
Matimg_scene=imread(argv[2],CV_LOAD_IMAGE_GRAYSCALE);
if(!img_object.data||!img_scene.data)
{
std::cout<<"--(!)Errorreadingimages"<<std::endl;
return-1;
}
doublebegin=clock();
//第一步:用SIFT算子检测关键点
SiftFeatureDetectordetector;//构造函数采用默认的
std::vector<KeyPoint>keypoints_object,keypoints_scene;//构造2个专门由点组成的点向量用来存储特征点
detector.detect(img_object,keypoints_object);//将img_object图像中检测到的特征点存储起来放在keypoints_object中
detector.detect(img_scene,keypoints_scene);//同理
//在图像中画出特征点
Matimg_keypoints_object,img_keypoints_scene;
//先在内存中绘制
drawKeypoints(img_object,keypoints_object,img_keypoints_object,Scalar::all(-1),DrawMatchesFlags::DEFAULT);//在内存中画出特征点
drawKeypoints(img_scene,keypoints_scene,img_keypoints_scene,Scalar::all(-1),DrawMatchesFlags::DEFAULT);
//再显示
imshow("sift_keypoints_object",img_keypoints_object);
imshow("sift_keypoints_scene",img_keypoints_scene);
//第二步:计算特征向量
;//定义描述子对象
Matdescriptors_1,descriptors_2;//存放特征向量的矩阵
//计算特征向量
extractor.compute(img_object,keypoints_object,descriptors_1);
extractor.compute(img_scene,keypoints_scene,descriptors_2);
//第三步,用FLANN进行匹配特征向量
FlannBasedMatchermatcher;//定义一个FlannBasedMatcher对象
std::vector<DMatch>matches;
matcher.match(descriptors_1,descriptors_2,matches);
doublemax_dist=0;
doublemin_dist=100;
//计算特征点间的最大最小距离
for(inti=0;i<descriptors_1.rows;i++)
{
doubledist=matches[i].distance;
if(dist<min_dist)min_dist=dist;
if(dist>max_dist)max_dist=dist;
}
printf("--Maxdist:%f ",max_dist);
printf("--Mindist:%f ",min_dist);
//只保留好的匹配:特征点距离小于3倍最小距离
std::vector<DMatch>good_matches;
for(inti=0;i<descriptors_1.rows;i++)
{
if(matches[i].distance<3*min_dist)
{
good_matches.push_back(matches[i]);
}
}
//在内存中绘制保留的好的匹配
Matimg_matches;
drawMatches(img_object,keypoints_object,img_scene,keypoints_scene,
good_matches,img_matches,Scalar::all(-1),Scalar::all(-1),
vector<char>(),DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
//在场景中定位目标图像
std::vector<Point2f>obj;
std::vector<Point2f>scene;
std::cout<<"good_matches.size():"<<good_matches.size()<<" ";
for(inti=0;i<good_matches.size();i++)
{
//从好的匹配中找到特征点
obj.push_back(keypoints_object[good_matches[i].queryIdx].pt);
scene.push_back(keypoints_scene[good_matches[i].trainIdx].pt);
}
//基于匹配的关键点找出相应的变换
cv::MatH=cv::findHomography(cv::Mat(obj),cv::Mat(scene),CV_RANSAC);
//找到目标的角点
std::vector<Point2f>obj_corners(4);
obj_corners[0]=cvPoint(0,0);
obj_corners[1]=cvPoint(img_object.cols,0);
obj_corners[2]=cvPoint(img_object.cols,img_object.rows);
obj_corners[3]=cvPoint(0,img_object.rows);
std::vector<Point2f>scene_corners(4);
//映射点群,在场景中获取目标的坐标
cv::perspectiveTransform(cv::Mat(obj_corners),cv::Mat(scene_corners),H);
//目标的角点之间连线(框出目标)
line(img_matches,scene_corners[0]+Point2f(img_object.cols,0),scene_corners[1]+Point2f(img_object.cols,0),Scalar(0,255,0),4);
line(img_matches,scene_corners[1]+Point2f(img_object.cols,0),scene_corners[2]+Point2f(img_object.cols,0),Scalar(0,255,0),4);
line(img_matches,scene_corners[2]+Point2f(img_object.cols,0),scene_corners[3]+Point2f(img_object.cols,0),Scalar(0,255,0),4);
line(img_matches,scene_corners[3]+Point2f(img_object.cols,0),scene_corners[0]+Point2f(img_object.cols,0),Scalar(0,255,0),4);
//显示保留的好的匹配
imshow("GoodMatches&Objectdetection-SIFT",img_matches);
imwrite("GoodMatches&Objectdetection-SIFT.png",img_matches);
doubleend=clock();
cout<<" SURF-elapsedtimeis:"<<(end-begin)/CLOCKS_PER_SEC*1000<<"ms ";
waitKey(0);
return0;
}
/**
*@函数readme
*/
voidreadme()
{
std::cout<<"Usage:./cv_sift_demo<img1><img2>"<<std::endl;
}
box_in_scene.png
‘柒’ robhess的sift源码怎么编译
这个函数包含整个sift算法的流程,函数返回值为特征点的数目,如果没有找到特征点则返回-1。img定义为输入图像,feat定义为指向结构体feature的指针。
int sift_features( IplImage* img, struct feature** feat )
{
return _sift_features( img,
feat,
SIFT_INTVLS,
SIFT_SIGMA,
SIFT_CONTR_THR,
SIFT_CURV_THR,
SIFT_IMG_DBL,
SIFT_DESCR_WIDTH,
SIFT_DESCR_HIST_BINS );
}
int _sift_features( IplImage* img, struct feature** feat, intintvls,
doublesigma, doublecontr_thr, intcurv_thr,
intimg_dbl,intdescr_width, intdescr_hist_bins)
{
IplImage* init_img;
IplImage***gauss_pyr, *** dog_pyr;
CvMemStorage*storage;
CvSeq* features;
intoctvs, i, n = 0;
‘捌’ 8点算法 需要哪些sift数据
一、特征点(角点)匹配图像匹配能够应用的场合非常多,如目标跟踪,检测,识别,图像拼接等,而角点匹配最核心的技术就要属角点匹配了,所谓角点匹配是指寻找两幅图像之间的特征像素点的对应关系,从而确定两幅图像的位置关系。角点匹配可以分为以下四个步骤:1、提取检测子:在两张待匹配的图像中寻找那些最容易识别的像素点(角点),比如纹理丰富的物体边缘点等。2、提取描述子:对于检测出的角点,用一些数学上的特征对其进行描述,如梯度直方图,局部随机二值特征等。检测子和描述子的常用提取方法有:sift,harris,surf,fast,agast,brisk,freak,brisk,brief/orb等。3、匹配:通过各个角点的描述子来判断它们在两张图像中的对应关系,常用方法如flann等。4、消噪:去除错误匹配的外点,保留正确的匹配点。常用方法有KDTREE,BBF,Ransac,GTM等。二、SIFT匹配方法的提出为了排除因为图像遮挡和背景混乱而产生的无匹配关系的关键点,SIFT的作者Lowe提出了比较最近邻距离与次近邻距离的SIFT匹配方式:取一幅图像中的一个SIFT关键点,并找出其与另一幅图像中欧式距离最近的前两个关键点,在这两个关键点中,如果最近的距离除以次近的距离得到的比率ratio少于某个阈值T,则接受这一对匹配点。因为对于错误匹配,由于特征空间的高维性,相似的距离可能有大量其他的错误匹配,从而它的ratio值比较高。显然降低这个比例阈值T,SIFT匹配点数目会减少,但更加稳定,反之亦然。Lowe推荐ratio的阈值为0.8,但作者对大量任意存在尺度、旋转和亮度变化的两幅图片进行匹配,结果表明ratio取值在0.4~0.6之间最佳,小于0.4的很少有匹配点,大于0.6的则存在大量错误匹配点,所以建议ratio的取值原则如下:ratio=0.4:对于准确度要求高的匹配;ratio=0.6:对于匹配点数目要求比较多的匹配;ratio=0.5:一般情况下。三、常见的SIFT匹配代码1、vlfeat中sifttoolbox中的vl_ubcmatch.c使用的是普通的欧氏距离进行匹配(该SIFT代码贡献自AndreaVedaldi)。2、Lowe的C++代码中使用的是欧氏距离,但是在matlab代码中为了加速计算,使用的是向量夹角来近似欧氏距离:先将128维SIFT特征向量归一化为单位向量(每个数除以平方和的平方根),然后点乘来得到向量夹角的余弦值,最后利用反余弦(acos函数)求取向量夹角。实验证明Lowe的法正确率和耗时都很不错。同样,也可以采用knnsearch函数求最近点和次近点:knnsearch采用euclidean距离时得到的结果与lowe采用的近似方法结果几乎一致,正好印证了模拟欧氏距离的效果。3、RobHess的OpenSIFT采用了KDTREE来对匹配进行优化。4、CSDN大神v_JULY_v实现了KDTREE+BBF对SIFT匹配的优化和消除错误匹配:从K近邻算法、距离度量谈到KD树、SIFT+BBF算法-结构之法算法之道-博客频道-CSDN.NET。5、OpenCV中features2d实现的SIFT匹配有多种matcher:VectorDescriptorMatcher,BFMatcher(Brute-forcedescriptormatcher),FernDescriptorMatcher,OneWayDescriptorMatcher,FlannBasedMatcher等等。目前只知道采用knnsearch,提供了多种距离度量方式,具体区别不懂。
‘玖’ 紧急求助:在运行SIFT源码时,由于是matlab和vc混编的,设置了mex后还是显示找不到c文件。
尝试将'imsmooth.c' 也mex,把相关文件拷到vc。编译出来的好像是.mexw32.混编会遇到诸多问题,若还未解决,多贴出些相关信息。我现在也在做混编,不过是基于COM的。
‘拾’ 如何本地安装SIFT
SIFT的实现有很多版本,具体方式都是那么几个,找个好用的不太容易,因为对于代码不熟练者各种版本用起来都有点水土不服,需要调整调整才行。本人是在VS2010下使用的Rob Hess的源码。
一、前提
安装Opencv,详见:VS2010+Opencv-2.4.0的配置攻略(该版本SIFT是基于Opencv的)。
下载SIFT源码,见Rob Hess的主页(别告诉我不懂英文不知道下载链接在哪,下那个Windows VC++的版本 sift-latest_win.zip)。
二、测试
1、解压sift源码,发现有如下文件:
5、C语法设定:分别打开imgfeatures.h和sift.h,让所有函数包含在
#ifdef __cplusplusextern"C"{#endif
和
#ifdef __cplusplus }#endif
之间。例如:
View Code
... #ifdef __cplusplusextern"C"{#endif...externintsift_features( IplImage* img,structfeature**feat ); ...externint_sift_features( IplImage* img,structfeature** feat,intintvls,doublesigma,doublecontr_thr,intcurv_thr,intimg_dbl,intdescr_width,intdescr_hist_bins ); #ifdef __cplusplus }#endif#endif
PS:我只是用了_sift_features(...)等几个函数,所以只加了两个头文件的C语法声明,如果是用了其他的头文件,均需要添加。
6、综上,你应该可以直接使用sift相关函数了,参照siftfeat.c中的写法,用用_sift_features(...)试试!
实际上如果只需要使用SIFT特征提取的函数,前面几步只需要复制imgfeatures.c imgfeatures.h sift.c sift.h utils.c utils.h这6个文件就够了