OpenCV-Python实战(13)——图像轮廓
一、找轮廓 cv2.findContours()
contours,hierarchy = cv2.findContours(image=*,mode=*,method=*)
contours:找到的所有轮廓数组,数组内的元素为轮廓像素点坐标。
hierarchy:轮廓间的层次关系。
image:二值图像(cv2.threshold())。
mode:轮廓检测模式,常见方法如下:
| 模式 | 值 | 解释 |
| RETR_EXTERNAL | 0 | 只检测外部轮廓 |
| RETR_LIST | 1 | 检测所有轮廓,但不建立层级关系 |
| RETR_CCOMP | 2 | 检测所有轮廓,同时建立两个层级关系,如果内部还有轮廓则此轮廓与最外层轮廓同级 |
| RETR_TREE | 3 | 检测所有轮廓,同时建立一个树状层级关系 |
method:保存轮廓的方法,常见方法如下:
| 方法 | 值 | 解释 |
| CHAIN_APPROX_NONE | 1 | 存储所有轮廓点坐标 |
| CHAIN_APPROX_SIMPLE | 2 | 只保存轮廓顶点坐标 |
| CHAIN_APPROX_TC89L1 | 3 | 使用CHAIN_APPROX_TC89L1 近视算法保存轮廓坐标 |
| CHAIN_APPROX_TC89KCOS | 4 | 使用CHAIN_APPROX_TC89KCOS近视算法保存轮廓坐标 |
二、绘轮廓 cv2.drawContours()
img = cv2.drawContours(image=*,contours=,contourIdx=*,color=*,thickness=*,lineType=*,hierarchy=*,maxLevel=*,offset=*)
img:目标图像。
image:二值图像,用于填画上轮廓。
contours:cv2.findContours()函数返回的轮廓列表 list。
contourIdx:需要绘制的轮廓,在轮廓列表中的索引。-1 表示绘制列表中的所有轮廓。
color:(B,G,R)颜色。
thickness:轮廓粗细,-1 表示实心。
lineType:线条类型。
hierarchy:cv2.findContours() 输出的层次关系。
maxLevel:轮廓层次关系的深度,0表示绘制第0层次关系的轮廓。
offset:常数值,轮廓偏移量(相较于原轮廓坐标)
三、检测模式
3.1 外轮廓 RETR_EXTERNAL
import cv2
# 图像前处理
img = cv2.imread('contours.png') # 原图
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) # GRAY
thresh,img_threshold = cv2.threshold(img_gray,150,255,cv2.THRESH_BINARY) # 二值contours,hierarchy = cv2.findContours(img_threshold,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
img1 = cv2.drawContours(img,contours,-1,(255,0,0),3)cv2.imshow('img',img)
cv2.imshow('img_threshold',img_threshold)
cv2.waitKey(0)
cv2.destroyAllWindows()

3.2 所有轮廓 cv2.RETR_LIST
import cv2
# 图像前处理
img = cv2.imread('contours.png') # 原图
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) # GRAY
thresh,img_threshold = cv2.threshold(img_gray,150,255,cv2.THRESH_BINARY) # 二值contours,hierarchy = cv2.findContours(img_threshold,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
img1 = cv2.drawContours(img,contours,-1,(255,0,0),2)cv2.imshow('img',img)
cv2.imshow('img_threshold',img_threshold)
cv2.waitKey(0)
cv2.destroyAllWindows()

3.3 RETR_CCOMP
import cv2
import numpy as np# 图像前处理
img = cv2.imread('m.png') # 原图
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) # GRAY
thresh,img_threshold = cv2.threshold(img_gray,150,255,cv2.THRESH_BINARY) # 二值contours,hierarchy = cv2.findContours(img_threshold,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_SIMPLE)
print(hierarchy)
img1 = cv2.drawContours(img,contours,-1,(255,0,0),2)cv2.imshow('img',img)
cv2.imshow('img_threshold',img_threshold)
cv2.waitKey(0)
cv2.destroyAllWindows()
hierarchy:详细解释请参考:《OpenCV计算机视觉项目实战(Python版)---p265》
print(hierarchy)结果
[[[ 1 -1 -1 -1][-1 0 2 -1][ 3 -1 -1 1][-1 2 -1 1]]]

