opencv学习:图像轮廓识别及代码实现
图像轮廓
1.获取图像轮廓
cv2.findContours() 函数是 OpenCV 库中用于检测图像中轮廓的函数。它可以检测到图像中所有连通区域的边界,并返回这些轮廓的列表。从 OpenCV 3.4 版本开始,这个函数的返回值和参数有所变化,以下是详细的参数说明:
方法:
contours, hierarchy = cv2.findContours( img, mode, method )
参数说明
-
img:输入图像,必须是二值图像。图像中的轮廓将基于此图像进行检测。
-
mode:轮廓检索模式,用于指定要检索哪些轮廓。可用的模式有:
cv2.RETR_EXTERNAL:只检索最外层的轮廓。cv2.RETR_LIST:检索所有轮廓,但不建立任何父子关系。cv2.RETR_CCOMP:检索所有轮廓,并将它们组织成两级层次结构。cv2.RETR_TREE:检索所有轮廓,并重建完整的层次结构。
-
method:轮廓近似方法,用于指定如何存储轮廓点。可用的方法有:
cv2.CHAIN_APPROX_NONE:存储所有轮廓点。cv2.CHAIN_APPROX_SIMPLE:只存储轮廓的拐点,这可以减少轮廓点的数量。
返回值
- contours:这是一个 Python 列表,其中包含了检测到的轮廓。每个轮廓都是一个形状为
(n, 1, 2)的 numpy 数组,其中n是轮廓点的数量。 - hierarchy:这是一个 numpy 数组,包含了轮廓的层次信息。层次信息可以用来了解轮廓之间的父子关系。
2.绘制图像轮廓
在OpenCV中,cv2.drawContours()函数用于在图像上绘制轮廓。这个函数非常强大,因为它允许你指定轮廓的颜色、线条粗细以及其他参数。下面是这个函数的详细参数说明:
方法:
cv2.drawContours(img, contours, contourIdx, color, thickness, lineType=None, hierarchy=None)
参数说明
-
img:目标图像,即你要在其上绘制轮廓的图像。这个图像应该是一个可以修改的图像数组。
-
contours:这是一个轮廓列表。轮廓可以是OpenCV中找到的任何轮廓,通常是一个形状为
(N, 1, 2)的numpy数组,其中N是轮廓中的点数。 -
contourIdx:指定要绘制的轮廓的索引。如果传递的是-1,则绘制所有轮廓。
-
color:轮廓线的颜色。这应该是一个具有三个元素的元组,表示BGR颜色(例如,红色为(0, 0, 255))。
-
thickness:线条的粗细。如果设置为正数,则线条的粗细为指定的像素数;如果设置为
cv2.FILLED或-1,则轮廓将被填充。 -
lineType(可选):线条的类型。默认是
cv2.LINE_8,表示8连通性线。其他选项包括cv2.LINE_4(4连通性线)和cv2.LINE_AA(抗锯齿线)。 -
hierarchy(可选):轮廓的层次结构。这是一个与
contours数组相对应的数组,其中包含每个轮廓的层次信息。如果提供,可以用来绘制轮廓的父子关系。
实验代码
1.获取图像
import cv2# 读取图像
phone = cv2.imread('cat.png') # 读取名为'cat.png'的图像# 将图像转换为灰度图像
phone_gray = cv2.cvtColor(phone, cv2.COLOR_BGR2GRAY) # 将彩色图像转换为灰度图# 应用阈值操作以创建二值图像
ret, phone_binary = cv2.threshold(phone_gray, 120, 255, cv2.THRESH_BINARY) # 使用阈值120将灰度图转换为二值图
# cv2.imshow('1',phone_binary) # 显示二值图像
2.查找轮廓
# 查找轮廓
_, contours, hierarchy = cv2.findContours(phone_binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) # 在二值图中查找轮廓
# 打印轮廓数量和层次结构信息
print(hierarchy) # 打印轮廓的层次结构信息
print(len(contours)) # 打印轮廓的数量
3.复制图像用于绘制轮廓
# 复制图像用于绘制轮廓
image_copy = phone.copy()
image_copy = cv2.drawContours(image=image_copy, contours=contours, contourIdx=-1, color=(0, 255, 0), thickness=3) # 在图像上绘制所有轮廓
# cv2.imshow('contours',image_copy) # 显示绘制了轮廓的图像
cv2.waitKey(0) # 等待按键
4.计算轮廓面积和周长
# 计算第一个和第二个轮廓的面积
area_0 = cv2.contourArea(contours[0])
area_1 = cv2.contourArea(contours[1])
print(area_0, area_1) # 打印面积# 计算第一个轮廓的周长
length = cv2.arcLength(contours[0], closed=True)
print(length) # 打印周长
5.查找轮廓
# 筛选面积大于10000的轮廓
a_list = []
for i in range(len(contours)):if cv2.contourArea(contours[i]) > 10000:a_list.append(contours[i])# 找到第七个轮廓的最小包围圆
cnt = contours[6]
(x, y), r = cv2.minEnclosingCircle(cnt)
phone_circle = cv2.circle(phone, (int(x), int(y)), int(r), (0, 255, 0), 2) # 在图像上绘制最小包围圆
cv2.imshow('phone_circle', phone_circle) # 显示绘制了最小包围圆的图像# 找到第七个轮廓的最小包围矩形
x, y, w, h = cv2.boundingRect((cnt))
phone_rectangle = cv2.rectangle(phone, (x, y), (x + w, y + h), (0, 255, 0), 2) # 在图像上绘制最小包围矩形
cv2.imshow('phone_rectangle', phone_rectangle) # 显示绘制了最小包围矩形的图像
6.轮廓近似
# 重新查找轮廓
image, contours, hierarchy = cv2.findContours(phone_binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)# 对最后一个轮廓进行轮廓近似
epsilon = 0.001 * cv2.arcLength(contours[-1], True)
approx = cv2.approxPolyDP(contours[-1], epsilon, True)
phone_new = phone.copy()
image_contours = cv2.drawContours(phone_new, [approx], contourIdx=-1, color=(0, 255, 0), thickness=3) # 在图像上绘制近似轮廓
cv2.imshow('image_contours', image_contours) # 显示绘制了近似轮廓的图像cv2.waitKey(0)
实验分析
- 通过阈值操作,图像中的轮廓被清晰地分离出来,这为后续的轮廓处理提供了便利。
- 轮廓的面积和周长的计算对于理解图像中对象的大小和形状特征非常重要。
- 最小包围圆和最小包围矩形的绘制有助于识别和定位图像中的主要对象。
- 轮廓近似可以简化轮廓的形状,减少计算复杂度,同时保留轮廓的主要特征。
结论
本实验通过使用OpenCV库成功地完成了图像处理的各个步骤,包括图像的读取、转换、阈值操作、轮廓查找、面积和周长计算、最小包围圆和矩形的绘制以及轮廓近似。这些技术在图像识别、对象检测和图像分析等领域有着广泛的应用。
相关文章:
opencv学习:图像轮廓识别及代码实现
图像轮廓 1.获取图像轮廓 cv2.findContours() 函数是 OpenCV 库中用于检测图像中轮廓的函数。它可以检测到图像中所有连通区域的边界,并返回这些轮廓的列表。从 OpenCV 3.4 版本开始,这个函数的返回值和参数有所变化,以下是详细的参数说明&…...
存储课程学习笔记2_借助内核插入一个文件系统,用文件夹下测试文件系统(mount文件系统到目录下是入口)
裸盘是如何能达到我们日常操作目录那样,按目录依次访问文件等,实际上就是基于裸盘上,用文件系统进行控制。 0:总结。 0:mount是入口,一个裸盘先赋予文件系统,然后mount后才可以用。 1…...
chunk-vendors.js 文件过大导致页面加载缓慢解决方案
1、路由懒加载 在 Webpack 中,我们可以使用动态 import语法来定义代码分块点 (split point): import(./Foo.vue) // 返回 Promise如果您使用的是 Babel,你将需要添加 syntax-dynamic-import 插件,才能使 Babel 可以正确地解析语…...
【Postgresql】地理空间数据的存储与查询,查询效率优化策略,数据类型与查询速度的影响
注:使用postgresql数据库会用到PostGIS 扩展。 一、安装PostGIS 扩展 在 PostgreSQL 中遇到错误 “type geography does not exist” 通常意味着你的 PostgreSQL 数据库还没有安装 PostGIS 扩展,或者 PostGIS 扩展没有被正确地安装在你的数据库中。geo…...
设计模式应用
单例模式 RunTime类是单例模式的体现,getRunTime()方法会返回一个唯一的实例。确保程序中只有一个唯一的RunTime类对象建造者模式 StringBuilder和StringBuffer是建造者模式的体现工厂模式 Calender类中Calender.getInstance()方法 DriverManager.getConnection()方…...
Android开机启动流程
Android开机启动流程 systemReady启动"added application" frameworks/base/services/java/com/android/server/SystemServer.java mainnew SystemServer().run();startBootstrapServicesmActivityManagerService ActivityManagerService.Lifecycle.startService(…...
数据结构基本知识
一、什么是数据结构 1.1、组织存储数据 ---------》内存(存储) 1.2、研究目的 如何存储数据(变量,数组....)程序数据结构算法 1.3、常见保存数据的方法 数组:保存自己的数据指针:是间接访问已经存在的…...
浙大数据结构:02-线性结构4 Pop Sequence
这道题我们采用数组来模拟堆栈和队列。 简单说一下大致思路,我们用栈来存1234.....,队列来存输入的一组数据,栈与队列进行匹配,相同就pop 机翻 1、条件准备 stk是栈,que是队列。 tt指向的是栈中下标,fr…...
java开发,记录一些注解和架构 pojo、entity、respository
最近接了一个项目,说是项目其实也不算是项目,因为是把这个项目赛到其他项目中的。 熟悉一些这个项目的功能,梳理了一下,在代码开发中主要关心pojo、entity、respository、controller、service。 在这里主要记录前3个的流程与作用…...
MatLab基础学习01
MatLab基础学习01 1.基础入门2.MatLab的数据类型2.1数字2.2字符串2.3矩阵2.4.元胞数组2.5结构体 3.MatLab的矩阵的操作3.1矩阵定义与构造3.2矩阵的下标取值 4.MatLab的逻辑流程4. For循环结构4.2 While循环,当条件成立的时候进行循环4.3 IF end 1.基础入门 matlba必…...
第 5 章多视图几何
本章讲解如何处理多个视图,以及如何利用多个视图的几何关系来恢复照相机位置信息和三维结构。通过在不同视点拍摄的图像,我们可以利用特征匹配来计算出三维场景点以及照相机位置。本章会介绍一些基本的方法,展示一个三维重建的完整例子&#…...
IOS 开发者账号注册流程
注册步骤 准备资料 营业执照 法人信息(电话、身份证信息) 注册邮箱(公司邮箱) 开发者信息(电话、身份证信息、邮箱)1. 注册AppleID 注册地址: https://appleid.apple.com/account 填写表单信…...
netty之NioEventLoop和NioEventLoopGroup
类结构图 NioEventLoopGroup #mermaid-svg-5g1iVjr5oyhqXK92 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-5g1iVjr5oyhqXK92 .error-icon{fill:#552222;}#mermaid-svg-5g1iVjr5oyhqXK92 .error-text{fill:#55222…...
睿考网:中级经济师考试题型有哪些?
中级经济师考试时间在每年的11月份,2024年考试时间定于11月16-17日,考试科目为《经济基础知识》与《专业知识与实务》两科。 《专业知识与实务》有10个专业,分别是工商管理、知识产权、农业经济、财政税收、金融、保险、运输经济、人力资源管…...
kubernetes集群部署Confluence 7.2.0+mysql 5.7(自测有效)
背景介绍: Confluence是一个专业的企业知识管理与协同软件。使用简单,但它强大的编辑和站点管理特征能够帮助团队成员之间共享信息、文档协作、集体讨论,信息推送。 这里介绍的使用的是Confluence 7.2.0版本的。 一、在kubernetes集群部署 1…...
Vmware ubuntu22.04 虚拟机 连接Windows主机虚拟串口
1. Windows虚拟串口配置 虚拟串口下载:虚拟串口 VSPD 的使用_vspd使用教程-CSDN博客 虚拟串口使用:使用虚拟串口在一台电脑上模拟串口通讯_pc怎么模拟一主多从串口-CSDN博客 2. ubuntu虚拟串口配置 Vmware ubuntu22.04 虚拟机 连接windows主机虚拟串口…...
Postgresql碎片整理
创建pgstattuple 扩展 CREATE EXTENSION pgstattuple 获取表的元组(行)信息,包括空闲空间的比例和行的平均宽度 SELECT * FROM pgstattuple(表名); 查看表和索引大小 SELECT pg_relation_size(表名), pg_relation_size(索引名称); 清理碎片方…...
【最新华为OD机试E卷-支持在线评测】字母组合(200分)多语言题解-(Python/C/JavaScript/Java/Cpp)
🍭 大家好这里是春秋招笔试突围 ,一枚热爱算法的程序员 💻 ACM金牌🏅️团队 | 大厂实习经历 | 多年算法竞赛经历 ✨ 本系列打算持续跟新华为OD-E/D卷的多语言AC题解 🧩 大部分包含 Python / C / Javascript / Java / Cpp 多语言代码 👏 感谢大家的订阅➕ 和 喜欢�…...
力扣493.翻转对
class Solution {public static int MAXN 50001;public static int[] help new int[MAXN];public static void main(String[] args) {}public static int reversePairs(int[] arr) {return counts(arr, 0, arr.length - 1);}//统计l …… r上反转对的数量,同时计算…...
潜望长焦+快充:vivo X200系列,小尺寸手机的大突破
在智能手机市场日益激烈的竞争中,厂商们不断推陈出新,以满足消费者多样化的需求。vivo作为中国知名的智能手机品牌,一直以其创新的设计和强大的功能赢得市场的认可。 近日,vivo X200系列的即将发布引起了广泛关注,特别…...
AlphaStar强化学习工程范式:从星际争霸到工业决策
1. 这不是“下棋”的升级版:AlphaStar 的强化学习到底在学什么? 很多人第一次听说 AlphaStar,第一反应是:“哦,又一个打败人类的AI,跟 AlphaGo 差不多吧?”——这个理解偏差非常典型࿰…...
Unity低耦合可复用交互系统设计与落地
1. 为什么“交互系统”在Unity项目里总被反复重写?我带过三支不同规模的Unity团队,从百人MMO到五人独立游戏,几乎每个项目都会在第3个月左右出现一个标志性场景:美术同学发来一段动画片段,说“这个门要点击打开”&…...
如何在Mac上免费快速导出微信聊天记录:WeChatExporter终极指南
如何在Mac上免费快速导出微信聊天记录:WeChatExporter终极指南 【免费下载链接】WeChatExporter 一个可以快速导出、查看你的微信聊天记录的工具 项目地址: https://gitcode.com/gh_mirrors/wec/WeChatExporter 你是否曾因误删重要微信聊天记录而焦虑&#x…...
跨境电商标题焦虑?QA揭秘“批量更新标题“如何拯救你的运营效率
Q1:什么是"批量更新标题"?这玩意儿真的存在吗?Q:小彭,我听说有个功能叫"批量更新标题",能批量改产品标题,是真的吗?还是又是那种"画大饼"的工具&…...
面部美化 API 集成指南
面部美化 API 集成指南 在本教程中,我们将介绍如何集成面部美化 API。该 API 能够准确识别面部特征,并通过用户上传的面部图像实现皮肤平滑、皮肤美白和去痘等美化功能(每张图像最多可处理五张面孔)。 环境准备 在使用 API 之前…...
圆桌探讨AI原生人才:从定义、来源到培养留存,为企业老板提供实战手册
嘉宾介绍真正AI原生的人或不来现场,对于积极转型的20%人群,有实战手册可用于找到、培养并留住他们。目前,仅1%的企业是AI原生企业,20%积极拥抱变化,80%在苦苦挣扎,人才情况也类似。一场圆桌深入探讨企业“赶…...
Android动态换肤框架深度解析:如何5分钟实现应用主题实时切换
Android动态换肤框架深度解析:如何5分钟实现应用主题实时切换 【免费下载链接】Android-Skin-Loader 一个通过动态加载本地皮肤包进行换肤的皮肤框架 项目地址: https://gitcode.com/gh_mirrors/an/Android-Skin-Loader 在Android应用开发中,主题…...
【QMT 量化实战】股市 “高开低走“ 是陷阱还是机会?(下)附完整 Python 代码
摘要 本文为《股市 "高开低走" 是陷阱还是机会?》系列下篇,提供基于QMT 量化交易平台的完整 "高开低走" 策略 Python 实现代码。包含 Xtquant 初始化、全局参数配置、数据获取、趋势判断、周期计算及结果输出等全流程代码ÿ…...
CV产线MLOps平台:图像原生处理与硬件感知交付
1. 项目概述:这不是又一个“模型训练平台”,而是一套能真正跑通CV产线的MLOps工作流“Streamline Your Computer Vision Stack with an End-to-End MLOps Platform”——这个标题里藏着三个被太多团队长期忽视的关键事实:第一,“C…...
Rshell框架实战:红队内网渗透的信道管理与双平台协同
1. 这不是“教你怎么黑”,而是还原一次真实红队作业的完整切片Rshell框架——这个名字在渗透测试圈子里不算陌生,但真正把它用透、用稳、用出生产级效果的人,远比想象中少。我见过太多人把Rshell当成一个“带图形界面的msfvenomnc组合包”&am…...
