python学opencv|读取图像(二十二)使用cv2.polylines()绘制多边形

【1】引言

前序学习进程中,已经掌握了使用python+opencv绘制线段、矩形和圆形的基本操作,相关链接包括且不限于:

python学opencv|读取图像(十八)使用cv2.line创造线段-CSDN博客

python学opencv|读取图像(十九)使用cv2.rectangle()绘制矩形-CSDN博客

python学opencv|读取图像(二十)使用cv2.circle()绘制圆形-CSDN博客

python学opencv|读取图像(二十一)使用cv2.circle()绘制圆形进阶-CSDN博客

在此基础上,我们进一步学习回合绘制多边形。

【2】官网教程

点击下述链接,直达官网:

OpenCV: Drawing Functions

在官网,会看到如下介绍:

图1 

这里的几个参数意义为:

void cv::polylines     (     InputOutputArray     img,  #输入的画布
        InputArrayOfArrays     pts, #多边形的各个端点
        bool     isClosed, #图形是否封闭,True为封闭图形,False为开放图形
        const Scalar &     color, #图形颜色
        int     thickness = 1, #图形线宽
        int     lineType = LINE_8, #线条存储类型
        int     shift = 0 ) #各个短点的坐标数据存储类型,暂无需关注

【3】代码测试

从这里,我们开始测试代码。

代码可以在绘制矩形的基础上稍作修改,这里先给出完整段落(代码里有大量的注释,方便大家直接调用后练习绘制线段、圆和矩形):

import numpy as np  # 引入numpy模块
import cv2 as cv  # 引入cv模块canvas = np.ones((580, 580, 3), np.uint8) * 225  # 绘制一个580*580大小的画布,3代表有3个通道,unit8为图像存储格式
canvasa = np.ones((580, 580, 3), np.uint8) * 25  # 绘制一个580*580大小的画布,3代表有3个通道,unit8为图像存储格式# 第一个通道值
#for i in range(0, 580, 1):#for j in range(0, 580, 1):#canvas[i, j, 0] = 0.2 * (i + j)  # 第一个通道值# 第二个通道值
#for i in range(0, 580, 1):#for j in range(0, 580, 1):#canvas[i, j, 1] = 50 * np.cos(i ^ j) + 55 * np.sin(j ^ i) + 150 * np.sin(j - i)  # 第二个通道值# 第三个通道值
for i in range(0, 580, 1):for j in range(0, 580, 1):canvas[i, j, 2] = 100 * np.tanh(i + j) + 100 * np.tanh(i - j) + 50 * np.cos(j - i)  # 第三个通道值pts0=np.array([[100,50],[200,50],[250,250],[50,250]],np.int32)
pts1=np.array([[100,300],[250,500],[200,300],[50,500]],np.int32)
pts2=np.array([[350,150],[450,150],[500,350],[300,350]],np.int32)canvas0=cv.polylines(canvas,[pts0],True,(120,100,25),5)
canvas1=cv.polylines(canvas,[pts1],False,(120,200,225),5)
canvas2=cv.polylines(canvas,[pts2],True,(120,100,25),5)#x0=285 #圆心横坐标
#y0=285 #圆心横坐标
#r=160 #半径
#for i in range(0,10,1):#canvas = cv.circle(canvas, ((i-5)*5+280, (i-5)*5+280), (200+i,15*i,10*i), 2) #输出同心圆#canvas = cv.circle(canvas, (285, 285), 80, (0, 0, 255), 3)  # 第一个圆形
#canvas = cv.circle(canvas, (100, 285), 80, (0, 255, 255), -1)  # 第二个圆形
#canvas = cv.circle(canvas, (470, 285), 80, (255, 0, 0), -1)  # 第三个圆形
# canvas = cv.rectangle(canvas, (50, 30), (530, 550), (155, 120, 60), 5)  # 矩形
# canvas = cv.rectangle(canvas, (80, 80), (500, 500), (55, 160, 230), 10)  # 矩形
# canvas = cv.rectangle(canvas, (150, 150), (430, 430), (50, 120, 90), -1)  # 矩形
# canvas = cv.line(canvas, (50, 550), (550, 550), (58, 50, 150), 15)  # 线段
# canvas = cv.line(canvas, (300, 50), (300, 550), (120, 150, 25), 20)  # 线段cv.imshow('Polylines', canvas)  # 在屏幕展示绘制圆形的效果
#cv.imshow('Polylines1', canvas1)  # 在屏幕展示绘制圆形的效果
#cv.imshow('Polylines2', canvas2)  # 在屏幕展示绘制圆形的效果
cv.imwrite('Polylines.png', canvas)  # 保存图像
cv.waitKey()  # 图像不会自动关闭
cv.destroyAllWindows()  # 释放所有窗口

