修改了下 https://blog.csdn.net/Yong_Qi2015/article/details/81938305?utm_source=blogxgwz2 里的代码
画轮廓函数的调用形式 (引自 https://blog.csdn.net/qq_36239854/article/details/52665107 )
void drawContours(InputOutputArray image, InputArrayOfArrays contours, int contourIdx, const Scalar& color, int thickness=1, int lineType=8, InputArray hierarchy=noArray(), int maxLevel=INT_MAX, Point offset=Point() )
函数参数详解:
其中第一个参数image表示目标图像,
第二个参数contours表示输入的轮廓组,每一组轮廓由点vector构成,
第三个参数contourIdx指明画第几个轮廓,如果该参数为负值,则画全部轮廓,
第四个参数color为轮廓的颜色,
第五个参数thickness为轮廓的线宽,如果为负值或CV_FILLED表示填充轮廓内部,
第六个参数lineType为线型,
第七个参数为轮廓结构信息,
第八个参数为maxLevel。
画轮廓函数引自 https://blog.csdn.net/u013105205/article/details/78835969/
#include <opencv.hpp>
#include <iostream>
#include <math.h>
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
//读入源图
Mat src = imread("src.jpg");
if (!src.data) {
printf("could not load image...\n");
return -1;
}
namedWindow("input image", CV_WINDOW_AUTOSIZE);
imshow("input image", src);
//读入替换图
Mat replaceImg = imread("gez.png");
imshow("replace image", replaceImg);
vector<Point> rep_corners(4);
vector<Point> src_corners(4);
//替换图的四角坐标
rep_corners[0] = Point(0, 0);
rep_corners[1] = Point(replaceImg.cols, 0);
rep_corners[2] = Point(replaceImg.cols, replaceImg.rows); //第三个点和第四个点的值可以互换
rep_corners[3] = Point(0, replaceImg.rows);
//源图中广告牌的四角坐标
src_corners[0] = Point(218, 50);
src_corners[1] = Point(557, 30);
src_corners[2] = Point(559, 215); //第三个点和第四个点的值可以互换
src_corners[3] = Point(273, 236);
//计算单应性矩阵
Mat h = findHomography(rep_corners, src_corners);
//替换后的广告牌图
Mat output_img;
warpPerspective(replaceImg, output_img, h, src.size());
imshow("output image", output_img);
//求广告牌的掩膜-法一
Mat m1 = Mat::zeros(replaceImg.size(), CV_8UC1); //注意size
m1 = Scalar(255);
Mat mask_output;
warpPerspective(m1, mask_output, h, src.size());
imshow("Mask Result", mask_output);
//求广告牌的掩膜-法二
Mat roi = Mat::zeros(src.size(), CV_8UC1); //注意size
vector<vector<Point>> contour;
vector<Point> pts;
pts.push_back(Point(218, 50));
pts.push_back(Point(557, 30));
pts.push_back(Point(559, 215)); //第三个点和第四个点不可以互换,采用顺时针取点
pts.push_back(Point(273, 236));
contour.push_back(pts); //一个轮廓
drawContours(roi, contour, 0, Scalar::all(255), -1);
imshow("Mask roi", roi);
//无广告牌的掩膜
Mat mask_outputsrc;
bitwise_not(mask_output, mask_outputsrc);
imshow("Masksrc Result", mask_outputsrc);
//无广告牌的源图
Mat result1;
src.copyTo(result1, mask_outputsrc);
imshow("result1", result1);
//结果图
Mat result;
add(output_img, result1, result);
imshow("Final Result", result);
waitKey(0);
return 0;
}
这篇也可以参考 https://blog.csdn.net/liuphahaha/article/details/50719275