opencv函数
- polylines 作用:绘制多条多边形曲线
void cv::polylines(
InputOutputArray img,
const Point* const* pts,
const int* npts,
int ncontours,
bool isClosed,
const Scalar& color,
int thickness = 1,
int lineType = LINE_8,
int shift = 0
)
void cv::polylines(
InputOutputArray img, //输入图像
InputArrayOfArrays pts, //多边形曲线点
bool isClosed, //指示绘制的多段线是否闭合的标志。如果它们是闭合的,则函数将从每条曲线的最后一个顶点到其第一个顶点绘制一条线。
const Scalar& color, //折线颜色
int thickness = 1, //多段线边缘的厚度
int lineType = LINE_8, //线段的线型类型
int shift = 0 //缩放比例(0是不缩放,4是1/4)
)
- fillPoly 填充由多个多边形轮廓界定的区域
void cv::fillPoly(InputOutputArray img,
const Point** pts,
const int* npts,
int ncontours,
const Scalar& color,
int lineType = LINE_8,
int shift = 0,
Point offset = Point())
void cv::fillPoly(
InputOutputArray img, //输入图像
InputArrayOfArrays pts, //多边形数组,其中每个多边形表示为点数组
const Scalar& color, //多边形颜色
int lineType = LINE_8, //多边形边界的类型
int shift = 0, //缩放比例(0是不缩放,4是1/4)
Point offset = Point() //轮廓所有点的偏移
)
测试代码
Mat src = imread("test.jpg");
imshow("src", src);
//方式一
//Point root_points[1][5];
//root_points[0][0] = Point(93, 146);
//root_points[0][1] = Point(243, 57);
//root_points[0][2] = Point(290, 190);
//root_points[0][3] = Point(239, 259);
//root_points[0][4] = Point(155, 240);
//const Point* ppt[1] = { root_points[0] };
//int npt[] = { 5 };
//polylines(src, ppt, npt, 1, 1, Scalar(255), 3);
//fillPoly(src, ppt, npt, 1, Scalar(0, 0, 255));
//方式二
vector<Point> pt0 = { Point(93, 146), Point(243, 57), Point(290, 190), Point(239, 259), Point(155, 240) };
vector<vector<Point>> pt1;
pt1.push_back(pt0);
polylines(src, pt1, true, Scalar(255), 3);
fillPoly(src, pt1, Scalar(0, 0, 255));
imshow("dst", src);
Mat src = imread("test.jpg");
imshow("src", src);
Point root_points[1][5];
root_points[0][0] = Point(93, 146);
root_points[0][1] = Point(243, 57);
root_points[0][2] = Point(290, 190);
root_points[0][3] = Point(239, 259);
root_points[0][4] = Point(155, 240);
const Point* ppt[1] = { root_points[0] };
int npt[] = { 5 };
polylines(src, ppt, npt, 1, 1, Scalar(0, 255, 0), 3);
imshow("poly", src);
Mat mask, dst;
src.copyTo(mask);
mask.setTo(Scalar::all(0));
fillPoly(mask, ppt, npt, 1, Scalar(255, 255, 255));
imshow("mask", mask);
src.copyTo(dst, mask);
imshow("dst", dst);
#include <opencv2/imgproc.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
using namespace std;
using namespace cv;
Mat src, img1, mask, final;
Point point;
vector<Point> pts;
int drag = 0;
int var = 0;
int flag = 0;
void mouseHandler(int, int, int, int, void*);
void mouseHandler(int event, int x, int y, int, void*)
{
// 左键按下
if (event == EVENT_LBUTTONDOWN && !drag)
{
if (flag == 0) // 标记是否生成掩码
{
// 第一次进入备份原图像
if (var == 0)
img1 = src.clone();
// 记录当前左键按下的点
point = Point(x, y);
// 在图像上将这个点用圆绘制出来,实心圆
circle(img1, point, 2, Scalar(0, 0, 255), -1, 8, 0);
// 点入vector
pts.push_back(point);
// 点的数量加1
var++;
// 表示已经有了一个点了
drag = 1;
// 如果点的数量大于1,则绘制上一个点于当前点的直线
if (var > 1)
line(img1, pts[var - 2], point, Scalar(0, 0, 255), 2, 8, 0);
// 刷新图像
imshow("Source", img1);
}
}
// 左键松起
if (event == EVENT_LBUTTONUP && drag)
{
// 显示图像
imshow("Source", img1);
drag = 0;
}
// 右键按下
if (event == EVENT_RBUTTONDOWN)
{
// 表示右键
flag = 1;
// 备份图像
img1 = src.clone();
// 如果左键点击的得到的点数不为0,则绘制多边形
if (var != 0)
{
polylines(img1, pts, 1, Scalar(0, 0, 0), 2, 8, 0);
}
// 显示图像
imshow("Source", img1);
}
// 右键松起
if (event == EVENT_RBUTTONUP)
{
flag = var;
// 创建全为0的彩色图像
final = Mat::zeros(src.size(), CV_8UC3);
// 创建掩码图像
mask = Mat::zeros(src.size(), CV_8UC1);
vector<vector<Point> > vpts;
// 如果点集为孔,则什么都不做
if (pts.size() == 0)
{
return;
}
vpts.push_back(pts);
// 用白色填充多边形(掩码图像)
fillPoly(mask, vpts, Scalar(255, 255, 255), 8, 0);
// 对原图像每一个像素进行与操作,使用mask掩码
bitwise_and(src, src, final, mask);
// 显示掩码图像
imshow("Mask", mask);
// 显示结果图像
imshow("Result", final);
// 显示原图像
imshow("Source", img1);
}
// 指示按下鼠标中间按钮,清除所有标记
if (event == EVENT_MBUTTONDOWN)
{
pts.clear();
var = 0;
drag = 0;
flag = 0;
imshow("Source", src);
}
}
int main(int argc, char **argv)
{
// 载入图像
src = imread("lena.png");
// 图像是否为孔
if (src.empty())
{
printf("Error open image !\n");
return 0;
}
// 创建窗口
namedWindow("Source", WINDOW_AUTOSIZE);
// 调用鼠标回调函数
setMouseCallback("Source", mouseHandler, NULL);
// 显示图像
imshow("Source", src);
waitKey(0);
return 0;
}
参考:
https://www.jianshu.com/p/4bd302ff91a3