『7x24小时有问必答』
点击上方蓝字关注我们
微信公众号:OpenCV学堂
关注获取更多计算机视觉与深度学习知识

很多人都问过我这个问题,OpenCV中是怎么绘制与填充多边形的,特别是填充多边形的。因为根据OpenCV中的多边形绘制函数,他们发现这是一个无解的问题。其实我在2017底做一个项目的时候当时会对得到的一个多边形边缘轮廓进行填充,我就发现OpenCV中的多边形绘制函数无法填充,但是其实换个函数就会顺利搞定,只是大家被OpenCV官方的教程误导思维定势,没有想到而已。下面我们就来详细说一下,OpenCV中的多边形绘制与填充问题。

多边形绘制
OpenCV中支持常见的点、线、圆、椭圆与矩形的绘制与填充都是通过设置thickness这个参数来实现绘制与填充,当thickness是正数的时就会绘制;当thickness为非正数时就会填充。但是对多边形来说,polylines函数把thickness设置为非正数就会直接报错,无法通过修改thickness完成填充,该函数只能实现绘制。
void  cv::polylines(

                  InputOutputArray    img,

                  InputArrayOfArrays              pts,

                  bool                isClosed,

                  const  Scalar  &                color,

                  int      thickness  =  1,

                  int      lineType  =  LINE_8,

                  int      shift  =  0

)

参数解释
img表示绘制画布,图像
pts表示多边形的点
isClosed表示是否闭合,默认闭合
color表示颜色
thickness表示线宽,必须是正数
lineType表示线渲染类型
shift表示相对位移
绘制一个多边形的代码演示如下:
1Mat  canvas  =  Mat::zeros(Size(512,  512),  CV_8UC3);

2int  w  =  canvas.cols;

3int  h  =  canvas.rows;

4Point  p1(100,  100);

5Point  p2(300,  150);

6Point  p3(300,  350);

7Point  p4(250,  450);

8Point  p5(50,  450);

9std::vector<point>  pts;

10pts.push_back(p1);

11pts.push_back(p2);

12pts.push_back(p3);

13pts.push_back(p3);

14pts.push_back(p4);

15pts.push_back(p5);

16polylines(canvas,  pts,  true,  Scalar(0,  255,  0),  1,  8,  0);
随机拾取5个点的坐标,然后完成绘制运行结果如下:
填充多边形
OpenCV中可以完成多边形填充的函数有两个,第一个填充多边形的函数为:
1void  cv::fillPoly(         

2                  InputOutputArray    img,

3                  InputArrayOfArrays              pts,

4                  const  Scalar  &                color,

5                  int      lineType  =  LINE_8,

6                  int      shift  =  0,

7                  Point              offset  =  Point()

8)

该函数参数跟polylines很相似,唯一没有的就是thickness跟isClose参数,该函数会完成一个多边形的填充操作。代码演示如下:
1Mat  canvas  =  Mat::zeros(Size(512,  512),  CV_8UC3);

2int  w  =  canvas.cols;

3int  h  =  canvas.rows;

4Point  p1(100,  100);

5Point  p2(300,  150);

6Point  p3(300,  350);

7Point  p4(250,  450);

8Point  p5(50,  450);

9std::vector<point>  pts;

10pts.push_back(p1);

11pts.push_back(p2);

12pts.push_back(p3);

13pts.push_back(p3);

14pts.push_back(p4);

15pts.push_back(p5);

16fillPoly(canvas,  pts,  Scalar(255,  0,  255),  8,  0);

17polylines(canvas,  pts,  true,  Scalar(0,  255,  255),  2,  8,  0);
第二个一次可以填充/绘制任意数目的多边形函数,该函数来自轮廓分析的轮廓绘制,因此很多人不会注意到它其实是一个很强悍的多边形填充与绘制函数,函数说明如下:
1void  cv::drawContours  (               

2        InputOutputArray    image,

3        InputArrayOfArrays    contours,

4        int      contourIdx,

5        const  Scalar  &                color,

6        int      thickness  =  1,

7        int      lineType  =  LINE_8,

8        InputArray            hierarchy  =  noArray(),

9        int      maxLevel  =  INT_MAX,

10        Point              offset  =  Point()

11)

该函数功能比较强大,一次可以完成多个多边形的填充与绘制,它本质上把每个多边形的顶点集作为轮廓看待,可以很方便的完成轮廓的绘制与填充,跟点、线、圆、椭圆与矩形的绘制与填充一样,都是通过设置thickness这个参数来实现绘制与填充。只是在输入的时候需要适当改一下。参数controus表示的多个多边形点集合,contourIdx大于零表示绘制指定索引的轮廓,-1表示绘制全部,thickness正数表示绘制,非正数表示填充。就这样一个函数就可以轻松搞定多边形的填充与绘制。代码实现如下:
1Mat  canvas  =  Mat::zeros(Size(512,  512),  CV_8UC3);

2int  w  =  canvas.cols;

3int  h  =  canvas.rows;

4Point  p1(100,  100);

5Point  p2(300,  150);

6Point  p3(300,  350);

7Point  p4(250,  450);

8Point  p5(50,  450);

9std::vector<point>  pts;

10pts.push_back(p1);

11pts.push_back(p2);

12pts.push_back(p3);

13pts.push_back(p3);

14pts.push_back(p4);

15pts.push_back(p5);

16std::vector<std::vector<point>>  contours;

17contours.push_back(pts);

18drawContours(canvas,  contours,  0,  Scalar(0,  0,  255),  -1,  8);

19drawContours(canvas,  contours,  0,  Scalar(255,  0,  255),  2,  8);

运行结果如下:
点  阅读原文  看视频版本!

善始者实繁
克终者盖寡

  推荐阅读  

</point></point></point></point>

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

上一主题上一主题         下一主题下一主题
QQ手机版小黑屋粤ICP备17165530号

关于我们·投诉举报· 用户帮助· 联系我们 · 本站服务 · 版权声明· 隐私政策 · 投搞指南

法律保护:PLC技术网,plcjs.com,plcjs.net等字样
Copyright 2010-2030. All rights reserved. 


微信公众号二维码 抖音二维码 百家号二维码 今日头条二维码哔哩哔哩二维码