【opencv学习之四十一】SIFT和SUFT算法

本文通过实例演示了SIFT和SURF两种图像特征提取算法的应用过程,包括关键点检测、描述符计算及匹配,并提供了筛选匹配结果的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SIFT和SUFT算法是有相关专利的,所以在opencv中属于"nonfree"里的,在opencv2.x.x版本可能还有保留,但是在opencv3.x.x后就没有了,需要单独下载opencv_contrib库,然后自己Cmake;

相关算法的详解这里不做过多解释了,推举两个大神博客:

1.小魏的修行的博客:http://blog.youkuaiyun.com/xiaowei_cqu/article/details/8069548;

2.赵春江的源码详细分析:http://blog.youkuaiyun.com/zhaocj/article/details/42124473;

3.详细分析算法原理:http://blog.youkuaiyun.com/zddblog/article/details/7521424;

大家可以在网上再看看,相关解释等很多;

下面贴几个简单实例:

sift实例:

void imgSIFT()//SIFT算法
{
    //sift算法不是开源的所以很多内容用起来很不方便
    //Create SIFT class pointer
    Ptr<Feature2D> f2d = xfeatures2d::SIFT::create();
    //1、读入图片
    Mat img_1 = imread("D:/ImageTest/source.png");//模板图片
    Mat img_2 = imread("D:/ImageTest/222.JPG");//检测图片
    //2、声明检测点;Detect the keypoints
    vector<KeyPoint> keypoints_1, keypoints_2;
    f2d->detect(img_1, keypoints_1);
    f2d->detect(img_2, keypoints_2);
    //3、计算描述符(特征向量);Calculate descriptors (feature vectors)
    Mat descriptors_1, descriptors_2;
    f2d->compute(img_1, keypoints_1, descriptors_1);
    f2d->compute(img_2, keypoints_2, descriptors_2);
    //4、使用BFMatcher匹配描述符向量;Matching descriptor vector using BFMatcher
    BFMatcher matcher;
    vector<DMatch> matches;
    matcher.match(descriptors_1, descriptors_2, matches);
    //5、绘制匹配出的关键点
    Mat img_matches;
    drawMatches(img_1, keypoints_1, img_2, keypoints_2, matches, img_matches);
    imshow("match",img_matches);
    //6、匹配结果筛选
    nth_element(matches.begin(), matches.begin()+30, matches.end());   //提取出前最佳匹配结果
    matches.erase(matches.begin()+30, matches.end());    //剔除掉其余的匹配结果
    Mat img_matches2;
    drawMatches(img_1, keypoints_1, img_2, keypoints_2, matches, img_matches2);
    imshow("match2",img_matches2);
    waitKey(0);
}

效果,未过滤:


过滤后:


SURF算法:

void imgSURF()//SURF算法
{
    //1、加载图片
    Mat img_1 = imread( "D:/ImageTest/source.png", IMREAD_GRAYSCALE );//模板图片
    Mat img_2 = imread("D:/ImageTest/222.JPG", IMREAD_GRAYSCALE );//被查找图片
    //2、使用SURF检测器检测关键点,计算描述符;Detect the keypoints using SURF Detector, compute the descriptors
    int minHessian = 400;
    Ptr<SURF> detector = SURF::create();
    detector->setHessianThreshold(minHessian);
    std::vector<KeyPoint> keypoints_1, keypoints_2;
    Mat descriptors_1, descriptors_2;
    detector->detectAndCompute( img_1, Mat(), keypoints_1, descriptors_1 );
    detector->detectAndCompute( img_2, Mat(), keypoints_2, descriptors_2 );
    //3、匹配描述符向量与一个蛮力匹配;Matching descriptor vectors with a brute force matcher
    BFMatcher matcher(NORM_L2);
    std::vector< DMatch > matches;
    matcher.match( descriptors_1, descriptors_2, matches );
    //4、绘制匹配结果;Draw matches
    Mat img_matches;
    drawMatches( img_1, keypoints_1, img_2, keypoints_2, matches, img_matches );
    //5、显示检测到匹配; Show detected matches
    imshow("SURF_Matches", img_matches );
    //6、匹配结果筛选
    nth_element(matches.begin(), matches.begin()+50, matches.end());   //提取出前最佳匹配结果
    matches.erase(matches.begin()+50, matches.end());    //剔除掉其余的匹配结果
    Mat img_matches2;
    drawMatches(img_1, keypoints_1, img_2, keypoints_2, matches, img_matches2);
    imshow("SURF_Matches2",img_matches2);
    waitKey(0);
}

效果:



SURF算法计算匹配(opencv文档实例),并输出点信息:

