失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 特征提取算法的综合实验(多种角度比较sift/surf/brisk/orb/akze)

特征提取算法的综合实验(多种角度比较sift/surf/brisk/orb/akze)

时间:2020-10-10 06:11:52

相关推荐

特征提取算法的综合实验(多种角度比较sift/surf/brisk/orb/akze)

一、基本概念:作用:特征点提取在“目标识别、图像拼接、运动 跟踪、图像检索、自动定位”等研究中起着重要作用;主要算法: •FAST , Machine Learning forHigh-speed Corner Detection, • SIFT, Distinctive ImageFeatures from Scale-Invariant Keypoints, ,invariant to image translation, scaling, and rotation, partially invariant toillumination changes and robust to local geometric distortion • SURF, Speeded Up RobustFeatures, , 受 SIFT 启发,比 SIFT 快,健壮 • ORB, ORB: an efficientalternative to SIFT or SURF, ,基于 FAST ,比 SIFT 快两个数量级,可作为 SIFT 的替代 • BRISK , BRISK:Binary Robust Invariant Scalable Keypoints •STAR , Censure: Centersurround extremas for realtime featuredetection and matching, 引用次数不高 •MSER , RobustWide Baseline Stereo from Maximally Stable Extremal Regions,2002, 斑点检测 •GFTT , GoodFeatures to Track,1994,Determines strong corners on animage •HARRIS, Harris and M. Stephens (1988).“A combined corner and edge detector”, 也是一种角点检测 方法 •FREAK •AKAZE等 其中标红的5项是在OpenCV中已经进行了实现的。特征点识别主要流程为:1、检测关键点、提取描述向量和特征匹配; 2、通过检测关键点和提取描述向量构造出局部特征描述子, 3、然后进行特征匹配 二、数据准备: 数据集为pascal中取出的6个数据,分别针对特征点提取的6个方面 其中特征点识别在以下6个方面进行比较1、算法匹配速度比较 (ubc) 测试方法:在相同的匹配环境下,即使用同样配置的计算机,对相同的一对图像进行比较,测试算法的执行时间 2、旋转变换鲁棒性比较 (bark) 测试方法:对同一图像进行一定角度的旋转,旋转角度逐步递增,旋转后的图像逐一与原始图像进行匹配,比较能够正确匹配的特征点对数,并观察正确匹配对数的变化幅度 3、模糊变换鲁棒性比较 (bikes) 测试方法:对同一图像用不同的高斯核进行模糊处理,模糊处理后的图像逐一与原始图像进 行匹配,比较能够正确匹配的特征点对数,并观察正确匹配对数的变化幅度 4、光照变换鲁棒性比较 (leuven) 测试方法:对同一图像的亮度进行改变,逐 渐降低亮度,改变亮度后的图像逐一与原始图像进行匹配,比较能够正确匹配的特征点对数,并观察正确匹配对数的变化幅度 5、尺度变换鲁棒性比较 (bark) 测试方法:对原图像的尺度大小进行改变,尺度变化后的图像逐一与原始图像进行匹配,比较能够正确匹配的特征点对数,并观察正确匹配对数的变化幅度 6、视角变换鲁棒性比较 (graf) 测试方法:对原场景转一定角度进行拍摄,不同视角的图像逐一与原始图像进行匹配,比较能够正确匹配的特征点对数,并观察正确匹配对 数的变化幅度三、实验步骤:1、依次对各个数据集进行特征点提取并进行两两特征点的比较,也就是match。这个流程是正常的流程,执行的过程中要注意错误控制//使用img1对比余下的图片,得出结果 img1=imread(files[0],0); imgn=imread(files[iimage],0); //生成特征点算法及其匹配方法 Ptr<Feature2D>extractor; BFMatchermatcher; switch(imethod) {case0://"SIFT" extractor=SIFT::create(); matcher=BFMatcher(NORM_L2); break; case1://"SURF" extractor=SURF::create(); matcher=BFMatcher(NORM_L2); break; case2://"BRISK" extractor=BRISK::create(); matcher=BFMatcher(NORM_HAMMING); break; case3://"ORB" extractor=ORB::create(); matcher=BFMatcher(NORM_HAMMING); break; case4://"AKAZE" extractor=AKAZE::create(); matcher=BFMatcher(NORM_HAMMING); break; } try {extractor->detectAndCompute(img1,Mat(),keypoints1,descriptors1); extractor->detectAndCompute(imgn,Mat(),keypoints2,descriptors2); matcher.match(descriptors1,descriptors2,matches); } catch(CException*e) {cout<<"特征点提取时发生错误"<<endl; continue; } //对特征点进行粗匹配 doublemax_dist=0; doublemin_dist=100; for(inta=0;a<matches.size();a++) {doubledist=matches[a].distance; if(dist<min_dist)min_dist=dist; if(dist>max_dist)max_dist=dist; } for(inta=0;a<matches.size();a++) { if(matches[a].distance<=max(2*min_dist,0.02)) good_matches.push_back(matches[a]); } if(good_matches.size()<4) {cout<<"有效特征点数目小于4个,粗匹配失败"<<endl; continue; }2、对match的结果进行RANSAC提纯计算,计算“内点”。主要是RANSAC提纯的一个过程,这个过程在图像拼接中也是很常见的。//通过RANSAC方法,对现有的特征点对进行“提纯” std::vector<Point2f>obj; std::vector<Point2f>scene; for(inta=0;a<(int)good_matches.size();a++) { //分别将两处的good_matches对应的点对压入向量,只需要压入点的信息就可以 obj.push_back(keypoints1[good_matches[a].queryIdx].pt); scene.push_back(keypoints2[good_matches[a].trainIdx].pt); } //计算单应矩阵(在calib3d中) MatH; try {H=findHomography(obj,scene,CV_RANSAC); } catch(CException*e) {cout<<"findHomography失败"<<endl; continue; } if(H.rows<3) {cout<<"findHomography失败"<<endl; continue; } //计算内点数目 MatmatObj; MatmatScene; CvMat*pcvMat=&(CvMat)H; constdouble*Hmodel=pcvMat->data.db; doubleHtmp=Hmodel[6]; for(intisize=0;isize<obj.size();isize++) {doubleww=1./(Hmodel[6]*obj[isize].x+Hmodel[7]*obj[isize].y+1.); doubledx=(Hmodel[0]*obj[isize].x+Hmodel[1]*obj[isize].y+Hmodel[2])*ww-scene[isize].x; doubledy=(Hmodel[3]*obj[isize].x+Hmodel[4]*obj[isize].y+Hmodel[5])*ww-scene[isize].y; floaterr=(float)(dx*dx+dy*dy);//3个像素之内认为是同一个点 if(err<9) {innersize=innersize+1; } }3、比较“耗时”和“内点比例”两个因素。其中建立数学模型,就是用"准确率“/“内点比例”,这样得到一个正向的结论。4、结合相关数据,得出综合结论四、实验结果:1、sift和surf一直提供了较高的准确率,并且结果比较稳定;sift较surf更准一些,但是也有brisk最好的时候;2、orb的速度非常快,但是最容易出现问题;3、AKAZA也很容易出现问题;4、其他算法,包括AKAZA,速度的差别都不是很大。五、结论那么我们在做大型特征点提取的算法的时候,就需要综合考虑速度、准确率等多种要素;很可能要自己设计新的算法,将这几种典型算法包含其中,扬长避短了。附: 配套课程: /course/11555.html (实验可以免费观看)//遍历dateset,分别对SIFT、SURF、BRISK、ORB、FREAK算法进行运算,得出初步结论 //jsxyhelu11月3日 #include"stdafx.h" #include<opencv2/core/utility.hpp> #include"opencv2/imgproc.hpp" #include"opencv2/videoio.hpp" #include"opencv2/highgui.hpp" #include"opencv2/calib3d.hpp" #include"opencv2/xfeatures2d.hpp" #include<iostream> #include<ctype.h> #include"GOCVHelper.h" #defineDATESET_COUNT8 #defineMETHOD_COUNT5 usingnamespacecv; usingnamespacestd; usingnamespacexfeatures2d; voidmain() {stringstrDateset[DATESET_COUNT]; strDateset[0]="bark";strDateset[1]="bikes";strDateset[2]="boat";strDateset[3]="graf";strDateset[4]="leuven"; strDateset[5]="trees";strDateset[6]="ubc";strDateset[7]="wall"; stringstrMethod[METHOD_COUNT]; strMethod[0]="SIFT";strMethod[1]="SURF";strMethod[2]="BRISK";strMethod[3]="ORB";strMethod[4]="AKAZE"; 递归读取目录下全部文件 vector<string>files; Matdescriptors1; std::vector<KeyPoint>keypoints1; Matdescriptors2; std::vector<KeyPoint>keypoints2; std::vector<DMatch>matches; std::vector<DMatch>good_matches; 用于模型验算 intinnersize=0; Matimg1; Matimgn; int64t=getTickCount(); std::cout<<"SIFT、SURF、BRISK、ORB、AKAZE算法测试实验开始"<<endl; //遍历各种特征点寻找方法 for(intimethod=METHOD_COUNT-1;imethod<METHOD_COUNT;imethod++) {string_strMethod=strMethod[imethod]; std::cout<<"开始测试"<<_strMethod<<"方法"<<endl; //遍历各个路径 for(intidateset=0;idateset<DATESET_COUNT;idateset++) {//获得测试图片绝对地址 stringpath="E:/template/dateset/"+strDateset[idateset]; std::cout<<"数据集为"<<strDateset[idateset]; //获得当个数据集中的图片 GO::getFiles(path,files,"r"); std::cout<<"共"<<files.size()<<"张图片"<<endl; for(intiimage=1;iimage<files.size();iimage++) {//使用img1对比余下的图片,得出结果 img1=imread(files[0],0); imgn=imread(files[iimage],0); //生成特征点算法及其匹配方法 Ptr<Feature2D>extractor; BFMatchermatcher; switch(imethod) {case0://"SIFT" extractor=SIFT::create(); matcher=BFMatcher(NORM_L2); break; case1://"SURF" extractor=SURF::create(); matcher=BFMatcher(NORM_L2); break; case2://"BRISK" extractor=BRISK::create(); matcher=BFMatcher(NORM_HAMMING); break; case3://"ORB" extractor=ORB::create(); matcher=BFMatcher(NORM_HAMMING); break; case4://"AKAZE" extractor=AKAZE::create(); matcher=BFMatcher(NORM_HAMMING); break; } try {extractor->detectAndCompute(img1,Mat(),keypoints1,descriptors1); extractor->detectAndCompute(imgn,Mat(),keypoints2,descriptors2); matcher.match(descriptors1,descriptors2,matches); } catch(CException*e) {cout<<"特征点提取时发生错误"<<endl; continue; } //对特征点进行粗匹配 doublemax_dist=0; doublemin_dist=100; for(inta=0;a<matches.size();a++) {doubledist=matches[a].distance; if(dist<min_dist)min_dist=dist; if(dist>max_dist)max_dist=dist; } for(inta=0;a<matches.size();a++) { if(matches[a].distance<=max(2*min_dist,0.02)) good_matches.push_back(matches[a]); } if(good_matches.size()<4) {cout<<"有效特征点数目小于4个,粗匹配失败"<<endl; continue; } //通过RANSAC方法,对现有的特征点对进行“提纯” std::vector<Point2f>obj; std::vector<Point2f>scene; for(inta=0;a<(int)good_matches.size();a++) { //分别将两处的good_matches对应的点对压入向量,只需要压入点的信息就可以 obj.push_back(keypoints1[good_matches[a].queryIdx].pt); scene.push_back(keypoints2[good_matches[a].trainIdx].pt); } //计算单应矩阵(在calib3d中) MatH; try {H=findHomography(obj,scene,CV_RANSAC); } catch(CException*e) {cout<<"findHomography失败"<<endl; continue; } if(H.rows<3) {cout<<"findHomography失败"<<endl; continue; } //计算内点数目 MatmatObj; MatmatScene; CvMat*pcvMat=&(CvMat)H; constdouble*Hmodel=pcvMat->data.db; doubleHtmp=Hmodel[6]; for(intisize=0;isize<obj.size();isize++) {doubleww=1./(Hmodel[6]*obj[isize].x+Hmodel[7]*obj[isize].y+1.); doubledx=(Hmodel[0]*obj[isize].x+Hmodel[1]*obj[isize].y+Hmodel[2])*ww-scene[isize].x; doubledy=(Hmodel[3]*obj[isize].x+Hmodel[4]*obj[isize].y+Hmodel[5])*ww-scene[isize].y; floaterr=(float)(dx*dx+dy*dy);//3个像素之内认为是同一个点 if(err<9) {innersize=innersize+1; } } //打印内点占全部特征点的比率 floatff=(float)innersize/(float)good_matches.size(); cout<<ff; //打印时间 cout<<""<<((getTickCount()-t)/getTickFrequency())<<endl; t=getTickCount(); //如果效果较好,则打印出来 MatmatTmp; if(ff==1.0) {drawMatches(img1,keypoints1,imgn,keypoints2,good_matches,matTmp); charcharJ[255];sprintf_s(charJ,"_%d.jpg",iimage); stringstrResult="E:/template/result/"+strDateset[idateset]+_strMethod+charJ; imwrite(strResult,matTmp); } ff=0; innersize=0; matches.clear(); good_matches.clear(); } files.clear(); } } getchar(); waitKey(); return; };

如果觉得《特征提取算法的综合实验(多种角度比较sift/surf/brisk/orb/akze)》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。