《数字图像处理-OpenCV/Python》连载(26)绘制椭圆和椭圆弧

《数字图像处理-OpenCV/Python》连载(26)绘制椭圆和椭圆弧


本书京东优惠购书链接:https://item.jd.com/14098452.html
本书CSDN独家连载专栏:https://blog.csdn.net/youcans/category_12418787.html

在这里插入图片描述


第 4 章 绘图与鼠标交互


本章介绍OpenCV的绘图功能和简单的鼠标交互处理方法。与Excel或Matplotlib中的可视化数据图不同,OpenCV中的绘图功能主要用于在图像的指定位置绘制几何图形。


本章内容概要

  • 学习OpenCV绘图的基本方法和参数。
  • 通过学习OpenCV绘图函数,能在图像上绘制直线、矩形、圆形和多边形等,以及在图像上添加文字和符号。
  • 介绍鼠标交互操作方法,通过鼠标、键盘与显示图像的实时交互获取数据。

4.5 绘制圆形和椭圆

4.5.2 绘制椭圆和椭圆弧

函数cv.ellipse用于在图像上绘制椭圆轮廓、填充椭圆、椭圆弧或填充椭圆扇区。

函数原型

cv.ellipse(img, center, axes, angle, startAngle, endAngle, color[, thickness=1, lineType=LINE_8, shift=0]) → img
cv.ellipse(img, box, color[, thickness=1, lineType=LINE_8]) → img

参数说明

  • img:输入/输出图像,允许为单通道灰度图像或多通道彩色图像。
  • center:椭圆中心点的坐标,格式为元组(x,y)。
  • axes:椭圆半轴长度,格式为元组 (hfirst,hsecond)。
  • angle:椭圆沿x轴方向的旋转角度(角度制,按顺时针方向)。
  • startAngle:绘制椭圆/圆弧的起始角度。
  • endAngle:绘制椭圆/圆弧的终止角度。
  • box:旋转矩形类RotateRect,格式为元组((x,y),(w,h),angle)。

注意问题

  • (1)椭圆参数的定义非常复杂,容易混淆,以下结合图4-5所示的椭圆绘制参数示意图来解释。
    • axes的值是椭圆主轴长度的一半,而不是主轴长度。第一半轴hfirst指x轴顺时针旋转时首先遇到的轴,与长轴或短轴无关;第二半轴hsecond是与第一半轴垂直的轴。
    • startAngle和endAngle都是指从第一半轴开始顺时针旋转的角度,起止角度与次序无关。(0,360)表示绘制整个椭圆,(0,180)表示绘制半个椭圆。

在这里插入图片描述
图4-5 椭圆绘制参数示意图

  • (2)box是旋转矩形类RotatedRect,由box可确定一个内接于box的椭圆。

    • 旋转矩形类RotatedRect在Python中是形状为((x,y),(w,h),angle)的元组,(x,y)表示矩形中心点坐标,(w,h)表示矩形的宽和高、angle表示旋转角度,范围为[-180,180]。
  • (3) 函数cv.ellipse采用分段线性曲线逼近椭圆弧边界。如果需要对椭圆进行更多控制,可以使用ellipse2Poly检索曲线后进行渲染或填充。


【例程0405】绘制椭圆和椭圆弧

本例程用于绘制椭圆和椭圆弧,注意对照图4-5理解各个参数的含义。