代码运行后获得的图像为:

图2

这里的核心行代码的意义是:

pts0=np.array([[100,50],[200,50],[250,250],[50,250]],np.int32) 是用于绘图的第一组点。

pts1=np.array([[100,300],[250,500],[200,300],[50,500]],np.int32) 是用于绘图的第二组点。

pts2=np.array([[350,150],[450,150],[500,350],[300,350]],np.int32) 是用于绘图的第三组点 。

canvas0=cv.polylines(canvas,[pts0],True,(120,100,25),5) 是调用第一组点绘制的多边形 。

canvas1=cv.polylines(canvas,[pts1],False,(120,200,225),5) 是调用第二组点绘制的多边形。

canvas2=cv.polylines(canvas,[pts2],True,(120,100,25),5) 是调用第三组点绘制的多边形。

在左下角看到一个不封闭交叉的图像,这是因为:

【a】canvas1=cv.polylines(canvas,[pts1],False,(120,200,225),5),这里的False约定了图像不封闭。

【b】pts1=np.array([[100,300],[250,500],[200,300],[50,500]],np.int32) 里面的点没有按照顺时针或者逆时针的顺序给定,所以点的连线出现了交叉。

【4】代码修改

继续增加代码,让背景颜色更加繁复:

# 第一个通道值
for i in range(0, 580, 1):for j in range(0, 580, 1):canvas[i, j, 0] = 0.2 * (i + j)  # 第一个通道值# 第二个通道值
for i in range(0, 580, 1):for j in range(0, 580, 1):canvas[i, j, 1] = 50 * np.cos(i ^ 255) + 55 * np.sin(j ^ 255) + 150 * np.sin(255+j - i)  # 第二个通道值# 第三个通道值
for i in range(0, 580, 1):for j in range(0, 580, 1):canvas[i, j, 2] = 100 * np.tanh(i + j+255) + 100 * np.tanh(i - j-255) + 50 * np.cos(j - i)  # 第三个通道值

运行代码后的图像为:

图3

此时的完整代码为:

import numpy as np  # 引入numpy模块
import cv2 as cv  # 引入cv模块canvas = np.ones((580, 580, 3), np.uint8) * 225  # 绘制一个580*580大小的画布,3代表有3个通道,unit8为图像存储格式
canvasa = np.ones((580, 580, 3), np.uint8) * 25  # 绘制一个580*580大小的画布,3代表有3个通道,unit8为图像存储格式# 第一个通道值
for i in range(0, 580, 1):for j in range(0, 580, 1):canvas[i, j, 0] = 0.2 * (i + j)  # 第一个通道值# 第二个通道值
for i in range(0, 580, 1):for j in range(0, 580, 1):canvas[i, j, 1] = 50 * np.cos(i ^ 255) + 55 * np.sin(j ^ 255) + 150 * np.sin(255+j - i)  # 第二个通道值# 第三个通道值
for i in range(0, 580, 1):for j in range(0, 580, 1):canvas[i, j, 2] = 100 * np.tanh(i + j+255) + 100 * np.tanh(i - j-255) + 50 * np.cos(j - i)  # 第三个通道值pts0=np.array([[100,50],[200,50],[250,250],[50,250]],np.int32) #第一组点
pts1=np.array([[100,300],[250,500],[200,300],[50,500]],np.int32) #第二组点
pts2=np.array([[350,150],[450,150],[500,350],[300,350]],np.int32) #第三组点canvas0=cv.polylines(canvas,[pts0],True,(120,100,25),5) #多边形
canvas1=cv.polylines(canvas,[pts1],False,(120,200,225),5) #多边形
canvas2=cv.polylines(canvas,[pts2],True,(120,100,25),5) #多边形#x0=285 #圆心横坐标
#y0=285 #圆心横坐标
#r=160 #半径
#for i in range(0,10,1):#canvas = cv.circle(canvas, ((i-5)*5+280, (i-5)*5+280), (200+i,15*i,10*i), 2) #输出同心圆#canvas = cv.circle(canvas, (285, 285), 80, (0, 0, 255), 3)  # 第一个圆形
#canvas = cv.circle(canvas, (100, 285), 80, (0, 255, 255), -1)  # 第二个圆形
#canvas = cv.circle(canvas, (470, 285), 80, (255, 0, 0), -1)  # 第三个圆形
# canvas = cv.rectangle(canvas, (50, 30), (530, 550), (155, 120, 60), 5)  # 矩形
# canvas = cv.rectangle(canvas, (80, 80), (500, 500), (55, 160, 230), 10)  # 矩形
# canvas = cv.rectangle(canvas, (150, 150), (430, 430), (50, 120, 90), -1)  # 矩形
# canvas = cv.line(canvas, (50, 550), (550, 550), (58, 50, 150), 15)  # 线段
# canvas = cv.line(canvas, (300, 50), (300, 550), (120, 150, 25), 20)  # 线段cv.imshow('Polylines', canvas1)  # 在屏幕展示绘制圆形的效果
#cv.imshow('Polylines1', canvas1)  # 在屏幕展示绘制圆形的效果
#cv.imshow('Polylines2', canvas2)  # 在屏幕展示绘制圆形的效果
cv.imwrite('Polylines.png', canvas)  # 保存图像
cv.waitKey()  # 图像不会自动关闭
cv.destroyAllWindows()  # 释放所有窗口

