// 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
vector
Mat description1;
Mat description2;
//特征点检测
orb(srcImg1, Mat(), keyPoints1, description1);
finish=clock();
totaltime=(double)(finish-start);
cout<<"\norb1: "<
orb(srcImg2, Mat(), keyPoints2, description2);
totaltime=(double)(clock()-finish);
finish=clock();
cout<<"\norb2: "<
//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
//FlannBasedMatcher matcher; //实例化FLANN匹配器
vector
matcher.match(description1, description2, matches); //实现描述符之间的匹配
totaltime=(double)(clock()-finish);
finish=clock();
cout<<"\n BruteForceMatcher: "<
int i,j,k;double sum=0;double b;
double max_dist = 0;
double min_dist = 100;
for(int i=0; i
double dist = matches[i].distance;
if(dist < min_dist)
min_dist = dist;
if(dist > max_dist)
max_dist = dist;
}
cout<<"最大距离:"<
//筛选出较好的匹配点
vector
double dThreshold = 0.5; //匹配的阈值,越大匹配的点数越多
for(int i=0; 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
for (i=0;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
for (i=0;i
p01.push_back(R_keypoint01[i].pt);
p02.push_back(R_keypoint02[i].pt);
}
//计算基础矩阵并剔除误匹配点
vector
Mat Fundamental= findHomography(p01,p02,RansacStatus,CV_RANSAC);
totaltime=(double)(clock()-finish);
finish=clock();
cout<<"\n findHomography: "<
warpPerspective(srcImg1, dst, Fundamental,Size(srcImg1.cols,srcImg1.rows));
totaltime=(double)(clock()-finish);
finish=clock();
cout<<"\n warpPerspective: "<
/*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: "<
finish=clock();
totaltime=(double)(finish-start);
cout<<"\n此程序的运行时间为: "<
imshow("diff",diffImg );
waitKey(0);
}