SIFT的两个版本:OpenCV和VL_SIFT

暂时记录一下

OpenCV版本:

#include<iostream>
#include<opencv2/opencv.hpp>
#include<opencv2/core.hpp>
#include<opencv2/features2d.hpp>
#include <opencv2/xfeatures2d/nonfree.hpp>

using namespace std;
using namespace cv;
using namespace cv::xfeatures2d;

int main(int argc, char* argv[]) {
   

    Mat img_object = imread("a.jpg", IMREAD_GRAYSCALE);
    Mat img_scene = imread("b.jpg", IMREAD_GRAYSCALE);

    Ptr<SIFT> detector = SIFT::create(argc > 1 ? atoi(argv[1]) : 400);

    if (img_object.empty() || img_scene.empty()) {
   
        cout << "Could not open or find the image!\n" << endl;
        return -1;
    }

    std::vector<KeyPoint> keypoints_object, keypoints_scene;
    Mat descriptors_object, descriptors_scene;
    detector->detectAndCompute(img_object, noArray(), keypoints_object, descriptors_object);
    detector->detectAndCompute(img_scene, noArray(), keypoints_scene, descriptors_scene);

    //-- Step 2: Matching descriptor vectors with a FLANN based matcher
    // Since SURF is a floating-point descriptor NORM_L2 is used
    Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create(DescriptorMatcher::FLANNBASED);
    std::vector< std::vector<DMatch> > knn_matches;
    matcher->knnMatch(descriptors_object, descriptors_scene, knn_matches, 2);

    //-- Filter matches using the Lowe's ratio test
    const float ratio_thresh = 0.85f;
    std::vector<DMatch> good_matches;
    for (size_t i = 0; i < knn_matches.size(); i++)
    {
   
        if (knn_matches[i][0].distance < ratio_thresh * knn_matches[i][1].distance)
        {
   
            good_matches.push_back(knn_matches[i][0]);
        }
    }
    img_object = imread("a.jpg");
    img_scene = imread("b.jpg");

    for (auto& k : keypoints_object) {
   
        circle(img_object, k.pt, k.size, CV_RGB(255, 0, 0));
    }
    for (auto& k : keypoints_scene) {
   
        circle(img_scene, k.pt, k.size, CV_RGB(0, 255, 0));
    }
    //-- Draw matches
    Mat img_matches;
    drawMatches(img_object, keypoints_object, img_scene, keypoints_scene, good_matches, img_matches, Scalar::all(-1),
        Scalar::all(-1), std::vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);

    //-- Localize the object
    std::vector<Point2f> obj;
    std::vector<Point2f> scene;

    for (size_t i = 0; i < good_matches.size(); i++)
    {
   
        //-- Get the keypoints from the good matches
        obj.push_back(keypoints_object[good_matches[i].queryIdx].pt);
        scene.push_back(keypoints_scene[good_matches[i].trainIdx].pt);
    }
    /*
        Mat H = findHomography(obj, scene, RANSAC);

        //-- Get the corners from the image_1 ( the object to be "detected" )
        std::vector<Point2f> obj_corners(4);
        obj_corners[0] = Point2f(0, 0);
        obj_corners[1] = Point2f((float)img_object.cols, 0);
        obj_corners[2] = Point2f((float)img_object.cols, (float)img_object.rows);
        obj_corners[3] = Point2f(0, (float)img_object.rows);
        std::vector<Point2f> scene_corners(4);

        perspectiveTransform(obj_corners, scene_corners, H);

        //-- Draw lines between the corners (the mapped object in the scene - image_2 )
        line(img_matches, scene_corners[0] + Point2f((float)img_object.cols, 0),
            scene_corners[1] + Point2f((float)img_object.cols, 0), Scalar(0, 255, 0), 4);
        line(img_matches, scene_corners[1] + Point2f((float)img_object.cols, 0),
            scene_corners[2] + Point2f((float)img_object.cols, 0), Scalar(0, 255, 0), 4);
        line(img_matches, scene_corners[2] + Point2f((float)img_object.cols, 0),
            scene_corners[3] + Point2f((float)img_object.cols, 0), Scalar(0, 255, 0), 4);
        line(img_matches, scene_corners[3] + Point2f((float)img_object.cols, 0),
            scene_corners[0] + Point2f((float)img_object.cols, 0), Scalar(0, 255, 0), 4);
        */
        //-- Show detected matches
    imshow("Good Matches & Object detection", img_matches);

    waitKey();
    return 0;
}

如果要用SURF,改这行代码即可:

//Ptr<SIFT> detector = SIFT::create(argc > 1 ? atoi(argv[1]) : 400);
Ptr<SURF> detector = SURF::create(argc > 1 ? atoi(argv[1]) : 400);

SURF是受专利保护的,所以编译OpenCV的时候需要把Contrib包一起编译,还要勾选OPENCV_ENABLE_NONFREE
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210314181942339.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,tex

_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MTY2NTIyNQ==,size_16,color_FFFFFF,t_70#pic_center)

SURF比较慢,精度怎样不做比较。

VLFeat 的SIFT版本据说比OpenCV好。

官网:https://www.vlfeat.org/

代码下载来后,为Visual Studio 2019建立工程文件 libvlfeat_sift.vcxproj 和vl目录同一级。

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup Label="ProjectConfigurations"> 
    <ProjectConfiguration Include="Debug|x64">
      <Configuration>Debug</Configuration>
      
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值