# 【0405】绘制椭圆和椭圆弧
import cv2 as cv
import numpy as np
from matplotlib import pyplot as pltif __name__ == '__main__':img = np.ones((400, 600, 3), np.uint8)*224img1 = img.copy()img2 = img.copy()# (1) 半轴长度 (haf) 的影响cx, cy = 150, 200  # 圆心坐标angle = 120  # 旋转角度startAng, endAng = 0, 360  # 开始角度,结束角度haf = [50, 100, 150, 180]  # 第一轴的半轴长度has = 100  # 第二轴的半轴长度for i in range(len(haf)):color = (i*50, i*50, 255-i*50)cv.ellipse(img1, (cx,cy), (haf[i],has), angle, startAng, endAng, color, 2)angPi = angle * np.pi / 180  # 转换为弧度制,便于计算坐标xe = int(cx + haf[i]*np.cos(angPi))ye = int(cy + haf[i]*np.sin(angPi))cv.circle(img1, (xe,ye), 2, color, -1)cv.arrowedLine(img1, (cx,cy), (xe,ye), color)  # 从圆心指向第一轴端点text = "haF={}".format(haf[i])cv.putText(img1, text, (xe+5,ye), cv.FONT_HERSHEY_SIMPLEX, 0.6, color)# 绘制第二轴xe = int(cx + has*np.sin(angPi))  # 计算第二轴端点坐标ye = int(cy - has*np.cos(angPi))cv.arrowedLine(img1, (cx, cy), (xe, ye), color)  # 从圆心指向第二轴端点text = "haS={}".format(has)cv.putText(img1, text, (xe-80, ye+30), cv.FONT_HERSHEY_SIMPLEX, 0.6, color)# (2) 旋转角度 (angle) 的影响cx, cy = 420, 180  # 圆心坐标haf, has = 120, 60  # 半轴长度startAng, endAng = 0,360  # 开始角度,结束角度angle = [0, 30, 60, 135]  # 旋转角度for i in range(len(angle)):color = (i*50, i*50, 255-i*50)cv.ellipse(img1, (cx,cy), (haf,has), angle[i], startAng, endAng, color, 2)angPi = angle[i] * np.pi / 180  # 转换为弧度制,便于计算坐标xe = int(cx + haf*np.cos(angPi))ye = int(cy + haf*np.sin(angPi))cv.circle(img1, (xe,ye), 2, color, -1)cv.arrowedLine(img1, (cx,cy), (xe,ye), color)  # 从圆心指向第一轴端点text = "rot {}".format(angle[i])cv.putText(img1, text, (xe+5,ye), cv.FONT_HERSHEY_SIMPLEX, 0.6, color)# (3) 起始角度 (startAngle) 的影响 Icx, cy = 60, 80  # 圆心坐标haf, has = 45, 30  # 半轴长度angle = 0  # 旋转角度endAng = 360  # 结束角度startAng = [0, 45, 90, 180]  # 开始角度for i in range(len(startAng)):color = (i*20, i*20, 255-i*20)cyi = cy+i*90cv.ellipse(img2, (cx,cyi), (haf,has), angle, startAng[i], endAng, color, 2)angPi = angle * np.pi / 180  # 转换为弧度制,便于计算坐标xe = int(cx + haf*np.cos(angPi))ye = int(cyi + haf*np.sin(angPi))cv.arrowedLine(img2, (cx,cyi), (xe,ye), 255)  # 从圆心指向第一轴端点text = "start {}".format(startAng[i])cv.putText(img2, text, (cx-40,cyi), cv.FONT_HERSHEY_SIMPLEX, 0.6, color)text = "end={}".format(endAng)cv.putText(img2, text, (10, cy-50), cv.FONT_HERSHEY_SIMPLEX, 0.6, 255)# (4) 起始角度 (startAngle) 的影响 IIcx, cy = 180, 80  # 圆心坐标haf, has = 45, 30  # 半轴长度angle = 30  # 旋转角度endAng = 360  # 结束角度startAng = [0, 45, 90, 180]  # 开始角度for i in range(len(startAng)):color = (i*20, i*20, 255-i*20)cyi = cy+i*90cv.ellipse(img2, (cx,cyi), (haf,has), angle, startAng[i], endAng, color, 2)angPi = angle * np.pi / 180  # 转换为弧度制,便于计算坐标xe = int(cx + haf*np.cos(angPi))ye = int(cyi + haf*np.sin(angPi))cv.arrowedLine(img2, (cx,cyi), (xe,ye), 255)  # 从圆心指向第一轴端点text = "start {}".format(startAng[i])cv.putText(img2, text, (cx-40,cyi), cv.FONT_HERSHEY_SIMPLEX, 0.6, color)text = "end={}".format(endAng)cv.putText(img2, text, (150,cy-50), cv.FONT_HERSHEY_SIMPLEX, 0.6, 255)# (5) 结束角度 (endAngle) 的影响 Icx, cy = 300, 80  # 圆心坐标haf, has = 45, 30  # 半轴长度angle = 0  # 旋转角度startAng = 0  # 开始角度endAng = [45, 90, 180, 360]  # 结束角度for i in range(len(endAng)):color = (i*20, i*20, 255-i*20)cyi = cy+i*90cv.ellipse(img2, (cx,cyi), (haf,has), angle, startAng, endAng[i], color, 2)angPi = angle * np.pi / 180  # 转换为弧度制,便于计算坐标xe = int(cx + haf*np.cos(angPi))ye = int(cyi + haf*np.sin(angPi))cv.arrowedLine(img2, (cx,cyi), (xe,ye), 255)  # 从圆心指向第一轴端点text = "end {}".format(endAng[i])cv.putText(img2, text, (cx-40,cyi), cv.FONT_HERSHEY_SIMPLEX, 0.6, color)text = "start={}".format(startAng)cv.putText(img2, text, (250,cy-50), cv.FONT_HERSHEY_SIMPLEX, 0.6, 255)# (6) 结束角度 (endAngle) 的影响 IIcx, cy = 420, 80  # 圆心坐标haf, has = 45, 30  # 半轴长度angle = 30  # 旋转角度startAng = 45  # 开始角度endAng = [30, 90, 180, 360]  # 结束角度for i in range(len(endAng)):color = (i*20, i*20, 255-i*20)cyi = cy+i*90cv.ellipse(img2, (cx,cyi), (haf,has), angle, startAng, endAng[i], color, 2)angPi = angle * np.pi / 180  # 转换为弧度制,便于计算坐标xe = int(cx + haf*np.cos(angPi))ye = int(cyi + haf*np.sin(angPi))cv.arrowedLine(img2, (cx,cyi), (xe,ye), 255)  # 从圆心指向第一轴端点text = "end {}".format(endAng[i])cv.putText(img2, text, (cx-40,cyi), cv.FONT_HERSHEY_SIMPLEX, 0.6, color)text = "start={}".format(startAng)cv.putText(img2, text, (370,cy-50), cv.FONT_HERSHEY_SIMPLEX, 0.6, 255)# (7) 起始角度和结束角度的影响cx, cy = 540, 80  # 圆心坐标haf, has = 40, 30  # 半轴长度angle = 30  # 旋转角度startAng = [0, 0, 180, 180 ]  # 开始角度endAng = [90, 180, 270, 360]  # 结束角度for i in range(len(endAng)):color = (i*20, i*20, 255-i*20)cyi = cy+i*90cv.ellipse(img2, (cx,cyi), (haf,has), angle, startAng[i], endAng[i], color, 2)angPi = angle * np.pi / 180  # 转换为弧度制,便于计算坐标xe = int(cx + haf*np.cos(angPi))ye = int(cyi + haf*np.sin(angPi))cv.arrowedLine(img2, (cx,cyi), (xe,ye), 255)  # 从圆心指向第一轴端点text = "start {}".format(startAng[i])cv.putText(img2, text, (cx-40,cyi-20), cv.FONT_HERSHEY_SIMPLEX, 0.6, color)text = "end {}".format(endAng[i])cv.putText(img2, text, (cx-40,cyi), cv.FONT_HERSHEY_SIMPLEX, 0.6, color)text = "rotate={}".format(angle)cv.putText(img2, text, (490,cy-50), cv.FONT_HERSHEY_SIMPLEX, 0.6, 255)plt.figure(figsize=(9, 3.5))plt.subplot(121), plt.title("1. Ellipse1"), plt.axis('off')plt.imshow(cv.cvtColor(img1, cv.COLOR_BGR2RGB))plt.subplot(122), plt.title("2. Ellipse2"), plt.axis('off')plt.imshow(cv.cvtColor(img2, cv.COLOR_BGR2RGB))plt.tight_layout()plt.show()

