获取两幅图重叠区域

#include 
#include "opencv2/opencv.hpp"
#include "opencv2/xfeatures2d.hpp"

using namespace std;
typedef struct
{
	cv::Point2f left_top;
	cv::Point2f left_bottom;
	cv::Point2f right_top;
	cv::Point2f right_bottom;
}four_corners_t;

void CalcCorners(const cv::Mat& H, const cv::Mat& src, four_corners_t& corners)
{
	double v2[] = { 0, 0, 1 };//左上角
	double v1[3];//变换后的坐标值
	cv::Mat V2 = cv::Mat(3, 1, CV_64FC1, v2);  //列向量
	cv::Mat V1 = cv::Mat(3, 1, CV_64FC1, v1);  //列向量

	V1 = H * V2;
	//左上角(0,0,1)
	//cout << "V2: " << V2 << endl;
	//cout << "V1: " << V1 << endl;
	corners.left_top.x = v1[0] / v1[2];
	corners.left_top.y = v1[1] / v1[2];

	//左下角(0,src.rows,1)
	v2[0] = 0;
	v2[1] = src.rows;
	v2[2] = 1;
	V2 = cv::Mat(3, 1, CV_64FC1, v2);  //列向量
	V1 = cv::Mat(3, 1, CV_64FC1, v1);  //列向量
	V1 = H * V2;
	corners.left_bottom.x = v1[0] / v1[2];
	corners.left_bottom.y = v1[1] / v1[2];

	//右上角(src.cols,0,1)
	v2[0] = src.cols;
	v2[1] = 0;
	v2[2] = 1;
	V2 = cv::Mat(3, 1, CV_64FC1, v2);  //列向量
	V1 = cv::Mat(3, 1, CV_64FC1, v1);  //列向量
	V1 = H * V2;
	corners.right_top.x = v1[0] / v1[2];
	corners.right_top.y = v1[1] / v1[2];

	//右下角(src.cols,src.rows,1)
	v2[0] = src.cols;
	v2[1] = src.rows;
	v2[2] = 1;
	V2 = cv::Mat(3, 1, CV_64FC1, v2);  //列向量
	V1 = cv::Mat(3, 1, CV_64FC1, v1);  //列向量
	V1 = H * V2;
	corners.right_bottom.x = v1[0] / v1[2];
	corners.right_bottom.y = v1[1] / v1[2];

}

bool ImageOverlap(cv::Mat &img1, cv::Mat &img2, cv::Mat &dst, std::vector& vPoint1, std::vector& vPoint2)
{
	cv::Mat g1(img1, cv::Rect(0, 0, img1.cols, img1.rows));
	cv::Mat g2(img2, cv::Rect(0, 0, img2.cols, img2.rows));

	cv::cvtColor(g1, g1, CV_BGR2GRAY);
	cv::cvtColor(g2, g2, CV_BGR2GRAY);

	std::vector keypoints_roi, keypoints_img;  /* keypoints found using SIFT */
	cv::Mat descriptor_roi, descriptor_img;                  /* Descriptors for SIFT */
	cv::FlannBasedMatcher matcher;                           /* FLANN based matcher to match keypoints */
	std::vector matches, good_matches;

	cv::Ptr f2d = cv::xfeatures2d::SIFT::create();
	f2d->detect(g1, keypoints_roi);                          /* get keypoints of ROI image */
	f2d->detect(g2, keypoints_img);                          /* get keypoints of the image */
	f2d->compute(g1, keypoints_roi, descriptor_roi);
	f2d->compute(g2, keypoints_img, descriptor_img);
	matcher.match(descriptor_roi, descriptor_img, matches);

	double max_dist = 0; double min_dist = 1000;
	int i, dist = 80;

	//-- Quick calculation of max and min distances between keypoints
	for (int i = 0; i < descriptor_roi.rows; i++)
	{
		double dist = matches[i].distance;
		if (dist < min_dist) min_dist = dist;
		if (dist > max_dist) max_dist = dist;
	}

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

	/*if (good_matches.size() < 10) {
		return false;
	}*/

	//cout << "matched keypoints numbers in right image:"<(),
		cv::DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
	imshow("matches", img_matches);
	cv::waitKey(1);*/

	vector keypoints1, keypoints2;
	for (i = 0; i img2.rows) {
		mRows = img1.rows;
	}
	dst = cv::Mat::zeros(mRows, MAX(corners_1.right_top.x, corners_1.right_bottom.x), CV_8UC3);
	warpPerspective(img2, dst, H, cv::Size(MAX(corners_1.right_top.x, corners_1.right_bottom.x), mRows));
	cv::Mat half(dst, cv::Rect(0, 0, img1.cols, img1.rows));
	img1.copyTo(half);

	vPoint1.push_back(cv::Point((int)corners_1.left_top.x, (int)corners_1.left_top.y));
	vPoint1.push_back(cv::Point((int)corners_1.right_top.x, (int)corners_1.right_top.y));
	vPoint1.push_back(cv::Point((int)corners_1.right_bottom.x, (int)corners_1.right_bottom.y));
	vPoint1.push_back(cv::Point((int)corners_1.left_bottom.x, (int)corners_1.left_bottom.y));

	vPoint2.push_back(cv::Point((int)corners_2.left_top.x, (int)corners_2.left_top.y));
	vPoint2.push_back(cv::Point((int)corners_2.right_top.x, (int)corners_2.right_top.y));
	vPoint2.push_back(cv::Point((int)corners_2.right_bottom.x, (int)corners_2.right_bottom.y));
	vPoint2.push_back(cv::Point((int)corners_2.left_bottom.x, (int)corners_2.left_bottom.y));

	return true;
}
void drawingLine(cv::Mat& img, std::vector& vPoints) {
	for (int i = 0; i < vPoints.size(); i++)
	{
		if (i == (vPoints.size() - 1))
		{
			line(img, vPoints[0], vPoints[i], cv::Scalar(0, 0, 255), 2);
		}
		else
		{
			line(img, vPoints[i], vPoints[i + 1], cv::Scalar(0, 0, 255), 2);
		}

	}
}

int main() {

	cv::Mat img1 = cv::imread("1.png");
	cv::Mat img2 = cv::imread("2.png");
	std::vector vPoint1;
	std::vector vPoint2;
	cv::Mat dst;
	if (ImageOverlap(img1, img2, dst, vPoint1, vPoint2)) {
		drawingLine(img1, vPoint1);
		drawingLine(img2, vPoint2);
	}
	cv::imshow("dst", dst);
	cv::imshow("img1", img1);
	cv::imshow("img2", img2);
	cv::waitKey(0);

	int a;
	cin >> a;
}

原图:

获取两幅图重叠区域_第1张图片

 

获取两幅图重叠区域_第2张图片

 

最后结果图:

获取两幅图重叠区域_第3张图片

参考:

https://www.cnblogs.com/skyfsm/p/7411961.html

https://blog.csdn.net/qq_15295565/article/details/89402644

你可能感兴趣的:(opencv,图像处理)