OpenCV-Python(21):OPenCV查找及绘制轮廓

1.认识轮廓

1.1 目标

  • 理解什么是轮廓
  • 学习掌握找轮廓、绘制轮廓等
  • 学习使用cv2.findContours()、cv2.drawContours()函数的用法

1.2 什么是轮廓

        在OpenCV中,轮廓是图像中连续的边界线的曲线,具有相同的颜色或者灰度,用于表示物体的形状。轮廓在图像处理和计算机视觉中非常重要,常用于物体检测、形状分析、图像分割等任务。

提示:

  • 为了使轮廓更加准确,要使用二值化图像。所以,在寻找轮之前,要进行阈值化处理或者Canny边界检测。
  • 查找轮廓的函数会修改原始图像。如果你在找到轮廓之后想使用原始图像的话,你应该将原始图像存储到其他变量中。
  • 在OpenCV 中,查找廓就像在黑色背景中查找白色物体。你应该记住,要找的物体应该是白色而背景应该是黑色。

在OpenCV中,可以通过以下步骤找到图像中的轮廓:

  1. 对图像进行预处理,如灰度化、二值化等操作。
  2. 使用cv2.findContours()函数找到图像中的轮廓。该函数会返回一个包含轮廓信息的列表。
  3. 遍历轮廓列表,可以使用cv2.drawContours()函数将轮廓绘制到图像上。
  4. 对轮廓进行进一步的分析和操作,如计算轮廓的面积、周长,寻找轮廓的凸包等。

cv2.findContours()是一个用于查找图像中轮廓的函数。它的语法如下:

contours, hierarchy = cv2.findContours(image, mode, method[, contours[, hierarchy[, offset]]])

参数说明:

  • image:输入的二值化图像,通常为灰度图像或二值图像。
  • mode:轮廓检索模式,指定轮廓的层级结构。常用的取值有:
    • cv2.RETR_EXTERNAL:只检测最外层的轮廓。
    • cv2.RETR_LIST:检测所有的轮廓,不建立层级关系。
    • cv2.RETR_CCOMP:检测所有的轮廓,并将它们组织为两层的层级结构。
    • cv2.RETR_TREE:检测所有的轮廓,并完整地重建轮廓之间的层级关系。
  • method:轮廓近似方法。常用的取值有:
    • cv2.CHAIN_APPROX_NONE:保存所有的轮廓点。
    • cv2.CHAIN_APPROX_SIMPLE:压缩水平、垂直和对角线方向上的轮廓,仅保留终点。
  • contours:输出的轮廓列表,每个轮廓由一系列点组成。
  • hierarchy:可选输出的层级关系,用于表示轮廓之间的层级关系。
  • offset:可选的偏移量,用于调整轮廓的位置。

4.0以上的版本cv2.findContours()函数会返回两个值(OpenCV 3.0系列版本会返回3个值,多出的第一个值是图像),分别是轮廓列表和层级关系。轮廓列表是一个包含每个轮廓的Numpy数组,每个数组中的元素表示轮廓上的一个点,包含对边界点(x,y)的坐标。层级关系是一个包含每个轮廓的层级关系信息的Numpy数组,用于表示轮廓之间的层级关系,可用于进一步分析轮廓的形状和结构。以下是一个使用cv2.findContours()函数查找轮廓的示例代码:

