如图,将一个矩形图像投射到图像上某一区域。这里用到几何图像变换的透视变换。首先要计算出源图像矩形(或图像中的某一区域)与目标区域间的变换矩阵,再对源图像中区域进行透视变换,再对两幅图像进行加操作。由于处理效果像对图像加上补丁,为形象化表达这里称为打补丁。
如果想从其他图像的一个不规则区域这里专指四边形区域图像,还可以参考本系列的“抠补丁”文章从图像中任意四边形区域中获取。
这里参考以下资料进行学习、整理、记录,对原代码进行简单改动和注释,如用getPerspectiveTransform()函数替换findHomography()计算转换矩阵。感谢两位。
https://blog.csdn.net/liuphahaha/article/details/50719275
https://www.learnopencv.com/homography-examples-using-opencv-python-c/
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
struct userdata
{
Mat img;
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->img, Point(x, y), 3, Scalar(0, 255, 255), 5);
imshow("Image", data->img);
if (data->points.size() < 4)
{
data->points.push_back(Point2f(x, y));
}
}
}
int main(int argc, char** argv)
{
// Read in the image. 图标
Mat img_icon = imread("outRect.jpg");
int nrows = img_icon.rows;
int ncols = img_icon.cols;
Size size = img_icon.size();
// Create a vector of points.
vector<Point2f> src_points;
src_points.push_back(Point2f(0, 0));
src_points.push_back(Point2f(size.width - 1, 0));
src_points.push_back(Point2f(size.width - 1, size.height - 1));
src_points.push_back(Point2f(0, size.height - 1));
// Destination image 大图
Mat im_dst = imread("D:/show-1.jpg");
// Set data for mouse handler
Mat im_temp = im_dst.clone();
userdata data;
data.img = im_temp;
imshow("Image", im_temp);
cout << "Click on four corners(start from left-top to left-bottom) of a billboard and then press ENTER" << endl;
//set the callback function for any mouse event
setMouseCallback("Image", mouseHandler, &data);
waitKey(0);
// Calculate Homography between source and destination points
Mat h = findHomography(src_points, data.points);
warpPerspective(img_icon, im_temp, h, im_temp.size()); //把整图投射到全0大图的某一区域
// Extract four points from mouse data
Point pts_dst[4];
for (int i = 0; i < 4; i++)
{
pts_dst[i] = data.points[i];
}
// Black out polygonal area in destination image.
fillConvexPoly(im_dst, pts_dst, 4, Scalar(0)); //将图像多边形区域置零
// Add warped source image to destination image.
im_dst = im_dst + im_temp;
imshow("dst", im_dst);
waitKey(0);
return 0;
}