OpenCV学习之旅9——特征检测与匹配(2)

1. FLANN结合SURF进行关键点匹配与描述

1.1 程序实例

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/nonfree/features2d.hpp>
#include <opencv2/features2d/features2d.hpp>
using namespace cv;
using namespace std;

//--------------------------------------【main( )函数】-----------------------------------------
//          描述:控制台应用程序的入口函数,我们的程序从这里开始执行
//-----------------------------------------------------------------------------------------------
int main( ) 
{
    //【0】改变console字体颜色
    system("color 6F"); 

    //【1】载入图像、显示并转化为灰度图
    Mat trainImage = imread("1.jpg"), trainImage_gray;
    imshow("原始图",trainImage);
    cvtColor(trainImage, trainImage_gray, CV_BGR2GRAY);

    //【2】检测Surf关键点、提取训练图像描述符
    vector<KeyPoint> train_keyPoint;
    Mat trainDescriptor;
    SurfFeatureDetector featureDetector(80);
    featureDetector.detect(trainImage_gray, train_keyPoint);
    SurfDescriptorExtractor featureExtractor;
    featureExtractor.compute(trainImage_gray, train_keyPoint, trainDescriptor);

    //【3】创建基于FLANN的描述符匹配对象
    FlannBasedMatcher matcher;
    vector<Mat> train_desc_collection(1, trainDescriptor);
    matcher.add(train_desc_collection);
    matcher.train();

    //【4】创建视频对象、定义帧率
    VideoCapture cap(0);
    unsigned int frameCount = 0;//帧数

    //【5】不断循环,直到q键被按下
    while(char(waitKey(1)) != 'q')
    {
        //<1>参数设置
        int64 time0 = getTickCount();
        Mat testImage, testImage_gray;
        cap >> testImage;//采集视频到testImage中
        if(testImage.empty())
            continue;

        //<2>转化图像到灰度
        cvtColor(testImage, testImage_gray, CV_BGR2GRAY);

        //<3>检测S关键点、提取测试图像描述符
        vector<KeyPoint> test_keyPoint;
        Mat testDescriptor;
        featureDetector.detect(testImage_gray, test_keyPoint);
        featureExtractor.compute(testImage_gray, test_keyPoint, testDescriptor);

        //<4>匹配训练和测试描述符
        vector<vector<DMatch> > matches;
        matcher.knnMatch(testDescriptor, matches, 2);

        // <5>根据劳氏算法(Lowe's algorithm),得到优秀的匹配点
        vector<DMatch> goodMatches;
        for(unsigned int i = 0; i < matches.size(); i++)
        {
            if(matches[i][0].distance < 0.6 * matches[i][1].distance)
                goodMatches.push_back(matches[i][0]);
        }

        //<6>绘制匹配点并显示窗口
        Mat dstImage;
        drawMatches(testImage, test_keyPoint, trainImage, train_keyPoint, goodMatches, dstImage);
        imshow("匹配窗口", dstImage);

        //<7>输出帧率信息
        cout << "当前帧率为:" << getTickFrequency() / (getTickCount() - time0) << endl;
    }

    return 0;
}

2. SIFT配合暴力匹配进行关键点描述与提取

SURF与SIFT算法的比较:
这里写图片描述
理论上SURF要比SIFT快三倍。

2.1 程序实例

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/nonfree/features2d.hpp>
#include <opencv2/features2d/features2d.hpp>
using namespace cv;
using namespace std;

//--------------------------------------【main( )函数】-----------------------------------------
//          描述:控制台应用程序的入口函数,我们的程序从这里开始执行
//-----------------------------------------------------------------------------------------------
int main()
{
    //【0】改变console字体颜色
    system("color 5F"); 

    //【1】载入图像、显示并转化为灰度图
    Mat trainImage = imread("2.jpg"), trainImage_gray;
    imshow("原始图",trainImage);
    cvtColor(trainImage, trainImage_gray, CV_BGR2GRAY);

    //【2】检测SIFT关键点、提取训练图像描述符
    vector<KeyPoint> train_keyPoint;
    Mat trainDescription;
    SiftFeatureDetector featureDetector;
    featureDetector.detect(trainImage_gray, train_keyPoint);
    SiftDescriptorExtractor featureExtractor;
    featureExtractor.compute(trainImage_gray, train_keyPoint, trainDescription);

    // 【3】进行基于描述符的暴力匹配
    BFMatcher matcher;
    vector<Mat> train_desc_collection(1, trainDescription);
    matcher.add(train_desc_collection);
    matcher.train();

    //【4】创建视频对象、定义帧率
    VideoCapture cap(0);
    unsigned int frameCount = 0;//帧数

    //【5】不断循环,直到q键被按下
    while(char(waitKey(1)) != 'q')
    {
        //<1>参数设置
        double time0 = static_cast<double>(getTickCount( ));//记录起始时间
        Mat captureImage, captureImage_gray;
        cap >> captureImage;//采集视频到testImage中
        if(captureImage.empty())
            continue;

        //<2>转化图像到灰度
        cvtColor(captureImage, captureImage_gray, CV_BGR2GRAY);

        //<3>检测SURF关键点、提取测试图像描述符
        vector<KeyPoint> test_keyPoint;
        Mat testDescriptor;
        featureDetector.detect(captureImage_gray, test_keyPoint);
        featureExtractor.compute(captureImage_gray, test_keyPoint, testDescriptor);

        //<4>匹配训练和测试描述符
        vector<vector<DMatch> > matches;
        matcher.knnMatch(testDescriptor, matches, 2);

        // <5>根据劳氏算法(Lowe's algorithm),得到优秀的匹配点
        vector<DMatch> goodMatches;
        for(unsigned int i = 0; i < matches.size(); i++)
        {
            if(matches[i][0].distance < 0.6 * matches[i][1].distance)
                goodMatches.push_back(matches[i][0]);
        }

        //<6>绘制匹配点并显示窗口
        Mat dstImage;
        drawMatches(captureImage, test_keyPoint, trainImage, train_keyPoint, goodMatches, dstImage);
        imshow("匹配窗口", dstImage);

        //<7>输出帧率信息
        cout << "\t>当前帧率为:" << getTickFrequency() / (getTickCount() - time0) << endl;
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值