【5】总结

掌握了python+opencv绘制多边形的基本技巧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/64368.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

教师管理系统

大概功能: 1.显示所有教师 2.按姓名查找教师 3.按工号查找教师 4.增加教师 5.删除教师 6.退出 数据会保存到 txt 文件里面 姓名:必须是中文 手机号码:必须是11位,必须是数字 效果展示: 代码展示: Teache…

小程序配置文件 —— 14 全局配置 - tabbar配置

全局配置 - tabBar配置 tabBar 字段:定义小程序顶部、底部 tab 栏,用以实现页面之间的快速切换;可以通过 tabBar 配置项指定 tab 栏的表现,以及 tab 切换时显示的对应页面; 在上面图中,标注了一些 tabBar …

[Wireshark] 使用Wireshark抓包https数据包并显示为明文、配置SSLKEYLOGFILE变量(附下载链接)

wireshark 下载链接:https://pan.quark.cn/s/eab7f1e963be 提取码:rRAg 链接失效(可能会被官方和谐)可评论或私信我重发 chrome与firefox在访问https网站的时候会将密钥写入这个环境变量SSLKEYLOGFILE中,在wireshark…

Android笔记(四十一):TabLayout内的tab不滚动问题

背景 假设二级页面是上面图片的布局,当进来时TabLayout和ViewPager2绑定完就马上调setCustomItem,跳转到最后一个tab页面时,会发现tab不滚动,手动滑一下ViewPager2时才会滚动tab到正确的位置 原因分析 调用TabLayoutMediator.at…

【Spring】 Bean 注入 HttpServletRequest 能保证线程安全的原理

