Opencv特征提取

最近复现SLAM14讲第7讲关于ORB的代码,特征提取的原理懂了,opencv里的实现方式,特别是如何构造特征点提取函数、描述子函数和暴力匹配等方法的函数不熟悉,因此翻到了《opencv编程入门》第三版了解了解,对整个流程有了个概念。我发现我的opencv版本不能构建fast的描述子,sift更是没有了,sift好像被专利保护了吧。目前只能用ORB了,其他的也暂时用不到,先不管了。

特征提取构造流程

//关键点
FeatureDetector featuredector;
//还可以Ptr构造智能指针型,比较安全,要指定特征点类型
//Ptr featuredector = ORB::create();
vector<KeyPoint> keypoints1, ketpoints2;
featuredector.detect(image1,keypoints1);

//描述子
Mat descriptor1, descriptor2;
DescriptorExtractor extractor;
//智能指针构造 
Ptr<DescriptorExractor> extractor = ORB::create();
extractor.compute(image1, keypoints1, descriptor1);

//计算距离,通用的方法
Ptr<DescriptorMatcher> mathcer = DescriptorMatcher::create(2);
/*
        FLANNBASED            = 1,
        BRUTEFORCE            = 2,
        BRUTEFORCE_L1         = 3,
        BRUTEFORCE_HAMMING    = 4,
        BRUTEFORCE_HAMMINGLUT = 5,
        BRUTEFORCE_SL2        = 6
*/
//也可以用暴力匹配的名称构造(仅限于BF)
//BFmathcer matcher;
vector<DMatch> matches;
matcher->match(descriptor1,descriptor2, matches);

BruteForce训练

int main()
{
    Mat src_image = imread("3.png",0);

    Ptr<FeatureDetector> featuredector = ORB::create();
    vector<KeyPoint> keypoint1;
    featuredector->detect(src_image,keypoint1);

    //descriptor
    Ptr<DescriptorExtractor> descriptorExtractor = ORB::create();
    Mat descriptor1;
    descriptorExtractor->compute(src_image,keypoint1,descriptor1);

    //训练BF //TODO
    BFMatcher matcher;
    vector<Mat> train_desc(1,descriptor1);
    matcher.add(train_desc);
    matcher.train();



    VideoCapture cap(0);

    while(char(waitKey(1))!='q')
    {
        Mat captureimage;
        double time0 = cvGetTickCount();
        cap >> captureimage;
        cvtColor(captureimage,captureimage,COLOR_RGB2GRAY);
        if (captureimage.empty())
            continue;

        vector<KeyPoint> keypoint2;
        featuredector->detect(captureimage,keypoint2);

        Mat descriptor2;
        descriptorExtractor->compute(captureimage,keypoint2,descriptor2);

        //knn树匹配
        vector<vector<DMatch>> matches;
        matcher.knnMatch(descriptor2,matches,2);

        vector<DMatch> goodmatches;
        for (int i = 0; i < matches.size(); ++i) {
            if (matches[i][0].distance < matches[i][1].distance * 0.6)
                goodmatches.push_back(matches[i][0]);
        }

        Mat dstimage;
        drawMatches(src_image,keypoint1,captureimage,keypoint2,goodmatches,dstimage);
        imshow("dstimage",dstimage);
        cout << "frame fs = " << getTickFrequency() / (cvGetTickCount() - time0) << endl;
    }

    return 0;

}

ORB特征提取构造

//初始化ORB特征点提取器,描述子、距离计算——bruteforce
    Ptr<FeatureDetector> orb = ORB::create();
    vector<KeyPoint> KeyPoints1_, KeyPOints2_;
    Ptr<DescriptorExtractor> extractor = ORB::create();
    vector<DMatch> matches;

    orb->detect(image_1,KeyPoints1_);
    orb->detect(image_2,KeyPOints2_);


    Mat descriptor1, descriptor2;
    extractor->compute(image_1,KeyPoints1_,descriptor1);
    extractor->compute(image_2,KeyPOints2_,descriptor2);
    
    //暴力匹配
    BFMatcher matcher;
    matcher.match(descriptor1,descriptor2,matches);

    //找到最大、最小距离
    double min_dst = 1000000.0;
    double max_dst = 0.0;
    for (int i = 0; i < matches.size(); ++i) {
        if (matches[i].distance < min_dst)
            min_dst = matches[i].distance;
    }

    //筛除误匹配特征
    vector<DMatch> goodmatches;
    for (int j = 0; j < matches.size(); ++j) {
        if (matches[j].distance <= max(30.0, 2*min_dst))
            goodmatches.push_back(matches[j]);
    }

你可能感兴趣的:(opencv,计算机视觉)