zoukankan      html  css  js  c++  java
  • 3. opencv进行SIFT特征提取

    opencv中sift特征提取的步骤

    1. 使用SiftFeatureDetector的detect方法检测特征存入一个向量里,并使用drawKeypoints在图中标识出来
    2. SiftDescriptorExtractor 的compute方法提取特征描述符,特征描述符是一个矩阵
    3. 使用匹配器matcher对描述符进行匹配,匹配结果保存由DMatch的组成的向量里
    4. 设置距离阈值,使得匹配的向量距离小于最小距离的2被才能进入最终的结果,用DrawMatch可以显示

    代码

    // 使用Flann进行特征点匹配.cpp : 定义控制台应用程序的入口点。
    //
    #include "stdafx.h"
    #include <opencv2/opencv.hpp>
    #include <highgui/highgui.hpp>
    #include <features2d/features2d.hpp>
    #include <nonfree/nonfree.hpp>
    #include <vector>
    using namespace cv;
    using namespace std;
    int _tmain(int argc, _TCHAR* argv[])
    {
        Mat input1 = imread("E://code//test//image//box.png", 1);
        Mat input2 = imread("E://code//test//image//box_in_scene.jpg", 1);
        if (input1.empty()||input2.empty())
        {
            cout << "不能正常加载图片" << endl;
            system("pause");
            return -1;
        }
        /************************************************************************/
        /*下面进行提取特征点*/
        /************************************************************************/
        SiftFeatureDetector feature;
        vector<KeyPoint> kerpoints1;
        feature.detect(input1, kerpoints1);
        Mat output1;
        drawKeypoints(input1, kerpoints1, output1);
        vector<KeyPoint> kerpoints2;
        feature.detect(input2, kerpoints2);
        Mat output2;
        drawKeypoints(input2, kerpoints2, output2);
        imshow("提取特征点后的box.png", output1);
        imshow("提取特征点后的box_in_scene.png", output2);
        imwrite("提取特征点后的box.png", output1);
        imwrite("提取特征点后的box_in_scene.png", output2);
        cout << "box提取的特征点数为:" << kerpoints1.size() << endl;
        cout << "box_in_scene的特征点数为:" << kerpoints2.size() << endl;
        /************************************************************************/
        /* 下面进行特征向量提取 */
        /************************************************************************/
        SiftDescriptorExtractor descript;
        Mat description1;
        descript.compute(input1, kerpoints1, description1);
        Mat description2;
        descript.compute(input2, kerpoints2, description2);
        /************************************************************************/
        /* 下面进行特征向量临近匹配 */
        /************************************************************************/
        vector<DMatch> matches;
        FlannBasedMatcher matcher;
        Mat image_match;
        matcher.match(description1, description2, matches);
        /************************************************************************/
        /* 下面计算向量距离的最大值与最小值 */
        /************************************************************************/
        double max_dist = 0, min_dist = 100;
        for (int i = 0; i < description1.rows; i++)
        {
            if (matches.at(i).distance>max_dist)
            {
                max_dist = matches[i].distance;
            }
            if (matches[i].distance<min_dist)
            {
                min_dist = matches[i].distance;
            }
        }
        cout << "最小距离为" << min_dist << endl;
        cout << "最大距离为" << max_dist << endl;
        /************************************************************************/
        /* 得到距离小于而V诶最小距离的匹配 */
        /************************************************************************/
        vector<DMatch> good_matches;
        for (int i = 0; i < matches.size(); i++)
        {
            if (matches[i].distance<2*min_dist)
            {
                good_matches.push_back(matches[i]);
                cout <<"第一个图中的"<< matches[i].queryIdx<<"匹配了第二个图中的"<<matches[i].trainIdx<<endl;
            }
        }
        drawMatches(input1, kerpoints1, input2, kerpoints2, good_matches, image_match);
        imshow("匹配后的图片", image_match);
        imwrite("匹配后的图片.png", image_match);
        cout << "匹配的特征点数为:" << good_matches.size() << endl;
        waitKey(0);
        return 0;
    }

    程序运行前的原始图片

    box.png
    box_in_scene.png

    提取特征点后

    box提取特征后
    这里写图片描述

    进行匹配后

    这里写图片描述

    相关代码介绍

        double max_dist = 0, min_dist = 100;
        for (int i = 0; i < description1.rows; i++)
        {
            if (matches.at(i).distance>max_dist)
            {
                max_dist = matches[i].distance;
            }
            if (matches[i].distance<min_dist)
            {
                min_dist = matches[i].distance;
            }
        }  

    设置阈值,当特征向量的距离在最小距离的二倍范围内的,匹配为好的匹配;

    本博文由时尚时尚最时尚的markdown编辑器编写.

  • 相关阅读:
    快速排序和归并排序的迭代实现
    Longest Increasing Subsequence Review
    IOCCC 1987 最佳单行代码解读
    C++类的成员函数对应的链接器符号的解析
    Scalable Global ID Generator Design
    欧拉回路 (Euler Circuit) POJ 1780
    深入理解函数内静态局部变量初始化
    memcached 线程模型
    类的加载与ClassLoader的理解
    字符集常见码表说明
  • 原文地址:https://www.cnblogs.com/dragonfive/p/4498644.html
Copyright © 2011-2022 走看看