技巧 | 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表示相对位移
绘制一个多边形的代码演示如下:
Mat canvas = Mat::zeros(Size(512, 512), CV_8UC3);
int w = canvas.cols;
int h = canvas.rows;
Point p1(100, 100);
Point p2(300, 150);
Point p3(300, 350);
Point p4(250, 450);
Point p5(50, 450);
std::vector<Point> pts;
pts.push_back(p1);
pts.push_back(p2);
pts.push_back(p3);
pts.push_back(p3);
pts.push_back(p4);
pts.push_back(p5);
polylines(canvas, pts, true, Scalar(0, 255, 0), 1, 8, 0);
随机拾取5个点的坐标,然后完成绘制运行结果如下:
填充多边形
OpenCV中可以完成多边形填充的函数有两个,第一个填充多边形的函数为:
void cv::fillPoly(
InputOutputArray img,
InputArrayOfArrays pts,
const Scalar & color,
int lineType = LINE_8,
int shift = 0,
Point offset = Point()
)
该函数参数跟polylines很相似,唯一没有的就是thickness跟isClose参数,该函数会完成一个多边形的填充操作。代码演示如下:
Mat canvas = Mat::zeros(Size(512, 512), CV_8UC3);
int w = canvas.cols;
int h = canvas.rows;
Point p1(100, 100);
Point p2(300, 150);
Point p3(300, 350);
Point p4(250, 450);
Point p5(50, 450);
std::vector<Point> pts;
pts.push_back(p1);
pts.push_back(p2);
pts.push_back(p3);
pts.push_back(p3);
pts.push_back(p4);
pts.push_back(p5);
fillPoly(canvas, pts, Scalar(255, 0, 255), 8, 0);
polylines(canvas, pts, true, Scalar(0, 255, 255), 2, 8, 0);
第二个一次可以填充/绘制任意数目的多边形函数,该函数来自轮廓分析的轮廓绘制,因此很多人不会注意到它其实是一个很强悍的多边形填充与绘制函数,函数说明如下:
void cv::drawContours (
InputOutputArray image,
InputArrayOfArrays contours,
int contourIdx,
const Scalar & color,
int thickness = 1,
int lineType = LINE_8,
InputArray hierarchy = noArray(),
int maxLevel = INT_MAX,
Point offset = Point()
)
该函数功能比较强大,一次可以完成多个多边形的填充与绘制,它本质上把每个多边形的顶点集作为轮廓看待,可以很方便的完成轮廓的绘制与填充,跟点、线、圆、椭圆与矩形的绘制与填充一样,都是通过设置thickness这个参数来实现绘制与填充。只是在输入的时候需要适当改一下。参数controus表示的多个多边形点集合,contourIdx大于零表示绘制指定索引的轮廓,-1表示绘制全部,thickness正数表示绘制,非正数表示填充。就这样一个函数就可以轻松搞定多边形的填充与绘制。代码实现如下:
Mat canvas = Mat::zeros(Size(512, 512), CV_8UC3);
int w = canvas.cols;
int h = canvas.rows;
Point p1(100, 100);
Point p2(300, 150);
Point p3(300, 350);
Point p4(250, 450);
Point p5(50, 450);
std::vector<Point> pts;
pts.push_back(p1);
pts.push_back(p2);
pts.push_back(p3);
pts.push_back(p3);
pts.push_back(p4);
pts.push_back(p5);
std::vector<std::vector<Point>> contours;
contours.push_back(pts);
drawContours(canvas, contours, 0, Scalar(0, 0, 255), -1, 8);
drawContours(canvas, contours, 0, Scalar(255, 0, 255), 2, 8);
运行结果如下:
- Spring Boot 2.0正式发布,升还是不升呢?
- Spring Cloud构建微服务架构:分布式服务跟踪(入门)
- Spring Cloud构建微服务架构:分布式服务跟踪(跟踪原理)
- Spring Cloud Gateway真的有那么差吗?
- Spring Cloud构建微服务架构:消息驱动的微服务(核心概念)【Dalston版】
- Golang语言社区--【基础知识】循环
- Spring Cloud构建微服务架构:消息驱动的微服务(消费组)【Dalston版】
- Spring Cloud构建微服务架构:消息驱动的微服务(消费分区)【Dalston版】
- Spring Boot中使用LDAP来统一管理用户信息
- 使用Swagger2Markup实现API文档的静态部署(一):AsciiDoc
- 使用Swagger2Markup实现API文档的静态部署(二):Markdown和Confluence
- Dubbo官方的Starter发布1.0.0测试版,与Spring Boot的结合将更加自然
- spring-boot-starter-swagger 1.2.0.RELEASE:新增分组配置功能
- 领域驱动设计
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- python数据类型强制转换实例详解
- PHP使用OB缓存实现静态化功能示例
- 在Keras中实现保存和加载权重及模型结构
- Tensorflow与Keras自适应使用显存方式
- Python类及获取对象属性方法解析
- Keras实现DenseNet结构操作
- python中format函数如何使用
- keras得到每层的系数方式
- 解决TensorFlow调用Keras库函数存在的问题
- php判断电子邮件是否正确方法
- python db类用法说明
- python中wheel的用法整理
- 使用Keras训练好的.h5模型来测试一个实例
- python中查看.db文件中表格的名字及表格中的字段操作
- Ubuntu 16.04中Laravel5.4升级到5.6的步骤