#include <iostream>
#include <opencv2\opencv.hpp>
using namespace std;
using namespace cv;
int main()
{
Mat firstImage=imread("ww.jpg");
Mat secondImage = imread("ee.jpg");
if(firstImage.empty()||secondImage.empty())
{
cout<<"error"<<endl;
return 0;
}
//resize(firstImage,firstImage,Size(800,1000),0,0,1);
//resize(secondImage,secondImage,Size(800,1000),0,0,1);
////////////////////////////////////////////////////////////////////////////////
//第一步:获取SIFT特征
//@Author:code陈
////////////////////////////////////////////////////////////////////////////////
//difine a sift detector
SiftFeatureDetector siftDetector;
//store key points
vector<KeyPoint> firstKeypoint,secondKeypoint;
//detect image with SIFT,get key points
siftDetector.detect(firstImage,firstKeypoint);
siftDetector.detect(secondImage,secondKeypoint);
Mat firstOutImage,secondOutImage;
//draw key points at the out image and show to the user
drawKeypoints(firstImage,firstKeypoint,firstOutImage,Scalar(255,0,0));
drawKeypoints(secondImage,secondKeypoint,secondOutImage,Scalar(0,255,0));
imshow("first",firstOutImage);
imshow("second",secondOutImage);
// difine a sift descriptor extractor
SiftDescriptorExtractor extractor;
//store the descriptor of each image
Mat firstDescriptor,secondDescriptor;
BruteForceMatcher<L2<float>> matcher;
vector<DMatch> matches;
Mat matcheImage;
//compute the descriptor of each image
extractor.compute(firstImage,firstKeypoint,firstDescriptor);
extractor.compute(secondImage,secondKeypoint,secondDescriptor);
//match
matcher.match(firstDescriptor,secondDescriptor,matches);
////////////////////////////////////////////////////////////////////////////////
//第二步:RANSAC方法剔除outliner
//@Author:code陈
////////////////////////////////////////////////////////////////////////////////
//将vector转化成Mat
Mat firstKeypointMat(matches.size(),2,CV_32F),secondKeypointMat(matches.size(),2,CV_32F);
for(int i = 0;i<matches.size();i++)
{
firstKeypointMat.at<float>(i,0) = firstKeypoint[matches[i].queryIdx].pt.x;
firstKeypointMat.at<float>(i,1) = firstKeypoint[matches[i].queryIdx].pt.y;
secondKeypointMat.at<float>(i,0) = secondKeypoint[matches[i].trainIdx].pt.x;
secondKeypointMat.at<float>(i,1) = secondKeypoint[matches[i].trainIdx].pt.y;
}
//Calculate the fundamental Mat;
vector<uchar> ransacStatus;
Mat fundamentalMat = findFundamentalMat(firstKeypointMat,secondKeypointMat,ransacStatus,FM_RANSAC);
cout<<fundamentalMat<<endl;
//Calculate the number of outliner points;
int outlinerCount = 0;
for(int i=0;i<matches.size();i++)
{
if(ransacStatus[i]==0)
{
outlinerCount++;
}
}
//Calculate inliner points;
vector<Point2f> firstInliner;
vector<Point2f> secondInliner;
vector<DMatch> inlinerMatches;
int inlinerCount = matches.size()-outlinerCount;
firstInliner.resize(inlinerCount);
secondInliner.resize(inlinerCount);
inlinerMatches.resize(inlinerCount);
int index = 0;
for(int i=0;i<matches.size();i++)
{
if(ransacStatus[i]!=0)
{
firstInliner[index].x = firstKeypointMat.at<float>(i,0);
firstInliner[index].y = firstKeypointMat.at<float>(i,1);
secondInliner[index].x = secondKeypointMat.at<float>(i,0);
secondInliner[index].y = secondKeypointMat.at<float>(i,1);
inlinerMatches[index].queryIdx = index;
inlinerMatches[index].trainIdx = index;
index ++;
}
}
vector<KeyPoint> inlinerFirstKeypoint(inlinerCount);
vector<KeyPoint> inlinerSecondKeypoint(inlinerCount);
KeyPoint::convert(firstInliner,inlinerFirstKeypoint);
KeyPoint::convert(secondInliner,inlinerSecondKeypoint);
//cout<<fundamentalMat<<endl;
//select 50 keypoints
//matches.erase(matches.begin()+50,matches.end());
//inlinerMatches.erase(inlinerMatches.begin()+50,inlinerMatches.end());
drawMatches(firstImage,inlinerFirstKeypoint,secondImage,inlinerSecondKeypoint,inlinerMatches,matcheImage);
imshow("ransacMatches",matcheImage);
drawMatches(firstImage,firstKeypoint,secondImage,secondKeypoint,matches,matcheImage);
imshow("matches",matcheImage);
//imshow();
waitKey(0);
return 0;
}下面对每一步进行简单描述:版权声明:本文为博主原创文章,未经博主允许不得转载。
原文:http://blog.csdn.net/chentravelling/article/details/49835169