void imgSURF2()//SURF算法2
{
      Mat img_1 = imread( "D:/ImageTest/source.png", IMREAD_GRAYSCALE );
      Mat img_2 = imread("D:/ImageTest/222.JPG", IMREAD_GRAYSCALE );
      if( !img_1.data || !img_2.data )
      { std::cout<< " --(!) Error reading images " << std::endl; }
      //-- Step 1: Detect the keypoints using SURF Detector, compute the descriptors
      int minHessian = 400;
      Ptr<SURF> detector = SURF::create();
      detector->setHessianThreshold(minHessian);
      std::vector<KeyPoint> keypoints_1, keypoints_2;
      Mat descriptors_1, descriptors_2;
      detector->detectAndCompute( img_1, Mat(), keypoints_1, descriptors_1 );
      detector->detectAndCompute( img_2, Mat(), keypoints_2, descriptors_2 );
      //-- Step 2: Matching descriptor vectors using FLANN matcher
      FlannBasedMatcher matcher;
      std::vector< DMatch > matches;
      matcher.match( descriptors_1, descriptors_2, matches );
      double max_dist = 0; double min_dist = 100;
      //-- Quick calculation of max and min distances between keypoints
      for( int i = 0; i < descriptors_1.rows; i++ )
      { double dist = matches[i].distance;
        if( dist < min_dist ) min_dist = dist;
        if( dist > max_dist ) max_dist = dist;
      }
      printf("-- Max dist : %f \n", max_dist );
      printf("-- Min dist : %f \n", min_dist );
      //-- Draw only "good" matches (i.e. whose distance is less than 2*min_dist,
      //-- or a small arbitary value ( 0.02 ) in the event that min_dist is very
      //-- small)
      //-- PS.- radiusMatch can also be used here.
      std::vector< DMatch > good_matches;
      for( int i = 0; i < descriptors_1.rows; i++ )
      { if( matches[i].distance <= max(2*min_dist, 0.02) )
        { good_matches.push_back( matches[i]); }
      }
      //-- Draw only "good" matches
      Mat img_matches;
      drawMatches( img_1, keypoints_1, img_2, keypoints_2,
                   good_matches, img_matches, Scalar::all(-1), Scalar::all(-1),
                   vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );
      //-- Show detected matches
      imshow( "Good Matches", img_matches );
      for( int i = 0; i < (int)good_matches.size(); i++ )
      { printf( "-- Good Match [%d] Keypoint 1: %d  -- Keypoint 2: %d  \n", i, good_matches[i].queryIdx, good_matches[i].trainIdx ); }

      cout<<"key:"<<keypoints_1[0].pt.x<<endl;
      waitKey(0);
}

效果:




### 回答1: OpenCV是一个开源的计算机视觉机器学习库,提供了丰富的图像处理计算机视觉算法,被广泛用于图像识别、目标检测图像处理等各个领域。 SURF(Speeded-Up Robust Features)是一种用于图像特征提取匹配的算法。与传统的特征提取算法相比,SURF算法具有更快的计算速度较好的鲁棒性。 在OpenCV中,SURF算法可以通过调用相关的函数来实现。首先,需要导入相应的模块以及图像数据。然后,可以利用SURF算法提取图像的关键点描述子。通过对多幅图像提取的特征进行匹配,可以实现图像的配准、目标识别等应用。 使用SURF算法需要注意的是,对于一些特别大的图像或需要处理大规模数据的情况,可能会导致计算速度较慢。此时可以考虑使用SIFT算法(Scale-Invariant Feature Transform)或其他更适合的特征提取算法。 总之,OpenCV中的SURF算法提供了一种快速而鲁棒的图像特征提取方法,可以广泛应用于计算机视觉机器学习等领域。通过调用相关函数,可以实现对图像进行特征提取匹配,从而实现目标检测、图像配准等应用。 ### 回答2: OpenCV SURF (Speeded-Up Robust Features) 是计算机视觉领域中常用的一种特征提取算法。它借鉴了SIFT算法的思想,并对其进行了改进以提高算法运行速度。 SURF算法通过在图像中检测描述特征点来提取图像中的特征。SURF在每个尺度下使用盒状滤波器对图像进行平滑处理,并使用Hessian行列式来检测关键点。这些关键点由特征点检测器筛选出来,并通过计算Haar小波响应来确定其位置。然后,通过计算关键点周围区域的Hessian矩阵Hessian矩阵的特征值,我们可以确定特征点的主方向,以及描述子的生成方式。 相比于其他特征提取算法,SURF有以下优点:1)通过对图像进行预处理,SURF算法可以在不同尺度下检测到更多的关键点,从而提高了算法的鲁棒性;2)SURF算法使用快速Hessian矩阵特征计算技术,大大加快了算法的运行速度;3)SURF算法生成的描述子具有较小的维度,适合于高效的图像匹配检索。 OpenCV是一个开源的计算机视觉库,它提供了丰富的函数工具来实现SURF算法。通过OpenCV中的SURF函数,我们可以轻松地在图像中检测提取SURF特征,从而实现图像特征匹配、目标跟踪、图像拼接等应用。 ### 回答3: OpenCV SURF是一种用于图像特征提取匹配的算法。SURF是Speeded-Up Robust Features的缩写,意为快速稳健特征。 OpenCV是一个开源计算机视觉库,其中包含了许多图像处理计算机视觉算法,包括SURF算法。使用OpenCV SURF可以在图像中检测到特征点,并从这些特征点中提取出描述子,用于后续的特征匹配、物体识别等任务。 SURF算法通过构建尺度空间的高斯金字塔对尺度空间的Hessian矩阵的行列式进行特征点的检测。在特征点检测的基础上,SURF还利用了积分图像计算快速Hessian矩阵的近似值,从而提高了算法的效率。 在特征点提取完成后,OpenCV SURF进一步计算每个特征点的描述子向量。描述子向量对于特征的唯一性稳定性具有重要意义,可以用于特征的匹配对图像的识别。 OpenCV SURF在计算机视觉领域广泛应用,例如图像拼接、物体识别、相机运动估计等任务。由于SURF算法的高效性稳健性,使得OpenCV SURF成为了一种非常重要的图像特征提取方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值