import cv2# 读取图像
image = cv2.imread("image.jpg")# 灰度化
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 二值化
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)# 寻找轮廓
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 三个参数的返回
'''
_,contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
'''# 绘制轮廓
cv2.drawContours(image, contours, -1, (0, 255, 0), 3)# 显示图像
cv2.imshow("Contours", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

代码中,首先读取了一张图像,并对其进行了灰度化和二值化处理。然后使用cv2.findContours()函数找到图像中的轮廓,并将其绘制到原始图像上。最后显示图像并等待按键关闭窗口。

1.3 怎样绘制轮廓

    cv2.drawContours()是一个用于绘制轮廓的函数,它可以根据你提供的边界点绘制任何形状。它的语法如下:

cv2.drawContours(image, contours, contourIdx, color[, thickness[, lineType[, hierarchy[, maxLevel[, offset]]]]])

参数说明:

  • image:要绘制轮廓的图像。
  • contours:轮廓列表,即cv2.findContours()函数返回的轮廓列表。
  • contourIdx:要绘制的轮廓的索引,绘制独立轮廓时很有用,-1表示绘制所有轮廓。
  • color:绘制轮廓的颜色,可以是一个BGR元组或一个整数。
  • thickness:轮廓线的粗细,默认为1。
  • lineType:轮廓线的类型,默认为cv2.LINE_8,表示8连通线。
  • hierarchy:层级关系,即cv2.findContours()函数返回的层级关系。
  • maxLevel:绘制轮廓的最大层级,默认为0,表示只绘制当前层级的轮廓。
  • offset:可选的偏移量,用于调整轮廓的位置。

cv2.drawContours()函数用于在图像上绘制轮廓。可以通过设置contourIdx参数来指定要绘制的轮廓的索引,-1表示绘制所有轮廓。可以通过设置color参数来指定绘制轮廓的颜色。绘制的轮廓线的粗细可以通过thickness参数进行设置,默认为1。轮廓线的类型可以通过lineType参数进行设置,默认为cv2.LINE_8,表示画8连通线。

以下是一个使用cv2.drawContours()函数绘制轮廓的示例代码:

import cv2# 读取图像
image = cv2.imread("image.jpg")# 灰度化
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 二值化
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)# 寻找轮廓
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)# 绘制轮廓
cv2.drawContours(image, contours, -1, (0, 255, 0), 3)# 显示图像
cv2.imshow("Contours", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

在上述代码中,首先读取了一张图像,并对其进行了灰度化和二值化处理。然后使用cv2.findContours()函数找到图像中的轮廓,并使用cv2.drawContours()函数将轮廓绘制到原始图像上。最后显示图像并等待按键关闭窗口。

绘制独立的廓,如第四个轮廓:

img = cv2.drawContour(img, contours, -1, (0,255,0), 3)

但是大多数时候下面的方法更有用:

img = cv2.drawContours(img, contours, 3, (0,255,0), 3)

注意:最后这两种方法结果是一样的,但是后面的知识会告诉你最后一种方法更有用。

1.4 轮廓的近似方法

        上面查找轮廓的时候,提到了是函数cv2.findCountours() 有一个轮廓的近似方法参数,那么它到底代表什么意思呢?
        上面我们已经提到轮廓是一个形状具有相同灰度值的边界。它会存储形状边界上所有的(x,y)坐标。但是,需要将所有的这些边界点都存储吗?这就是这个参数要告诉函数cv2.findContours 的。
        这个参数如果被设置为cv2.CHAIN_APPROX_NONE,所有的边界点都会被存储。但是我们真的需要这么么多点吗?例如,当我们找的边界是一条直线时。你用需要把直线上所有的点来表示直线吗?不是的,我们只需要这条直线的两个端点而已。这就是cv2.CHAIN_APPROX_SIMPLE 要做的。它会将将廓上的冗余点去掉,压缩轮廓,从而节省内存开支。
        我们用下图中的矩形来演示这个技术。在轮廓列表中的每一个坐标上画一个蓝色圆圈。第一个图显示使用cv2.CHAIN_APPROX_NONE 的效果,一共734 个点。第二个图是使用cv2.CHAIN_APPROX_SIMPLE 的结果,只有4 个点。看到他的威力了吧:

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

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

相关文章

docker 在线安装mysql 8.0.21版本

1、拉取mysql 8.0.21版本镜像 2、查看镜像 docker images 3、在宿主机 /usr/local/mysql 下的 conf 文件夹下,创建 my.cnf 文件,并编辑内容 [mysql] default-character-setutf8 [client] port3306 default-character-setutf8 [mysqld] port3306 se…

前后台分离开发

前后台分离开发 简介 前后台分离开发,就是在项目开发过程中,对于前端代码的开发由专门的前端开发人员负责,后端代码则由后端开发人员负责,这样可以做到分工明确、各司其职,提高开发效率,前后端代码并行开…

20231231_小米音箱接入GPT

参考资料: GitHub - yihong0618/xiaogpt: Play ChatGPT and other LLM with Xiaomi AI Speaker *.设置运行脚本权限 Set-ExecutionPolicy -ExecutionPolicy RemoteSigned *.配置小米音箱 ()pip install miservice_fork -i https://pypi.tuna.tsinghua.edu.cn/sim…

单机+内部备份_全备案例

此场景为单机数据库节点内部备份,方便部署和操作,但备份REPO与数据库实例处于同一个物理主机,冗余度较低。 前期准备 配置ksql免密登录(必须) 在Kingbase数据库运行维护中,经常用到ksql工具登录数据库,本地免密登录…

Kafka安装及简单使用介绍

🍓 简介:java系列技术分享(👉持续更新中…🔥) 🍓 初衷:一起学习、一起进步、坚持不懈 🍓 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正🙏 🍓 希望这篇文章对你有所帮助,欢…

电子邮件地址填写指南:格式与常见问题解答

一个专业的电子邮件地址是一个你只用于工作目的的通信帐户。当你给收件人发送电子邮件时,这是他们最先看到的细节之一。无论你的职位或行业如何,拥有一个专业的电子邮件地址都可以提高你和所在公司的可信度。 在本文中我们解释了专业的电子邮件地址是什么…

Reac03:react脚手架配置(代理配置)

react脚手架配置 reactAjax下载Axios配置代理第二种配置代理的方式 github搜索案例 reactAjax React本身只关注于界面,并不包含发送ajax请求的代码前端应用需要通过ajax请求与后台进行交互(json数据)react应用中需要集成第三方ajax(或自己封装) 常用的ajax请求库 j…

STL——queue容器

1.queue基本概念 概念:queue是一种先进先出(First In First Out,FIFO)的数据结构,它有两个出口。 队列容器允许从一端新增元素,从另一端移除元素。 队列中只有队头和队尾才可以被外界使用,因此队列不允许…

mongoose中http server服务器解决“Access-Control-Allow-Origin mongoose”跨域问题

问题 使用mongoose做http服务器,自己构造的浏览器端jquery在访问server时,会遇到: Access to XMLHttpRequest at http://127.0.0.1:8000/ from origin null has been blocked by CORS policy: No Access-Control-Allow-Origin header is pr…

关于HTTPS

目录 什么是加密 对称加密 非对称加密 中间人攻击 引入证书 HTTPS是一个应用层的协议,是在HTTP协议的基础上引入了一个加密层. HTTP协议内容都是按照文本的方式明文传输,这就导致在传输的过程中出现一些被篡改的情况. 运营商劫持事件 未被劫持的效果,点击下载按钮,就会…

uni-app引入vant表单(附源码)

新建项目 下载安装vant npm i vant main.js引入 import { Form } from vant; import { Field } from vant;Vue.use(Form); Vue.use(Field);代码引入 <van-form submit"onSubmit"><van-fieldclass"rePwd"v-model"username"name"请…

代码随想录刷题笔记(DAY2)

今日总结&#xff1a;今天在学 vue 做项目&#xff0c;学校还有很多作业要完成&#xff0c;熬到现在写完了三道题&#xff0c;有点太晚了&#xff0c;最后一道题的题解明天早起补上。&#xff08;补上了&#xff09; Day 2 01. 有序数组的平方&#xff08;No. 977&#xff09;…

【qt】解决qt里编辑qss后失效问题(qt编码问题)

1、先创建qss文本stylesheet.qss 以按钮为例 QPushButton {background-color:rgb(240,255,255);color: rgb(0, 0, 2);border-style: outset;border-color: beige;border-radius: 10px; }/* hover按钮悬浮&#xff0c;鼠标悬浮在按钮上的状态&#xff0c;按钮颜色 */QPushButto…

Linux调试工具—gdb

&#x1f3ac;慕斯主页&#xff1a;修仙—别有洞天 ♈️今日夜电波&#xff1a;HEART BEAT—YOASOBI 2:20━━━━━━️&#x1f49f;──────── 5:35 &#x1f504; ◀️ ⏸ ▶️ ☰ …

HackTheBox - Medium - Linux - Encoding

Encoding 前言 经过10个月左右的网安自学&#xff0c;我想说的第一句话无疑是&#xff1a;感谢TryHackMe。当然&#xff0c;后续的HackTheBox&学院、CRTO等等&#xff0c;对我的帮助都很大。 许多师傅们都在年度总结&#xff0c;我也看了大家都收获很多&#xff0c;都很…

软件工程PPT 笔记摘录(2)

分析软件需求 UML 提供了用例图来分析和描述用例视角的软件需求模型 UML 提供了交互图和状态图来描述行为视角的软件需求模型 UML 提供了类图来描述和分析业务领域的概念模型 顺序图&#xff1a;强调消息传递的时间序 通信图&#xff1a;突出对象间的合作 类图&#xff0…

重温MySQL之索引那些事

文章目录 前言一、概念1.1 索引作用1.2 索引类型1.3 B树索引结构1.4 B树索引源码分析 二、查询计划2.1 explain2.2 id2.3 select_type2.4 table2.5 partitions2.6 type2.7 possible_keys2.8 key2.9 key_len2.10 ref2.11 rows2.12 filtered2.13 Extra 三、索引优化3.1 索引失效3…

C#高级 02异步编程

基础知识 1.什么是异步任务 包含了异步任务的各种状态的一个引用类型 1)正在运行、完成、结果、报错等 2)另有ValueTask值类型版本对于异步任务的抽象 1)开启异步任务后&#xff0c;当前线程并不会阻塞&#xff0c;而是可以去做其他事情 2)异步任务&#xff08;默认&#xff…

Java技术栈 —— Nginx的使用

Java技术栈 —— Nginx的使用 一、认识Nginx二、搭建Nginx环境2.1 在Ubuntu上安装Nginx 三、使用Nginx3.1 配置负载均衡(HTTP) 一、认识Nginx 企业需要运行多个相同的副本&#xff0c;并将负载分散在整个系统集群上&#xff0c;为了高性能的负载均衡&#xff0c;引入了Nginx代…

【Vue2 + ElementUI】el-table中校验表单

一. 案例 校验金额 阐述&#xff1a;校验输入的金额是否正确。如下所示&#xff0c;点击【编辑图标】会变为input输入框当&#xff0c;输入金额。当输入框失去焦点时&#xff0c;若正确则调用接口更新金额且变为不可输入状态&#xff0c;否则返回不合法金额提示 <templat…