图像拼接

#include <stdio.h>  
#include <iostream> 
#include<vector>
#include"opencv2\opencv.hpp"
#include"opencv2\core\core.hpp"
#include"opencv2\xfeatures2d.hpp"
#include "opencv2/highgui/highgui.hpp"
using namespace cv;
using namespace std;


int main(int argc, char** argv) {
	Mat src1 = imread("1.jpg");
	Mat src2 = imread("2.jpg");


	if (src1.data == NULL || src2.data == NULL)
	{
		cout << "No exist" << endl;
		return -1;
	}


	Ptr<Feature2D> surf = xfeatures2d::SURF::create();
	vector<KeyPoint> pic1key, pic2key;
	Mat des1, des2;
	surf->detectAndCompute(src1, Mat(), pic1key, des1);
	surf->detectAndCompute(src2, Mat(), pic2key, des2);
	//drawKeypoints(src1,pic1key,src1);

	FlannBasedMatcher matcher;//不使用暴力匹配,改成Fast Library for Approximate Nearest Neighbors匹配(近似算法,比暴力匹配更快)
	vector<DMatch> matches;
	matcher.match(des1, des2, matches);


	vector<Point2f>pic1, pic2;//滤掉误匹配点
	for (int i = 0; i < matches.size(); i++)
	{
		pic1.push_back(pic1key[matches[i].queryIdx].pt);
		pic2.push_back(pic2key[matches[i].trainIdx].pt);
	}
	vector<unsigned char>mark(pic1.size());
	Mat transM = findHomography(pic1, pic2, CV_RANSAC, 5, mark, 500);
	cout << "变换矩阵为:" << endl;
	cout << transM;
	vector<DMatch>optimizeMatch;
	for (int i = 0; i < matches.size(); i++)
	{
		if (mark[i])
			optimizeMatch.push_back(matches[i]);
	}
	//开始拼接
	Mat tempP;
	warpPerspective(src1, tempP, transM, Size(src1.cols * 2, src1.rows));
	Mat matchP(src1.cols * 2, src1.rows, CV_8UC3);
	tempP.copyTo(matchP);
	src2.copyTo(matchP(Rect(0, 0, src2.cols, src2.rows)));
	imshow("compare", tempP);
	imshow("compare1", matchP);


	//优化拼接线
	double lefttop[3] = { 0,0,1 };
	double leftbottom[3] = { 0,src1.rows,1 };
	double transLT[3];
	double transLB[3];
	Mat _lefttop = Mat(3, 1, CV_64FC1, lefttop);
	Mat _leftbottom = Mat(3, 1, CV_64FC1, leftbottom);
	Mat _transLT = Mat(3, 1, CV_64FC1, transLT);
	Mat _transLB = Mat(3, 1, CV_64FC1, transLB);
	_transLT = transM * _lefttop;
	_transLB = transM * _leftbottom;
	double weight = 1;
	int leftline = MIN(transLT[0], transLB[0]);
	double width = src2.cols - leftline;
	for (int i = 0; i < src2.rows; i++)
	{
		uchar* src = src2.ptr<uchar>(i);
		uchar* trans = tempP.ptr<uchar>(i);
		uchar* match = matchP.ptr<uchar>(i);
		for (int j = leftline; j < src2.cols; j++)
		{
			if (trans[j * 3] == 0 && trans[j * 3 + 1] == 0 && trans[j * 3 + 2] == 0)
			{
				weight = 1;
			}
			else {
				weight = (double)(width - (j - leftline)) / width;
			}
			match[j * 3] = src[j * 3] * weight + trans[j * 3] * (1 - weight);
			match[j * 3 + 1] = src[j * 3 + 1] * weight + trans[j * 3 + 1] * (1 - weight);
			match[j * 3 + 2] = src[j * 3 + 2] * weight + trans[j * 3 + 2] * (1 - weight);
		}
	}

	namedWindow("output", 0);
	imshow("output", matchP);
	waitKey(0);
	return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值