文章目录 前言1. 图示2. 源码坐标后记 前言 今天看了一段老业务代码,HttpServletRequest 被注入后直接用于业务逻辑。 好奇Spring是如何解决线程安全问题。 Controller public class TestController {ResourceHttpServletRequest request;ResponseBodyGetMapping(…

CSS面试题|[2024-12-24]

1.说一下CSS的盒模型 在HTML页面中的所有元素都可以看成是一个盒子 盒子的组成:内容content、内边距padding、边框border、外边距margin 盒模型的类型: 标准盒模型 margin border padding content IE盒模型 margin content(包括border p…

Unity中如何修改Sprite的渲染网格

首先打开SpriteEditor 选择Custom OutLine,点击Genrate 则在图片边缘会出现边缘线,调整白色小方块可以调整边缘 调整后,Sprite就会按照调整后的网格渲染了。 如何在UI中使用? 只要在UI的Image组件中选择Use Sprite Mesh 即可 结果&#xff1…

【Artificial Intelligence篇】AI 前沿探秘:开启智能学习的超维征程

目录 一、人工智能的蓬勃发展与智能学习的重要性: 二、数据的表示与处理 —— 智能学习的基石: 三、构建一个简单的感知机模型 —— 智能学习的初步探索: 四、神经网络 —— 开启超维征程的关键一步: 五、超维挑战与优化 —— 探索智能学习的深度: 六、可视化与交互 —— …

docker-compos mysql5.7主从配置

docker-compos mysql5.7主从配置 docker-compose目录结构 配置文件 master/my.cnf [client] port 3306 socket /var/run/mysqld/mysqld.sock[mysqld_safe] pid-file /var/run/mysqld/mysqld.pid socket /var/run/mysqld/mysqld.sock nice 0…

开源轻量级文件分享服务Go File本地Docker部署与远程访问

???欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老…

路过石岩浪心古村

周末常去的七彩城堡儿童乐园附近经常有老房子,没想到老房子最多的地方还是浪心古村。而且越看越有历史。 见到一座写着《序西书室》的房子,我最开始以为是一个古代的学校。但是查了百度更加不知道什么意思了哈。‌“序西书室”‌是指《文心雕龙》中的一个…

面经hwl

线程进程协程区别 线程、进程和协程是计算机编程中常见的三个并发模型,它们各自有不同的特点和应用场景: 1. 进程 (Process) 定义: 进程是操作系统中资源分配的基本单位,代表一个正在运行的程序实例。特点: 独立性: 每个进程有自己独立的内…

【每日学点鸿蒙知识】PersistentStorage持久化、插槽方法、相对布局、上拉加载下拉刷新、List联动滑动

1、HarmonyOS 使用PersistentStorage持久化用户信息无效? 在首页通过StorageLink(‘userInfoTest’) userInfoTest: string 获取,获不到,返回undefind。是什么原因呢? 首先在首页时,在Entry外声明PersistentStorage…

torch.tensor

torch.tensor 通过复制数据构造一个张量 (构造出的张量是一个没有自动微分(autograd )历史的张量,也称为叶张量,参考Autograd mechanics)。 torch.tensor(data, *, dtypeNone, deviceNone, requires_gra…

探索PyTorch:从入门到实践的demo全解析

探索PyTorch:从入门到实践的demo全解析 一、环境搭建:PyTorch的基石(一)选择你的“利器”:安装方式解析(二)步步为营:详细安装步骤指南二、基础入门demo:点亮第一盏灯(一)张量操作:深度学习的“积木”(二)自动求导:模型学习的“幕后英雄”三、数据处理demo:喂饱…

SpringMVC学习(二)——RESTful API、拦截器、异常处理、数据类型转换

一、RESTful (一)RESTful概述 RESTful是一种软件架构风格,用于设计网络应用程序。REST是“Representational State Transfer”的缩写,中文意思是“表现层状态转移”。它基于客户端-服务器模型和无状态操作,以及使用HTTP请求来处理数据。RES…

Windows中安装Python3

Windows中安装Python3 1. 下载Python安装包 首先,访问Python的官方网站 Python.org,选择适合你Windows版本的Python安装包。 2. 运行安装包 下载完成.exe文件后,双击运行安装包。在安装过程中,有一些关键的选项需要特别注意&a…

JS数值类型中特殊数值NaN(Not-a-Number)理解和应用场景

NaN 的含义 在 JavaScript 中,NaN 是一种特殊的数值类型,表示 “Not-a-Number”。它通常用于标识数学运算或类型转换的结果无法产生有效数值的情况。 特性 类型为数值: console.log(typeof NaN); // "number"尽管 NaN 表示 “不是…

虚幻引擎结构之UWorld

Uworld -> Ulevel ->Actors -> AActor 在虚幻引擎中,UWorld 类扮演着至关重要的角色,它就像是游戏世界的总指挥。作为游戏世界的核心容器,UWorld 包含了构成游戏体验的众多元素,从游戏实体到关卡设计,再到物…

java中logback怎么开启异步功能

在Java中使用Logback时,开启异步日志记录功能可以通过配置AsyncAppender来实现。异步日志记录可以显著提高应用程序的性能,因为它将日志记录操作从主线程移到了后台线程执行,从而减少了主线程的阻塞时间。 步骤 1: 添加 Logback 配置文件 确…