opencv surf特征点匹配拼接源码

/**
 * @file SURF_Homography
 * @brief SURF detector + descriptor + FLANN Matcher + FindHomography
 * @author A. Huaman
 */

#include 
#include 
#include 
#include "opencv2/core/core.hpp"
#include   
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/nonfree/features2d.hpp"
#include 
#include   



using namespace cv;
using namespace std;

#ifdef _DEBUG
#pragma comment (lib, "opencv_calib3d246d.lib")
#pragma comment (lib, "opencv_contrib246d.lib")
#pragma comment (lib,"opencv_imgproc246d.lib")
#pragma comment (lib, "opencv_core246d.lib")
#pragma comment (lib, "opencv_features2d246d.lib")
#pragma comment (lib, "opencv_flann246d.lib")
#pragma comment (lib, "opencv_gpu246d.lib")
#pragma comment (lib, "opencv_highgui246d.lib")
#pragma comment (lib, "opencv_legacy246d.lib")
#pragma comment (lib, "opencv_ml246d.lib")
#pragma comment (lib, "opencv_objdetect246d.lib")
#pragma comment (lib, "opencv_ts246d.lib")
#pragma comment (lib, "opencv_video246d.lib")
#pragma comment (lib, "opencv_nonfree246d.lib")
#else
#pragma comment (lib, "opencv_calib3d246.lib")
#pragma comment (lib, "opencv_contrib246.lib")
#pragma comment (lib, "opencv_imgproc246.lib")
#pragma comment (lib, "opencv_core246.lib")
#pragma comment (lib, "opencv_features2d246.lib")
#pragma comment (lib, "opencv_flann246.lib")
#pragma comment (lib, "opencv_gpu246.lib")
#pragma comment (lib, "opencv_highgui246.lib")
#pragma comment (lib, "opencv_legacy246.lib")
#pragma comment (lib, "opencv_ml246.lib")
#pragma comment (lib, "opencv_objdetect246.lib")
#pragma comment (lib, "opencv_ts246.lib")
#pragma comment (lib, "opencv_video246.lib")
#pragma comment (lib, "opencv_nonfree246.lib")
#endif

