快速最近邻匹配

这是一个完整的利用Suft快速近邻匹配的程序

#include <opencv2/nonfree/nonfree.hpp>
#include <opencv2/nonfree/features2d.hpp>
#include <opencv.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/core/core.hpp>
#include <vector>
#include <math.h>
#include <opencv2/legacy/legacy.hpp>
using namespace std;
using namespace cv;
double Calcoefficient(const Mat &src1 , const Point2f key1 , const Mat &src2 , const Point2f key2) ;//用于计算匹配点之间的相关系数
    Mat src1 ; Mat src2 ;
    src1 = imread("zhugeleft.jpg") ;
    src2 = imread("zhugeright.jpg") ;
    if (!src1.data || !src2.data)
    {
        cout<<"读取图片失败!\n" ;
        return ;
    }
        SurfFeatureDetector dector(400) ;
    vector<KeyPoint> keypoints_1 , keypoints_2 ; //保存特征点向量
    dector.detect(src1 , keypoints_1) ; //检测SURF特征
    dector.detect(src2 , keypoints_2) ;

    //计算描述子
    SurfDescriptorExtractor extractor ;
    Mat descriptors_1 , descriptors_2 ;
    extractor.compute(src1 , keypoints_1 , descriptors_1) ;
    extractor.compute(src2 , keypoints_2 , descriptors_2) ;

      //Flan特征匹配算法
    FlannBasedMatcher matcher ;
    vector<DMatch> matches ;
    matcher.match(descriptors_1 , descriptors_2 , matches) ;
    cout<<"快速最近邻搜索匹配获得的匹配点数为:"<<matches.size()<<endl ;
    double max_dist = 0 ; double min_dist = 100 ;  

    //计算关键点之间最大最小欧式距离
    for (int i = 0 ; i < descriptors_1.rows ; i++)
    {
        double dist = matches[i].distance ;
        if (dist < min_dist)
        {
            min_dist = dist ;
        }
        if (dist > max_dist)
        {
            max_dist = dist ;
        }
    }
    cout<<"关键点之间欧式距离最小最大值分别为:max_dist = "<<max_dist<<"\tmin_dist = "<<min_dist<<endl ;

    //选择欧式距离小于2倍最小距离的匹配作为优良匹配
    vector<DMatch> good_matches ;
    for (int i = 0 ; i < descriptors_1.rows ; i++)
    {
        if (matches[i].distance < 2 * min_dist)
        {
            good_matches.push_back(matches[i]) ;
        }
    }

    Mat m_matches ;
    m_matches.create(src1.rows , 2 * src1.cols , src1.type()) ;
    Mat imageROI ;
    imageROI = m_matches(Rect(0 , 0 , src1.cols , src1.rows)) ;
    Mat imageROI2 ;
    imageROI2 = m_matches(Rect(src1.cols , 0 , src2.cols , src2.rows)) ;

    addWeighted(imageROI , 0.0 , src1 , 1.0 , 0 , imageROI) ;
    addWeighted(imageROI2 , 0.0 , src2 , 1.0 , 0 , imageROI2) ;

    cout<<"输出匹配点坐标:\n" ;
    for (int i = 0 ; i < good_matches.size() ; ++i)
    {
        int index1 = good_matches[i].queryIdx ;
        int index2 = good_matches[i].trainIdx ;
        circle(m_matches , keypoints_1[index1].pt , 10 , Scalar(0 , 0 , 255) , 5) ;
        circle(m_matches , Point(src1.cols + keypoints_2[index2].pt.x , keypoints_2[index2].pt.y) , 10 , Scalar(0 , 0 , 255) , 5) ;
        line(m_matches , keypoints_1[index1].pt , Point(keypoints_2[index2].pt.x + src1.cols , keypoints_2[index2].pt.y) , Scalar::all(-1) , 10 , 8) ;
        double coefficent = Calcoefficient(src1 , keypoints_1[index1].pt , src2 , keypoints_2[index2].pt) ;
        cout<<keypoints_1[index1].pt<<"\t"<<keypoints_2[index2].pt<<"\t匹配系数为:"<<coefficent ;
        cout<<endl ;
    }


    int good_count = good_matches.size() ;
    cout<<"优良匹配数量为:"<<good_count<<endl ;
    namedWindow("m_matches" , 0) ;
    imshow("m_matches" , m_matches) ;
    waitKey(0) ;

程序运行结果;
这里写图片描述
这里写图片描述

结果是不是很好啊!

k近邻匹配(k-nearest neighbor matching)是一种常用的非实验性研究设计中的数据分析方法,用于估计处理组和对照组之间的平均处理效应。下面是一个用Stata软件进行k近邻匹配的代码示例。 首先,假设我们有一个处理组和一个对照组的数据集,其中包含了一些特征变量和一个二元的处理变量。我们的目标是通过k近邻匹配方法来估计处理效应。 ``` * 加载数据集 use "data.dta", clear * 进行k近邻匹配 *p 选择最佳的匹配变量 *nn 选择最近邻的数量 knnmatch nn treated, neighbor(id) gen(matched_id) showprogress * 根据匹配结果生成配对数据集 gen paired = !missing(matched_id) drop if !paired * 检查配对数据集的平衡性 ttest var1 if treated == 1, by(paired) ``` 在上述代码中,我们首先加载了我们的数据集(假设为"data.dta")。然后,我们使用"knnmatch"命令进行k近邻匹配,指定了要进行匹配的变量(treated)和要生成的匹配变量的名称(matched_id)。我们还可以通过调整"nn"参数来选择最近邻的数量。 接下来,我们根据匹配结果生成配对数据集,只保留成功匹配的样本(由"!missing(matched_id)"部分实现)。最后,我们可以使用"ttest"命令检查配对数据集的平衡性,这将帮助我们确定匹配是否成功。 总的来说,上述代码展示了如何使用Stata进行k近邻匹配。您可以根据自己的数据集和研究目的对代码进行修改和调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值