同形投影矫正

利用opencv提供的findHomography函数获得一个变换矩阵,然后通过warpPerspective函数透视矫正变换为新的一张图,

下面例子通过透视矫正把一张摆正的广告矫正为用户指定的四边区域,然后通过图片叠加方式把广告替换

// homographyreplace.cpp: 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

struct userdata {
	Mat im;
	vector<Point2f> points;
};


void mouseHandler(int event, int x, int y, int flags, void* data_ptr)
{
	if (event == EVENT_LBUTTONDOWN)
	{
		userdata *data = ((userdata *)data_ptr);
		circle(data->im, Point(x, y), 3, Scalar(0, 255, 255), 5, CV_AA);
		imshow("Image", data->im);
		if (data->points.size() < 4)
		{
			data->points.push_back(Point2f(x, y));
		}
	}

}



int main(int argc, char** argv)
{

	// 读取第一张图片
	Mat im_src = imread("first-image.jpg");
	Size size = im_src.size();

	// 以这张图片的四个角的顶点坐标创建四个点列表
	vector<Point2f> pts_src;
	pts_src.push_back(Point2f(0, 0));
	pts_src.push_back(Point2f(size.width - 1, 0));
	pts_src.push_back(Point2f(size.width - 1, size.height - 1));
	pts_src.push_back(Point2f(0, size.height - 1)); 

	// 需要取代的图片
	Mat im_dst = imread("times-square.jpg");


	// clone一个临时图片
	Mat im_temp = im_dst.clone();
	userdata data;
	data.im = im_temp;


	// 显示这张图片
	imshow("Image", im_temp);

	cout << "点击一个广告牌的四个角点然后回车" << endl;
	// 设置鼠标事件回调
	setMouseCallback("Image", mouseHandler, &data);
	waitKey(0);

	// 计算矩形四个点到用户点击的四个点的同形变换矩阵
	Mat h = findHomography(pts_src, data.points);

	// 投影矫正
	warpPerspective(im_src, im_temp, h, im_temp.size());

	// 抽出用户点击的四个点
	Point pts_dst[4];
	for (int i = 0; i < 4; i++)
	{
		pts_dst[i] = data.points[i];
	}

	// 扣出四个点区域的像素填充0
	fillConvexPoly(im_dst, pts_dst, 4, Scalar(0), CV_AA);

	// 图片像素叠加合成
	im_dst = im_dst + im_temp;

	// 显示合成的图片
	imshow("Image", im_dst);
	waitKey(0);
	destroyAllWindows();
	return 0;
}

  

 图片资源:

https://files.cnblogs.com/files/zzatp/img.zip

在线h5版本的同形矫正,手机扫描

 

posted on 2018-06-05 14:21  zzatp  阅读(194)  评论(0编辑  收藏  举报

导航