int main()
{
	initModule_nonfree();//初始化模块,使用SIFT或SURF时用到 
	Ptr detector = FeatureDetector::create( "SURF" );//创建SIFT特征检测器,可改成SURF/ORB
	Ptr descriptor_extractor = DescriptorExtractor::create( "SURF" );//创建特征向量生成器,可改成SURF/ORB
	Ptr descriptor_matcher = DescriptorMatcher::create( "BruteForce" );//创建特征匹配器  
	if( detector.empty() || descriptor_extractor.empty() )  
		cout<<"fail to create detector!";  

	//读入图像  
	Mat img1 = imread("1.jpg");  
	Mat img2 = imread("2.jpg");  

	//特征点检测  
	double t = getTickCount();//当前滴答数  
	vector m_LeftKey,m_RightKey;  
	detector->detect( img1, m_LeftKey );//检测img1中的SIFT特征点,存储到m_LeftKey中  
	detector->detect( img2, m_RightKey );  
	cout<<"图像1特征点个数:"<compute( img1, m_LeftKey, descriptors1 );  
	descriptor_extractor->compute( img2, m_RightKey, descriptors2 );  
	t = ((double)getTickCount() - t)/getTickFrequency();  
	cout<<"SIFT算法用时:"< matches;//匹配结果  
	descriptor_matcher->match( descriptors1, descriptors2, matches );//匹配两个图像的特征矩阵  
	cout<<"Match个数:"< max_dist) max_dist = dist;  
	}  
	cout<<"最大距离:"< goodMatches;  
	for(int i=0; i m_Matches=goodMatches;
	// 分配空间
	int ptCount = (int)m_Matches.size();
	Mat p1(ptCount, 2, CV_32F);
	Mat p2(ptCount, 2, CV_32F);

	// 把Keypoint转换为Mat
	Point2f pt;
	for (int i=0; i(i, 0) = pt.x;
		p1.at(i, 1) = pt.y;

		pt = m_RightKey[m_Matches[i].trainIdx].pt;
		p2.at(i, 0) = pt.x;
		p2.at(i, 1) = pt.y;
	}

	// 用RANSAC方法计算F
	Mat m_Fundamental;
	vector m_RANSACStatus;       // 这个变量用于存储RANSAC后每个点的状态
	findFundamentalMat(p1, p2, m_RANSACStatus, FM_RANSAC);

	// 计算野点个数

	int OutlinerCount = 0;
	for (int i=0; i m_LeftInlier;
	vector m_RightInlier;
	vector m_InlierMatches;

	m_InlierMatches.resize(InlinerCount);
	m_LeftInlier.resize(InlinerCount);
	m_RightInlier.resize(InlinerCount);
	InlinerCount=0;
	float inlier_minRx=img1.cols;        //用于存储内点中右图最小横坐标,以便后续融合

	for (int i=0; i(i, 0);
			m_LeftInlier[InlinerCount].y = p1.at(i, 1);
			m_RightInlier[InlinerCount].x = p2.at(i, 0);
			m_RightInlier[InlinerCount].y = p2.at(i, 1);
			m_InlierMatches[InlinerCount].queryIdx = InlinerCount;
			m_InlierMatches[InlinerCount].trainIdx = InlinerCount;

			if(m_RightInlier[InlinerCount].x key1(InlinerCount);
	vector key2(InlinerCount);
	KeyPoint::convert(m_LeftInlier, key1);
	KeyPoint::convert(m_RightInlier, key2);

	// 显示计算F过后的内点匹配
	Mat OutImage;
	drawMatches(img1, key1, img2, key2, m_InlierMatches, OutImage);
	cvNamedWindow( "Match features", 1);
	cvShowImage("Match features", &IplImage(OutImage));
	waitKey(0);

	cvDestroyAllWindows();

	//矩阵H用以存储RANSAC得到的单应矩阵
	Mat H = findHomography( m_LeftInlier, m_RightInlier, RANSAC );

	//存储左图四角,及其变换到右图位置
	std::vector obj_corners(4);
	obj_corners[0] = Point(0,0); obj_corners[1] = Point( img1.cols, 0 );
	obj_corners[2] = Point( img1.cols, img1.rows ); obj_corners[3] = Point( 0, img1.rows );
	std::vector scene_corners(4);
	perspectiveTransform( obj_corners, scene_corners, H);

	//画出变换后图像位置
	Point2f offset( (float)img1.cols, 0);  
	line( OutImage, scene_corners[0]+offset, scene_corners[1]+offset, Scalar( 0, 255, 0), 4 );
	line( OutImage, scene_corners[1]+offset, scene_corners[2]+offset, Scalar( 0, 255, 0), 4 );
	line( OutImage, scene_corners[2]+offset, scene_corners[3]+offset, Scalar( 0, 255, 0), 4 );
	line( OutImage, scene_corners[3]+offset, scene_corners[0]+offset, Scalar( 0, 255, 0), 4 );
	imshow( "Good Matches & Object detection", OutImage );

	waitKey(0);
	imwrite("warp_position.jpg",OutImage);

 
 	int drift = scene_corners[1].x;                                                        //储存偏移量
 
 	//新建一个矩阵存储配准后四角的位置
 	int width = int(max(abs(scene_corners[1].x), abs(scene_corners[2].x)));
 	int height= img1.rows;                                                                  //或者:int height = int(max(abs(scene_corners[2].y), abs(scene_corners[3].y)));
 	float origin_x=0,origin_y=0;
 	if(scene_corners[0].x<0) {
 		if (scene_corners[3].x<0) origin_x+=min(scene_corners[0].x,scene_corners[3].x);
 		else origin_x+=scene_corners[0].x;}
 	width-=int(origin_x);
 	if(scene_corners[0].y<0) {
 		if (scene_corners[1].y) origin_y+=min(scene_corners[0].y,scene_corners[1].y);
 		else origin_y+=scene_corners[0].y;}
 	//可选:height-=int(origin_y);
 	Mat imageturn=Mat::zeros(width,height,img1.type());
 
 	//获取新的变换矩阵,使图像完整显示
 	for (int i=0;i<4;i++) {scene_corners[i].x -= origin_x; } 	//可选:scene_corners[i].y -= (float)origin_y; }
 	Mat H1=getPerspectiveTransform(obj_corners, scene_corners);
 
 	//进行图像变换,显示效果
	warpPerspective(img1,imageturn,H1,Size(width,height));	
 	imshow("image_Perspective", imageturn);
 	waitKey(0);
 
 
 	//图像融合
 	int width_ol=width-int(inlier_minRx-origin_x);
 	int start_x=int(inlier_minRx-origin_x);
 	cout<<"width: "<

你可能感兴趣的:(opencv,其它算法)