您当前的位置: 首页 >  opencv

程序员正茂

暂无认证

  • 3浏览

    0关注

    283博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

opencv 图像拼接

程序员正茂 发布时间:2018-11-19 17:12:27 ,浏览量:3

左右图单应性变换原理图

1.SURF特征点提取

#include "pch.h"
#include 
#include 
#include 
#include "StitcherTest.h"


using namespace cv;
using namespace cv::xfeatures2d;
using namespace std;


int main()
{
	Mat image_1 = imread("1.jpg");
	Mat image_2 = imread("2.jpg");
	Mat gray_image_1;
	Mat gray_image_2;

	cvtColor(image_1, gray_image_1, CV_RGB2GRAY);
	cvtColor(image_2, gray_image_2, CV_RGB2GRAY);

	// Check if image files can be read
	if (!gray_image_1.data) {
		std::cout compute(gray_image_2, keypoints_2, descriptors_2);
	extractor->compute(gray_image_1, keypoints_1, descriptors_1);

	// Matching descriptor vectors using FLANN matcher
	// Based from  Anna Huaman's 'Features2D + Homography to find a known object' Tutorial
	FlannBasedMatcher matcher;
	std::vector  matches;
	matcher.match(descriptors_2, descriptors_1, matches);

	double max_dist = 0;
	double min_dist = 100;

	// Quick calculation of max and min distances between keypoints
	// Based from  Anna Huaman's 'Features2D + Homography to find a known object' Tutorial
	for (int i = 0; i < descriptors_2.rows; i++) {

		double dist = matches[i].distance;

		if (dist < min_dist) {
			min_dist = dist;
		}
	}

	// Use matches that have a distance that is less than 3 * min_dist
	std::vector  good_matches;

	for (int i = 0; i < descriptors_2.rows; i++) {
		if (matches[i].distance < 3 * min_dist) {
			good_matches.push_back(matches[i]);
		}
	}

	std::vector  points2;
	std::vector  points1;

	for (int i = 0; i < good_matches.size(); i++) {
		// Get the keypoints from the good matches
		points2.push_back(keypoints_2[good_matches[i].queryIdx].pt);
		points1.push_back(keypoints_1[good_matches[i].trainIdx].pt);
	}

	//以左边的图片为准,从右边进行拼接,变换原理见上图
	// Find the Homography Matrix
	Mat H = findHomography(points2, points1, CV_RANSAC);
	// Use the Homography Matrix to warp the images
	cv::Mat resultRight;
	warpPerspective(image_2, resultRight, H, cv::Size(2 * image_2.cols, image_2.rows));
	cv::Mat half(resultRight, cv::Rect(0, 0, image_1.cols, image_1.rows));
	image_1.copyTo(half);
	imshow("resultRight", resultRight);

	//以右边的图片为准,从左边进行拼接,变换原理见上图
	Mat homo = findHomography(points1, points2);
	//需要向右平移image_1的宽度
	Mat shftMat = (Mat_(3, 3) detectAndCompute(image1, Mat(), keyImg1, descImg1, false);
	b->detectAndCompute(image2, Mat(), keyImg2, descImg2, false);

	//匹配特征点
	descriptorMatcher = DescriptorMatcher::create("BruteForce");
	descriptorMatcher->match(descImg1, descImg2, matches, Mat());

	Mat index;
	int nbMatch = int(matches.size());
	Mat tab(nbMatch, 1, CV_32F);
	for (int i = 0; i < nbMatch; i++)
	{
		tab.at(i, 0) = matches[i].distance;
	}
	sortIdx(tab, index, cv::SORT_EVERY_COLUMN + cv::SORT_ASCENDING);
	vector bestMatches;
	for (int i = 0; i < 60; i++)
	{
		bestMatches.push_back(matches[index.at(i, 0)]);
	}
	Mat result;
	drawMatches(image1, keyImg1, image2, keyImg2, bestMatches, result);
	std::vector obj;
	std::vector scene;
	for (int i = 0; i < (int)bestMatches.size(); i++)
	{
		obj.push_back(keyImg1[bestMatches[i].queryIdx].pt);
		scene.push_back(keyImg2[bestMatches[i].trainIdx].pt);
	}

	//直接调用ransac,计算单应矩阵
	Mat H = findHomography(scene, obj, CV_RANSAC);
	
	cv::Mat resultRight;
	warpPerspective(image2, resultRight, H, cv::Size(image1.cols + image2.cols, max(image1.rows, image2.rows)));
	cv::Mat half(resultRight, cv::Rect(0, 0, image1.cols, image1.rows));
	image1.copyTo(half);
	imshow("resultRight", resultRight);

	waitKey(0);
	return 0;
}

 

关注
打赏
1660743125
查看更多评论
立即登录/注册

微信扫码登录

0.0426s