#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;
}
图像拼接
最新推荐文章于 2024-07-25 23:04:51 发布