程序说明:
运行结果,绘制椭圆和椭圆弧如图4-6所示。
(1)图4-6(1)的左侧图形用于比较半轴长度的影响,表明第一半轴hfirst与长轴或短轴无关,而是取决于椭圆的旋转方向。
(2)图4-6(1)的右侧图形用于比较旋转角度的影响,旋转角度是指沿x轴方向顺时针旋转的角度。
(3)起始角度和结束角度的定义及关系比较复杂,图4-6(2)给出了详细示例,请对照程序注释与显示图像进行比较和理解。

在这里插入图片描述

图4-6 绘制椭圆和椭圆弧


版权声明:
youcans@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/134014737)
Copyright 2023 youcans, XUPT
Crated:2023-10-24

欢迎关注本书CSDN独家连载专栏
《数字图像处理-OpenCV/Python》连载: https://blog.csdn.net/youcans/category_12418787.html

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

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

相关文章

同心创变,共赢未来 ▏易我科技2023年度“春种秋收”经营分析会圆满举行

2023年10月12日—10月13日,易我科技举行了2023年度管理层秋季团建暨“春种秋收”经营分析会,全体管理干部参加了本次活动。 01 本次团建活动的主题是“同心创变,共赢未来”,旨在通过一系列有趣而富有挑战性的团队活动&#xff0c…

