任务:利用单应矩阵将广告牌的内容替换成自己的图片。
代码框架如下:
#include
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)
{
// Read in the image.
// input your image
Mat im_src = imread("new.jpg");
// imshow("src img", im_src);
Size size = im_src.size();
// Create a vector of points.
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));
// Destination image
// Mat im_dst = imread("times-square.jpg");
Mat im_dst = imread("ad.jpg");
// Set data for mouse handler
Mat im_temp = im_dst.clone();
userdata data;
data.im = im_temp;
// show the image
imshow("Image", im_temp);
cout << "Click on four corners of a billboard and then press ENTER" << endl;
// 注意鼠标旋转顺序和原图定义角点顺序要一致
setMouseCallback("Image", mouseHandler, &data);
waitKey(0);
// ---------- 开始你的代码 --------------
// 计算原图四个角点和目标图区域对应角点的 Homography
// 用H对原图做变换
// 提取鼠标点击的四个角点
// 把目标图中对应区域像素值设置为0dst << "\ttemp size: " << size_temp << std::endl;
// 把原图叠加到目标图上
// ---------- 结束你的代码 --------------
// Display image.
imshow("Image", im_dst);
waitKey(0);
return 0;
}
#include
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)
{
// Read in the image.
// input your image
// 新的广告图片
Mat im_src = imread("new.jpg");
Size size = im_src.size();
// Create a vector of points.
// 广告图片的四个角
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)); // 右上角
// Destination image
// 广告框图片
Mat im_dst = imread("ad.jpg");
// Set data for mouse handler
Mat im_temp = im_dst.clone();
userdata data;
data.im = im_temp;
// show the image
imshow("Image", im_temp);
cout << "Click on four corners of a billboard and then press ENTER" << endl;
// 注意鼠标旋转顺序和原图定义角点顺序要一致
// 在广告框上选取广告的的四个点
setMouseCallback("Image", mouseHandler, &data);
waitKey(0);
// 我想输出看一下坐标点是咋样的
// 这里就是想投影成什么形状的四边形的四个点坐标
for (auto i : data.points)
{
std::cout << i << std::endl;
}
// ---------- 开始你的代码 --------------
// 计算原图四个角点和目标图区域对应角点的 Homography
Mat h_matrix = findHomography(pts_src/*广告图片的四个顶点*/, data.points/*原广告的四个顶点*/);
std::cout << h_matrix << std::endl; // 单应矩阵
// 用H对原图做变换
warpPerspective(im_src/*新的广告图片*/, im_temp/*广告框图片*/, h_matrix/*单应矩阵*/, im_temp.size());
// 提取鼠标点击的四个角点
// 将data.points 从 vector 类型转换为 Point 类型
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));
Size size_dst = im_dst.size();
Size size_temp = im_temp.size();
std::cout << "dst size: " << size_dst << "\ttemp size: " << size_temp << std::endl;
// 把原图叠加到目标图上
im_dst = im_dst + im_temp;
// ---------- 结束你的代码 --------------
// Display image.
imshow("Image", im_dst);
waitKey(0);
return 0;
}