图像配准例子


// CVTest.cpp : 定义控制台应用程序的入口点。
//
 
#include "stdafx.h"
using namespace cv;
using namespace std;
 
 
int main( int argc, char** argv )  
{   
   
    //读取原始基准图和待匹配图
    Mat srcImg1 = imread("12.jpg", CV_LOAD_IMAGE_GRAYSCALE);      //待配准图
    Mat srcImg2 = imread("11.jpg", CV_LOAD_IMAGE_GRAYSCALE);      //基准图
    //Mat srcImg1 = imread("lena2.png", CV_LOAD_IMAGE_GRAYSCALE);      //待配准图
    //Mat srcImg2 = imread("lena1.png", CV_LOAD_IMAGE_GRAYSCALE);      //基准图
    
    //显示基准和待配准图
    //imshow("待配准图", srcImg1);
    //imshow("基准图", srcImg2);
    clock_t start,finish;
    double totaltime;
    start=clock();
    //定义SIFT特征检测类对象
    /*SiftFeatureDetector siftDetector1;
    SiftFeatureDetector siftDetector2;*/
    ORB orb;
 
    //定义KeyPoint变量
    vector<KeyPoint>keyPoints1;
    vector<KeyPoint>keyPoints2;
    Mat description1;
    Mat description2;
    //特征点检测
    
    orb(srcImg1, Mat(), keyPoints1, description1);
    finish=clock();
    totaltime=(double)(finish-start);
    cout<<"\norb1: "<<totaltime<<"ms!"<<endl;
    
    orb(srcImg2, Mat(), keyPoints2, description2);
    
    totaltime=(double)(clock()-finish);
    finish=clock();
    cout<<"\norb2: "<<totaltime<<"ms!"<<endl;
    
    //siftDetector1.detect(srcImg1, keyPoints1);
    
    
    //siftDetector2.detect(srcImg2, keyPoints2);
 
    //绘制特征点(关键点)
    Mat feature_pic1, feature_pic2;
 
    drawKeypoints(srcImg1, keyPoints1, feature_pic1, Scalar::all(-1));
    drawKeypoints(srcImg2, keyPoints2, feature_pic2, Scalar::all(-1));
 
    drawKeypoints(srcImg1, keyPoints1, feature_pic1, Scalar(0, 255, 0), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
    drawKeypoints(srcImg2, keyPoints2, feature_pic2, Scalar(0, 255, 0), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
 
    //显示原图
 
    //显示结果
    //imshow("feature1", feature_pic1);
    //imshow("feature2", feature_pic2);
 
    //计算特征点描述符 / 特征向量提取
    /*SiftDescriptorExtractor descriptor;
    
    
    descriptor.compute(srcImg1, keyPoints1, description1);
    
    
    
    descriptor.compute(srcImg2, keyPoints2, description2);*/
    
    cout << keyPoints1.size() << endl;
    cout << description1.cols << endl;      //列数
    cout << description1.rows << endl;      //行数
    
    
 
    //进行BFMatch暴力匹配
    //HammingLUT
    BruteForceMatcher<HammingLUT> matcher;    //实例化暴力匹配器
    //FlannBasedMatcher matcher;  //实例化FLANN匹配器
    vector<DMatch>matches;   //定义匹配结果变量
    
    matcher.match(description1, description2, matches);  //实现描述符之间的匹配
    totaltime=(double)(clock()-finish);
    finish=clock();
    cout<<"\n BruteForceMatcher: "<<totaltime<<"ms!"<<endl;
    //中间变量
    int i,j,k;double sum=0;double b;
 
    double max_dist = 0;  
    double min_dist = 100;  
    for(int i=0; i<matches.size(); i++)  
    {  
        double dist = matches[i].distance;  
        if(dist < min_dist) 
            min_dist = dist;  
        if(dist > max_dist) 
            max_dist = dist;  
    }  
    cout<<"最大距离:"<<max_dist<<endl;  
    cout<<"最小距离:"<<min_dist<<endl;  
 
    //筛选出较好的匹配点  
    vector<DMatch> good_matches;  
    double dThreshold = 0.5;    //匹配的阈值,越大匹配的点数越多
    for(int i=0; i<matches.size(); i++)  
    {  
        if(matches[i].distance < dThreshold * max_dist)  
        {  
            good_matches.push_back(matches[i]);  
        }  
    }  
 
    //RANSAC 消除误匹配特征点 主要分为三个部分:
    //1)根据matches将特征点对齐,将坐标转换为float类型
    //2)使用求基础矩阵方法findFundamentalMat,得到RansacStatus
    //3)根据RansacStatus来将误匹配的点也即RansacStatus[i]=0的点删除
 
    //根据matches将特征点对齐,将坐标转换为float类型
    vector<KeyPoint> R_keypoint01,R_keypoint02;
    for (i=0;i<good_matches.size();i++)   
    {
        R_keypoint01.push_back(keyPoints1[good_matches[i].queryIdx]);
        R_keypoint02.push_back(keyPoints2[good_matches[i].trainIdx]);
        // 这两句话的理解:R_keypoint1是要存储img01中能与img02匹配的特征点,
        // matches中存储了这些匹配点对的img01和img02的索引值
    }
 
    //坐标转换
    vector<Point2f>p01,p02;
    for (i=0;i<good_matches.size();i++)
    {
        p01.push_back(R_keypoint01[i].pt);
        p02.push_back(R_keypoint02[i].pt);
    }
 
    //计算基础矩阵并剔除误匹配点
    vector<uchar> RansacStatus;
    Mat Fundamental= findHomography(p01,p02,RansacStatus,CV_RANSAC);
    totaltime=(double)(clock()-finish);
    finish=clock();
    cout<<"\n findHomography: "<<totaltime<<"ms!"<<endl;
    Mat dst;
    warpPerspective(srcImg1, dst, Fundamental,Size(srcImg1.cols,srcImg1.rows));
    totaltime=(double)(clock()-finish);
    finish=clock();
    cout<<"\n warpPerspective: "<<totaltime<<"ms!"<<endl;
 
    /*imshow("配准后的图",dst );
    imwrite("dst.jpg", dst);*/
 
    //GaussianBlur(dst, dst, Size(5, 5),10);
    //GaussianBlur(srcImg2, srcImg2, Size(5, 5),10);
    //imshow("Guss",srcImg2 );
    Mat diffImg;
    absdiff(srcImg2, dst,  diffImg);
    totaltime=(double)(clock()-finish);
    finish=clock();
    cout<<"\n absdiff: "<<totaltime<<"ms!"<<endl;
    
    finish=clock();
    totaltime=(double)(finish-start);
    cout<<"\n此程序的运行时间为: "<<totaltime<<"ms!"<<endl;
 
    imshow("diff",diffImg );
    waitKey(0);
 
}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值