3.4 RETR_TREE
import cv2
import numpy as np# 图像前处理
img = cv2.imread('m.png') # 原图
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) # GRAY
thresh,img_threshold = cv2.threshold(img_gray,150,255,cv2.THRESH_BINARY) # 二值contours,hierarchy = cv2.findContours(img_threshold,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
print(hierarchy)
img1 = cv2.drawContours(img,contours,-1,(255,0,0),2)cv2.imshow('img',img)
cv2.imshow('img_threshold',img_threshold)
cv2.waitKey(0)
cv2.destroyAllWindows()
hierarchy:详细解释请参考:《OpenCV计算机视觉项目实战(Python版)---p265》
print(hierarchy) 结果:
[[[-1 -1 1 -1][ 3 -1 2 0][-1 -1 -1 1][-1 1 -1 0]]]

四、轮廓面积、周长
4.1 面积 cv2.contourArea()
area = cv2.contourArea(contour=*,oriented=*)
area:轮廓面积。
countour:要计算轮廓。
oriented:默认为:False,换回面积的绝对值。
import cv2
import numpy as np# 图像前处理
img = cv2.imread('contours.png') # 原图
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) # GRAY
thresh,img_threshold = cv2.threshold(img_gray,150,255,cv2.THRESH_BINARY) # 二值contours,hierarchy = cv2.findContours(img_threshold,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
img1 = cv2.drawContours(img,contours,-1,(255,0,0),2)
areas = []
for i in range(len(contours)):area = cv2.contourArea(contours[i])areas.append(area)
print(areas)
cv2.waitKey(0)
cv2.destroyAllWindows()
[8500.5, 15986.0, 11396.0, 11560.0, 7136.5]
4.2 面积 cv2.arcLength()
arc = cv2.arcLength(contours,closed=*)
arc:轮廓周长。
countours:要计算轮廓。
closed:Ture表示轮廓是封闭的。
import cv2
import numpy as np# 图像前处理
img = cv2.imread('contours.png') # 原图
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) # GRAY
thresh,img_threshold = cv2.threshold(img_gray,150,255,cv2.THRESH_BINARY) # 二值contours,hierarchy = cv2.findContours(img_threshold,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
img1 = cv2.drawContours(img,contours,-1,(255,0,0),2)
areas = []
for i in range(len(contours)):arc = cv2.arcLength(contours[i],closed=True)areas.append(arc)
print(areas)
cv2.waitKey(0)
cv2.destroyAllWindows()
[437.9482728242874, 492.6173119544983, 696.3086559772491, 403.98989498615265, 558.1147834062576]

