Opencv图像配准

// 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
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值