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

Posted GreenOpen专注图像处理

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了特征提取算法的综合实验(多种角度比较sift/surf/brisk/orb/akze)相关的知识,希望对你有一定的参考价值。

一、基本概念:
作用特征点提取在“目标识别、图像拼接、运动跟踪、图像检索、自动定位”等研究中起着重要作用;
主要算法
SIFT,Distinctive ImageFeatures from Scale-Invariant Keypoints,2004,invariant to image translation, scaling, and rotation, partially invariant toillumination changes and robust to local geometric distortion
SURF,Speeded Up RobustFeatures,2006,SIFT启发,比SIFT快,健壮
ORB,ORB: an efficientalternative to SIFT or SURF,2011,基于FAST,比SIFT快两个数量级,可作为SIFT的替代
GFTTGoodFeatures to Track,1994,Determines strong corners on animage
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;
                BFMatcher matcher;
                switch (imethod)
                {
                case 0: //"SIFT"
                    extractorSIFT::create();
                    matcher = BFMatcher(NORM_L2);    
                    break;
                case 1: //"SURF"
                    extractorSURF::create();
                    matcher = BFMatcher(NORM_L2);    
                    break;
                case 2: //"BRISK"
                    extractor = BRISK::create();
                    matcher = BFMatcher(NORM_HAMMING);
                    break;
                case 3: //"ORB"
                    extractorORB::create();
                    matcher = BFMatcher(NORM_HAMMING);    
                    break;
                case 4: //"AKAZE"
                    extractorAKAZE::create();
                    matcher = BFMatcher(NORM_HAMMING);    
                    break;
                }
                try
                {
                    extractor->detectAndCompute(img1,Mat(),keypoints1,descriptors1);
                    extractor->detectAndCompute(imgn,Mat(),keypoints2,descriptors2);
                    matcher.matchdescriptors1descriptors2matches );
                }
                catch (CExceptione)
                {
                    cout<<" 特征点提取时发生错误 "<<endl;
                    continue;
                }
 
                //对特征点进行粗匹配
                double max_dist = 0; 
                double min_dist = 100;
                forint a = 0; a < matches.size(); a++ )
                {
                    double dist = matches[a].distance;
                    ifdist < min_dist ) min_dist = dist;
                    ifdist > max_dist ) max_dist = dist;
                }
                forint a = 0; a < matches.size(); a++ )
                { 
                    ifmatches[a].distance <= max(2*min_dist, 0.02) )
                        good_matches.push_backmatches[a]); 
                }
                if (good_matches.size()<4)
                {
                    cout<<" 有效特征点数目小于4个,粗匹配失败 "<<endl;
                    continue;
                }
2、对match的结果进行RANSAC提纯计算,计算“内点”。主要是RANSAC提纯的一个过程,这个过程在图像拼接中也是很常见的。
 
                //通过RANSAC方法,对现有的特征点对进行“提纯”
                std::vector<Point2fobj;
                std::vector<Point2fscene;
                forint a = 0; a < (int)good_matches.size(); a++ )
                {    
                    //分别将两处的good_matches对应的点对压入向量,只需要压入点的信息就可以
                    obj.push_backkeypoints1[good_matches[a].queryIdx ].pt );
                    scene.push_backkeypoints2[good_matches[a].trainIdx ].pt );
                }
                //计算单应矩阵(在calib3d中)
                Mat H ;
                try
                {
                    H = findHomographyobjsceneCV_RANSAC );
                }
                catch (CExceptione)
                {
                    cout<<" findHomography失败 "<<endl;
                    continue;
                }
                if (H.rows < 3)
                {
                    cout<<" findHomography失败 "<<endl;
                    continue;
                }
              //计算内点数目
                Mat matObj;
                Mat matScene;
                CvMatpcvMat = &(CvMat)H;
                const doubleHmodel = pcvMat->data.db;
                double Htmp = Hmodel[6];
                forint isize = 0; isize < obj.size(); isize++ )
                {
                    double ww = 1./(Hmodel[6]*obj[isize].x + Hmodel[7]*obj[isize].y + 1.);
                    double dx = (Hmodel[0]*obj[isize].x + Hmodel[1]*obj[isize].y + Hmodel[2])*ww - scene[isize].x;
                    double dy = (Hmodel[3]*obj[isize].x + Hmodel[4]*obj[isize].y + Hmodel[5])*ww - scene[isize].y;
                    float err = (float)(dx*dx + dy*dy); //3个像素之内认为是同一个点
                    if (err< 9)
                    {
                        innersize = innersize+1;
                    }
                }
 
3、比较“耗时”和“内点比例”两个因素。其中建立数学模型,就是用"准确率“/“内点比例”,这样得到一个正向的结论。