相关文章:
OpenCV-Python实战(13)——图像轮廓
一、找轮廓 cv2.findContours() contours,hierarchy cv2.findContours(image*,mode*,method*) contours:找到的所有轮廓数组,数组内的元素为轮廓像素点坐标。 hierarchy:轮廓间的层次关系。 image:二值图像(cv2.t…...
javascript变量
变量 命名规范 以 字母、数字、下划线、美元符号 $ 组成、不能以 数字开头、且不能使用 js 中的关键字。 命名规范推荐采用小驼峰 命名法 。类名 采用 大驼峰命名。 var 声明变量的特点 在 script 上下文中定义的是 全局变量,全局变量会自动称为 window的属性。 在…...
在K8S中,如何查看kubelet组件的日志?
在kubernetes中,查看Kubelet组件的日志可以通过几种不同的方法。以下是详细的步骤: 1. 使用journalctl命令: 如果kubelet是通过systemd方式部署,你可以使用journalctl命令来查看其日志。执行journalctl -u kubelet将显示Kubelet…...
android studio android sdk下载地址
android studio安装后,因为公司网络原因,一直无法安装android sdk 后经过手机网络,安装android sdk成功如下,也可以手动下载后指定android sdk本地目录 https://dl.google.com/android/repository/source-35_r01.zip https://dl…...
Fetch处理大模型流式数据请求与解析
为什么有的大模型可以一次返回多个 data? Server-Sent Events (SSE):允许服务器连续发送多个 data: 行,每个代表一个独立的数据块。 流式响应:大模型服务通常以流式响应方式返回数据,提高响应速度。 批量处理&#x…...
FPGA自学之路:到底有多崎岖?
FPGA,即现场可编程门阵列,被誉为硬件世界的“瑞士军刀”,其灵活性和可编程性让无数开发者为之倾倒。但谈及FPGA的学习难度,不少人望而却步。那么,FPGA自学之路到底有多崎岖呢? 几座大山那么高?…...
从0到机器视觉工程师(二):封装调用静态库和动态库
目录 静态库 编写静态库 使用静态库 方案一 方案二 动态库 编写动态库 使用动态库 方案一 方案二 方案三 总结 静态库 静态库是在编译时将库的代码合并到最终可执行程序中的库。静态库的优势是在编译时将所有代码包含在程序中,可以使程序独立运行&…...
[极客大挑战 2019]Knife1
这里很显然,根据提示可以猜测,已经有一句话木马上传了,但是路径这里不是很清楚,不知道路径在哪里,不过还是用菜刀连一下试试: 连接成功,在根目录下发现flag。不过如果不用菜刀,可以用…...
【在Python中生成随机字符串】
在Python中生成随机字符串,你可以结合使用random模块和字符串操作。以下是一个常用的方法,通过从预定义的字符集中随机选择字符来构建字符串: import random import stringdef generate_random_string(length):# 定义字符集:可以…...
【three.js】场景搭建
three.js由场景、相机、渲染器、灯光、控制器等几个要素组成。每个要素都有不同的类型,例如光照有太阳光、环境光、半球光等等。每种光照都有不同的属性可以进行配置。 场景 场景(scene):场景是所有物体的容器,如果要…...
Singleton: WebRTC中ThreadManager中的单例模式
1. 什么是单例模式: 旨在确保一个类只有一个实例,并提供全局访问点。 应用场景:需要一个全局唯一的实例,避免资源浪费。 2. 单例模式的实现: Lazy Initialization(懒汉式)(延迟初…...
MySQL数据库笔记——多版本并发控制MVCC
大家好,这里是Good Note,关注 公主号:Goodnote,本文详细介绍MySQL的并发控制:多版本并发控制MVCC。 文章目录 背景介绍数据库并发控制——锁机制悲观锁和乐观锁悲观锁乐观锁 数据库并发控制——MVCC 的引入MVCC 和锁机…...
【0x0037】HCI_Write_Link_Supervision_Timeout命令详解
目录 一、命令概述 二、命令格式及参数说明 2.1. HCI_Write_Link_Supervision_Timeout 命令格式 2.2. Handle 2.3. Link_Supervision_Timeout 三、生成事件及参数 3.1. HCI_Command_Complete 事件 3.2. Status 3.3. Handle 四、命令执行流程 4.1. 命令准备阶段 4.…...
Linux下如何进行内存泄漏分析
前言 正文 一、环境的安装 1、tar –xf valgrind-3.17.0.tar.bz2 2、cd valgrind-3.17.0 3、./configure // 运行配置脚本生成makefile文件,可以--help查看配置项,自行按需配置,比如修改编译工具、修改安装路径等 4、make 5、make…...
Colyseus Metadata 详解
Colyseus Metadata 详解 Colyseus 是一个专注于实时多人在线游戏和应用的框架,它的 metadata 功能为每个房间提供了一个灵活且有用的机制,用来存储和共享与房间相关的非实时信息。这些信息可以用来描述房间、标记房间状态、或提供额外的房间配置选项。 …...
C语言day5:shell脚本
一、练习题1 定义一个find函数,查找ubuntu和root的gid并使用变量接收结果 二、练习题2 定义一个数组,写一个函数完成对数组的冒泡排序 三、练习题3 使用break求1-100中的质数(质数:只能被1和它本身整除,如:…...
微记录-Linux字符设备的write函数如何避免文件系统重复调用?
背景 linux字符设备的fops实现read write的时候,尤其是write,因为会指定写入的总长度,那么如果如果驱动中单次write最大个数小于需求len的时候,文件系统就会多次调用到write。他是根据wirte函数的返回值来判断的。如果返回值不是…...
本地调试自定义Maven Plugin步骤
添加自定义插件到dependencies 找到对应依赖的类,打上断点。 debug运行插件。...
二、github基础
Github基础 备用github.com网站一、用户界面-Overview(概览)1用户信息2 导航栏3 热门仓库4 贡献设置5贡献活动6搜索和筛选7自定义收藏8贡献统计9最近活动10其他链接 二、用户界面-Repositories(仓库)1 libusb_stm322 savedata3 Fi…...
如何在 Vue 2 中使用 Swiper 5.4.5 处理静态与后端数据不能切换问题
一、文章大纲 1.前言 介绍 Swiper 作为一款强大的轮播组件,常用于处理图片、文章、商品等内容的滑动展示。 在 Vue.js 项目中集成 Swiper,尤其是在 Vue 2 中使用,常见的两种数据来源:静态数据与后端数据。 在 Vue 2 项目中集成 Swiper 5.4.5 2.如何通过 npm 安装 Swiper…...
使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...
如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...
Java线上CPU飙高问题排查全指南
一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...
JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...
安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...
华为OD机考-机房布局
import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...
力扣热题100 k个一组反转链表题解
题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...
并发编程 - go版
1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...