计算机能转嵌入式吗?

计算机能转嵌入式吗?计算机和嵌入式不是一个范畴的,嵌入式是计算机的一个求职方向或者细分领域。你应该把他和Java放在一个层次上而不是跟整个计算机放在一个层次上。最近很多小伙伴找我,说想要一些嵌入式资料,然后我根据自己从业…

Node编写用户注册接口

目录 前言 创建服务器 编写注册接口API 创建路由对象,将路由对象导出去 将路由对象导出到服务器中 判断用户发起注册请求时是否输入账号或密码 验证表单数据 在数据库中创建表 在node中绑定mysql数据库 判断用户注册的账号密码是否已经被注册 密码加密 完…

水质分析仪器升级新功能

水质分析仪器:是一种适用于水质多参数测试的便携式仪器。它具有7英寸的触摸彩色屏幕,用户可以通过触摸屏幕进行操作和查看测试结果。 该仪器主要用于测定COD,氨氮,总磷,总氮等常规水质指标,pH值、溶解氧、…

CVer从0入门NLP(一)———词向量与RNN模型

🍊作者简介:秃头小苏,致力于用最通俗的语言描述问题 🍊专栏推荐:深度学习网络原理与实战 🍊近期目标:写好专栏的每一篇文章 🍊支持小苏:点赞👍🏼、…

rancher2.6.4配置管理k8s,docker安装

docker快速安装rancher并管理当前k8s集群。 1、拉镜像 docker pull rancher/rancher:v2.6.4 2、启动rancher 启动很慢 --privileged必须拥有root权限,并挂载卷 docker run --privileged -d --restartunless-stopped -p 80:80 -p 443:443 -v /usr/local/docker_vo…

模拟经营微信小游戏-休闲餐厅上线了

《休闲餐厅》是一款关于餐厅经营的小游戏,玩家可以在游戏中扮演餐厅老板,经营自己的休闲餐厅,收集美丽的厨娘,炒菜、做饭、卖钱、装饰餐厅,享受经营的乐趣。 在游戏中,玩家可以解锁几百种菜品,每…

【JS的设计模式一】

本文参考书籍 《JavaScript设计模式与开发实践》 在 JavaScript 编程中,this 关键字总是让人感到迷惑,Function.prototype.call 和 Function.prototype.apply 这两个方法也有着广泛的运用。我们有必要在学习设计模式之前先理解 这几个概念。 this Java…

百度Comate代码助手全新上线SaaS服务,助力企业释放10倍软件生产力!

“1024”程序员节来临之际,百度智能云宣布百度Comate智能代码助手正式上线SaaS版本,可提供10余项编码功能,适配100种开发语言,面向广大企业和开发者提供更便捷、更灵活的智能编码工具,助力企业提升研发效率。即日起企业…

