上图经过透视变换后贴到下图红色框选的那个位置
先介绍一下opencv的鼠标点击事件吧,opencv有自带的鼠标点击事件的函数
void setMousecallback(const string& winname, MouseCallback onMouse, void* userdata=0)
winname:窗口的名字
onMouse:鼠标响应函数,回调函数。指定窗口里每次鼠标时间发生的时候,被调用的函数指针。 这个函数的原型应该为void on_Mouse(int event, int x, int y, int flags, void* param);
userdate:传给回调函数的参数。
所以可以直接进行使用,注意:第一个参数是你要进行鼠标点击事件的那个窗口
接下来分享一下如何通过透视变换将图一嵌入到图二中框选的位置
效果大概是这样的
代码中有个结构体,结构体的第一个保存的是要操作的图片窗口,第二个参数是获取到的四个点保存在一个向量容器中
fillConvexPoly()函数
函数原型:void fillConvexPoly(Mat& img, const Point* pts, int npts, const Scalar& color, int lineType=8, int shift=0)
函数作用:填充凸多边形
参数说明:img 图像
pts 指向单个多边形的指针数组
npts 多边形的顶点个数
color 多边形的颜色
LineType 组成多边形的线条的类型
(or 0) - 8-connected line(8邻接)连接 线。
- 4-connected line(4邻接)连接线。
CV_AA - antialiased 线条。
shift 顶点坐标的小数点位数
函数说明:函数fillConvexPoly填充凸多边形内部。这个函数比函数cvFillPoly 更快。它除了可以填充凸多边形区域还可以填充任何的单调多边形。例如:一个被水平线(扫描线)至多两次截断的多边形
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
struct userdata
{
Mat img;
vector<Point2f> points;
};
//鼠标点击事件的回调函数
void mouserhandle(int event,int x,int y,int flags,void *ptr)
{
if(event==EVENT_LBUTTONDOWN)
{
userdata *data=(userdata *)ptr;
circle(data->img,Point(x,y),3,Scalar(0,0,255),3,CV_AA);
imshow("image1",data->img);
if(data->points.size()<5)
{
data->points.push_back(Point2f(x,y));
}
}
}
int main()
{
Mat image=imread("city.jpg");
Mat girl=imread("girl.jpg");
//imshow("girl",girl);
vector<Point2f> obj;
obj.push_back(Point2f(0,0));
obj.push_back(Point2f(girl.cols,0));
obj.push_back(Point2f(girl.cols,girl.rows));
obj.push_back(Point2f(0,girl.rows));
Mat image1=image.clone();
userdata data;
data.img=image1;
Mat result;
imshow("image1",image1);
setMouseCallback("image1",mouserhandle,&data);
waitKey(0);
Mat H=findHomography(obj,data.points,CV_RANSAC);
warpPerspective(girl, result, H, image.size());
Point PointArray[4];
for(int i=0;i<4;i++)
{
PointArray[i]=data.points[i];
}
fillConvexPoly(image,PointArray,4,Scalar(0));//将原图中的那个菱形区域变成黑色的
Mat endresult=image+result;
imshow("endresult",endresult);
waitKey(0);
return 0;
}
大概就是这样,有错误的地方欢迎各位指教哦!!!