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;
}

程序运行前的原始图片

3. opencv进行SIFT特征提取
opencv中sift特征提取的步骤
代码
程序运行前的原始图片
提取特征点后
进行匹配后
相关代码介绍
3. opencv进行SIFT特征提取
opencv中sift特征提取的步骤
代码
程序运行前的原始图片
提取特征点后
进行匹配后
相关代码介绍

提取特征点后

3. opencv进行SIFT特征提取
opencv中sift特征提取的步骤
代码
程序运行前的原始图片
提取特征点后
进行匹配后
相关代码介绍
3. opencv进行SIFT特征提取
opencv中sift特征提取的步骤
代码
程序运行前的原始图片
提取特征点后
进行匹配后
相关代码介绍

进行匹配后

3. opencv进行SIFT特征提取
opencv中sift特征提取的步骤
代码
程序运行前的原始图片
提取特征点后
进行匹配后
相关代码介绍

相关代码介绍

    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编辑器编写.