python控制Windows桌面程序自动化模块uiautomation

github仓库地址:GitHub - yinkaisheng/Python-UIAutomation-for-Windows: (Donot use 3.7.6,3.8.1):snake:Python 3 wrapper of Microsoft UIAutomation. Support UIAutomation for MFC, WindowsForm, WPF, Modern UI(Metro UI), Qt, IE, Firefox, Chrome ... uiaut…

领域驱动设计:基于DDD的微服务设计实例

文章目录 项目基本信息战略设计战术设计后续的工作 用一个项目来了解 DDD 的战略设计和战术设计,走一遍从领域建模到微服务设计的全过程,一起掌握 DDD 的主要设计流程和关键 点。 项目基本信息 项目的目标是实现在线请假和考勤管理。功能描述如下&…

新材料制造业工厂MES系统解决方案

新材料是指具有优异性能和功能的材料,是国家战略性新兴产业的重要支撑。新材料涵盖了高性能结构材料、先进功能材料、生物医用材料、智能制造材料等多个领域,广泛应用于航空航天、电子信息、节能环保、生物医药等行业,对于提升国家综合实力和…

生成式AI革命对亚马逊的电商业务是威胁还是机遇?

来源:猛兽财经 作者:猛兽财经 总结: (1)当所有人都在关注生成式AI是如何威胁谷歌(GOOG)的搜索业务之际,投资界却忽视了一个事实,即:它也给亚马逊(AMZN)的电商业务带来了威胁。 &…

使用Selenium-PO设计模式提高Web自动化测试效率

PO(page object)设计模式是在自动化中已经流行起来的一种易于维护和减少代码的设计模式。在自动化测试中,PO对象作为一个与页面交互的接口。测试中需要与页面的UI进行交互时,便调用PO的方法。这样做的好处是,如果页面的…

哪吒X选车指南:推荐哪吒X 500lite 版

当下,紧凑型纯电动SUV市场新车不断,可选项越来越多。最近哪吒汽车又上市一款“大气舒适新标杆”——哪吒X,限时权益价10.88万元-12.88万元,以大空间,超舒适,更安全等优势,强势对标AION Y Plus和元Plus等车型。 很多有购车打算的消费者看过价格和配置,直呼哪吒X是“性价比显眼包…

使用Vscode创建一个C_Hello程序

Vscode用来学习C语言语法确实很方便。问题是安装好了,不会用,或编译失败,也是常有的事情,其中一个原因就是不会创建工作区。下面介绍使用Vscode创建一个C语言工作区。有时候看着很简单,时间久了,我竟然忘记…

Mr.Alright---MTK安卓13 抬手亮屏功能的逻辑

该功能在系统设置-显示-拿起设备时唤醒 alps\vendor\mediatek\proprietary\packages\apps\MtkSettings\src\com\android\settings\display\LiftToWakePreferenceController.javapublic boolean isAvailable() {SensorManager sensors (SensorManager) mContext.getSystemServ…

在keil中debug分析单片机数据和函数调用过程(c51为例),使用寄存器组导致错误原因分析

寄存器参考 参考2 [寄存器组使用using参考](https://blog.csdn.net/weixin_46720928/article/details/110221835) keil中的using关键字参考 官方文档里关于using的说明可参阅2个地方,(1)keil软件菜单栏->Help->…

RabbitMQ的五种常见消费模型

目录 引言1. 简单队列模型(Simple Queue Model)优缺点及适用场景代码示例 2. 工作队列模型(Work Queue Model)优缺点及适用场景代码示例 3. 发布/订阅模型(Publish/Subscribe Model)优缺点及适用场景代码示…

python接口自动化测试(单元测试方法)

一、环境搭建 python unittest requests实现http请求的接口自动化Python的优势:语法简洁优美, 功能强大, 标准库跟第三方库灰常强大,建议大家事先了解一下Python的基础;unittest是python的标准测试库,相比于其他测试框架是python目前使用最广…