OpenCV轮廓检测全面解析:从基础到高级应用

一、概述

       轮廓检测是计算机视觉中的基础技术,用于识别和提取图像中物体的边界。与边缘检测不同,轮廓检测更关注将边缘像素连接成有意义的整体,形成封闭的边界。

轮廓检测的核心价值
- 物体识别:通过轮廓可以识别图像中的独立物体
- 形状分析:轮廓包含了物体的形状特征信息
- 测量计算:基于轮廓可进行面积、周长等测量
- 图像分割:是许多分割算法的基础步骤

二、OpenCV轮廓检测基础

1.cv2.findContours

2. cv2.drawContours()

3.示例代码


#查找轮廓的API:image,contours,hierarchy = cv2.findContours(img, mode, method)#
# 参数:img:需要实现轮廓检测的原图# mode:轮廓的检索模式,主要有四种方式:
#      CV2.RETR_EXTERNAL:只检测外轮廓,所有子轮廓被忽略并
#      CV2.RETR_LIST:检测的轮廓不建立等级关系,所有轮廊属于同一等级
#      CV2.RETR_CCOMP:返回所有的轮廓,只建立两个级的轮。一个对象的外轮为第1级组织结构。
#          而对象内部中空洞的轮廊为第2级组织结构,空洞中的任何对象的轮又是第 1级组织结构。
#      cV2.RETR_TREE:返回所有的轮廓,建立一个完整的组织结构的轮廓。# method:轮廓的近似方法,主要有以下两种:
#      CV2.CHAIN APPROX NONE:在储所有的轮点。
#      CV2.CHAIN_APPROX_SIMPLE:压缩模式,只保留该方向的终点坐标,例如一个矩形轮廊只需4 个点来保存轮信息。
# 返回:image:返回处理的原图# contours:包含图像中所有轮廊的list对象。其中每一个独立的轮廊信息以边界点坐标(x,y)的形式储存在numpy数组中。# hierarchy:轮廊的层次结构。一个包含4个值的数组:[Next,Previous,First child, Parent]
#     Next:与当前轮廓处于同一层级的下一条轮
#     Previous:与当前轮廓处于同一层级的上一条轮
#     First child:当前轮廓的第一条子轮康
#     Parent:当前轮廓的父轮廓并
# 注意:做轮廊检测前需要将图片读取为二值数据,即像素值只为0和255.import cv2
phone = cv2.imread('phone.png')
phone_grey=cv2.cvtColor(phone,cv2.COLOR_BGR2GRAY)
cv2.imshow('phone_b',phone_grey)
cv2.waitKey(0)ret,phone_binary=cv2.threshold(phone_grey,120,255,cv2.THRESH_BINARY)
cv2.imshow('phone_binary',phone_binary)
cv2.waitKey(0)_,contours,hierarchy = cv2.findContours(phone_binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)# # 轮廓的绘制
# # cv2.drawContours(image, contours, contourIdx, color, thickness=None,
# #                  lineType=None, hierarchy=None, maxLevel=None, offset=None)
# # 参数含义如下:
# # image:要在其上绘制轮廓的输入图像。
# # contours:轮廓列表,通常由cv2.findContours()函数返回。
# # contourIdx:要绘制的轮廓的索引。如果为负数,则绘制所有轮廓。 -1
# # color:轮廓的颜色,以BGR格式表示。例如,(0, 255, 0)表示绿色。
# # thickness:轮廓线的粗细。默认值为1。
# # lineType:轮廓线的类型。默认值为cv2.LINE_8。
# # hierarchy:轮廓层次结构。通常由cv2.findContours()函数返回。
# # maxLevel:绘制的最大轮廓层级。默认值为None,表示绘制所有层级。
# # offset:轮廓点的偏移量。默认值为None。
image_copy=phone.copy()
image_copy=cv2.drawContours(image=image_copy,contours=contours,contourIdx=-1,color=(0,255,0),thickness=2)
cv2.imshow('Contours',image_copy)
cv2.waitKey(0)
cv2.destroyAllWindows()

 三、轮廓特征提取与分析

1. 基本特征计算


面积

  
周长



 

import cv2phone = cv2.imread('phone.png')
phone_grey=cv2.cvtColor(phone,cv2.COLOR_BGR2GRAY)
cv2.imshow('phone_b',phone_grey)
cv2.waitKey(0)ret,phone_binary=cv2.threshold(phone_grey,120,255,cv2.THRESH_BINARY)
cv2.imshow('phone_binary',phone_binary)
cv2.waitKey(0)_,contours,hierarchy = cv2.findContours(phone_binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)# #轮廓特征
# cv2.contourArea(contour[, oriented]) → retval      面积
# contour:顶点构成的二维向量组(如轮廓列表contours中的一个轮廓)
# oriented:定向区域标志,默认值为 False,返回面积的绝对值,Ture 时则根据轮廓方向返回带符号的数值area_0 = cv2.contourArea(contours[0])
print(area_0)
area_1 = cv2.contourArea(contours[1])
print(area_1)# arcLength(InputArray curve, bool closed)              周长
# curve,输入的二维点集(轮廓顶点),可以是 vector 或 Mat 类型。
# closed,用于指示曲线是否封闭。
length = cv2.arcLength(contours[0],closed=True)
print(length)
# 根据面积显示特定轮廓
a_list=[]
# for i in range(len(contours)):
#     if cv2.contourArea(contours[i])>10000:
#         a_list.append(contours[i])
for i in contours:if cv2.contourArea(i)>10000:a_list.append(i)
image_copy = phone.copy()
image_copy = cv2.drawContours(image=image_copy, contours=a_list, contourIdx=-1,color=(0,255,0),thickness=3)
cv2.imshow('Contours_show_10000', image_copy)
cv2.waitKey(0)

2. 轮廓近似

# 轮廓的近似
# approx = cv2.approxPolyDP(curve, epsilon, closed)
# 参数说明:
# curve:输入轮廓。
# epsilon:近似精度,即两个轮廓之间最大的欧式距离。该参数越小,得到的近似结果越接近实际轮廓;反之,得到的近似结果会更加粗略。
# closed:布尔类型的参数,表示是否封闭轮廓。如果是 True,表示输入轮廓是封闭的,近似结果也会是封闭的;否则表示输入轮廓不是封闭的,近似结果也不会是封闭的。
# 返回值:approx:近似结果,是一个ndarray数组,为1个近似后的轮廓,包含了被近似出来的轮廓上的点的坐标
import cv2phone = cv2.imread('phone.png')
phone_gray = cv2.cvtColor(phone,cv2.COLOR_BGR2GRAY) #转换为灰度图
ret,phone_thresh = cv2.threshold(phone_gray,120,255,cv2.THRESH_BINARY)  #二值化image, contours, hierarchy = cv2.findContours(phone_thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)#获取轮廓
# #计算所有轮廓面积并存储在列表中
contours_with_area=[(cnt,cv2.contourArea(cnt)) for cnt in contours]
#根据轮廓面积降序排列
sorted_contours=sorted(contours_with_area,key=lambda x:x[1],reverse=True)
#如果你只需要降序后的轮廓,可以直接提取出来
aa=sorted_contours[0][0]
print(aa)epsilon = 0.01 * cv2.arcLength(aa,True)        #设置近似精度
approx = cv2.approxPolyDP(aa, epsilon, True)   #对轮廓进行近似
print(approx.shape)
phone_new = phone.copy()
image_contours = cv2.drawContours(phone_new,[approx],contourIdx=-1,color=(0,255,0),thickness=3)#绘制轮廓
cv2.imshow('phone',phone)
cv2.waitKey(0)
cv2.imshow('image_contours',image_contours)
cv2.waitKey(0)
# # $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
# # 外接圆、外接矩形,...
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)
cv2.waitKey(0)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)
cv2.waitKey(0)

3. 轮廓匹配


# 形状匹配(值越小匹配越好)
match_value = cv2.matchShapes(cnt1, cnt2, cv2.CONTOURS_MATCH_I1, 0)# 模板匹配
template = cv2.imread('template.png',0)
w, h = template.shape[::-1]
res = cv2.matchTemplate(gray, template, cv2.TM_CCOEFF_NORMED)
threshold = 0.8
loc = np.where(res >= threshold)

总结

       OpenCV的轮廓检测功能强大而灵活,从简单的物体识别到复杂的形状分析都能胜任。掌握轮廓检测技术需要注意以下几点:
1. 良好的预处理是成功的关键
2. 根据应用场景选择合适的轮廓检索模式
3. 合理利用轮廓特征进行筛选和分析
4. 高级应用常需要结合其他图像处理技术

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

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

相关文章

Jenkins学习(B站教程)

文章目录 1.持续集成CI2.持续交付CD3.持续部署4.持续集成的操作流程5.jenkins简介6.后续安装部署,见视频 bilibili视频 Jenkins是一个开源的、提供友好操作界面的持续集成(CI)工具,起源于Hudson(Hudson是商用的),主要用…

ARM-UART

时钟选择PLCK,超时3ms自动发送,设置发送8位的缓冲区,且发送中断 设置触发深度,达到8字节将缓冲区数据发憷 中断处理函数

Rust所有权详解

文章目录 Rust所有权所有权规则作用域 内存和分配移动与克隆栈空间堆空间 关于函数的所有权机制作为参数作为返回值 引用与租借垂悬引用 Rust所有权 C/C中我们对于堆内存通常需要自己手动管理,手动申请和释放,即便有了智能指针,对于效率的影…

【在线OJ项目测试报告】

朋友们、伙计们,我们又见面了,本期来给大家带来关于在线OJ项目的测试报告,如果看完之后对你有一定的启发,那么请留下你的三连,祝大家心想事成! C 语 言 专 栏:C语言:从入门到精通 数…

【HFP】蓝牙HFP应用层核心技术研究

免提配置文件(Hands-Free Profile, HFP)作为实现设备间音频通信的关键协议,广泛应用于车载系统、蓝牙耳机等场景。本文将基于最新技术规范,深入剖析HFP应用层的功能要求、协议映射及编解码器支持,为蓝牙开发工程师提供详尽的技术指南。 一、HFP应用层功能全景图 HFP定义…

横扫SQL面试——PV、UV问题

📊 横扫SQL面试:UV/PV问题 🌟 什么是UV/PV? 在数据领域,UV(Unique Visitor,独立访客) 和 PV(Page View,页面访问量) 是最基础也最重要的指标&…

【C++】第八节—string类(上)——详解+代码示例

hello,又见面了! 云边有个稻草人-CSDN博客 C_云边有个稻草人的博客-CSDN博客——C专栏(质量分高达97!) 菜鸟进化中。。。 目录 一、为什么要学习string类? 1.1 C语言中的字符串 1.2 面试题(暂不做讲解) …

如何判断JVM中类和其他类是不是同一个类

如何判断JVM中的类是否为同一个类 在Java虚拟机(JVM)中,判断两个类是否相同需要同时满足以下三个条件: 1. 类全限定名必须相同 包括包名类名的完整路径必须完全一致例如:java.lang.String和com.example.String被视为不同类 2. 加载该类的…

ifconfig 使用详解

目录 一、基本语法二、常见用途及示例1. 查看所有网络接口信息2. 启用/禁用网络接口3. 配置 IP 地址和子网掩码4. 修改 MAC 地址5. 启用混杂模式(Promiscuous Mode)6. 设置 MTU(最大传输单元) 三、其他选项四、常见问题1. 新系统中…

1. 标准库的强依赖(核心原因)

1. 标准库的强依赖(核心原因) 容器操作(如 std::vector 扩容) 当标准库容器(如 std::vector)需要重新分配内存时,它会尝试移动现有元素到新内存,而非拷贝(为了性能&…

【MySQL】常用SQL--持续更新ing

一、配置信息类 1.查看版本 select version; 或 select version(); 2.查看配置 show global variables where variable_name in (basedir,binlog_format,datadir,expire_logs_days,innodb_buffer_pool_size,innodb_log_buffer_size,innodb_log_file_size,innodb_log_files_i…

Day82 | 灵神 | 快慢指针 重排链表

Day82 | 灵神 | 快慢指针 重排链表 143.重排链表 143. 重排链表 - 力扣(LeetCode) 思路: 笔者直接给跪了,这个难度真是mid吗 直接去看灵神的视频 环形链表II【基础算法精讲 07】_哔哩哔哩_bilibili 1.简单来说就是&#xf…

常见的微信个人号二次开发功能

一、常见开发功能 1. 好友管理 好友列表维护 添加/删除好友 修改好友信息(备注、标签等) 分组管理 创建/编辑/删除标签 好友分类与筛选 2. 消息管理 信息发送 支持多类型内容:文本、图片、视频、文件、小程序、名片、URL链接等 附加功…

Android打包及上架应用市场问题处理

一、Gradle 配置参数含义: compileSdkVersion: 29 表示项目编译时使用的 Android SDK 版本为 API 29(Android 10),仅影响编译阶段的行为(如代码语法检查、资源处理等),不直接影响运行时兼容性。…

Docker 从入门到进阶 (Win 环境) + Docker 常用命令

目录 引言 一、准备工作 1.1 系统要求 1.2 启用虚拟化 二、安装Docker 2.1 安装WSL 2 2.2 安装Docker Desktop 2.3检查是否安装成功 三、配置Docker 3.1 打开Docker配置中心 四、下载和管理Docker镜像 4.1 拉取镜像 4.2 查看已下载的镜像 4.3 运行容器 4.4 查看正…

计算机视觉5——运动估计和光流估计

一、运动估计 (一)运动场(Motion Field) 定义与物理意义 运动场是三维场景中物体或相机运动在二维图像平面上的投影,表现为图像中每个像素点的运动速度矢量。其本质是场景点三维运动(平移、旋转、缩放等&a…

介质访问控制——信道划分

什么是介质访问 介质访问(Medium Access)​ 是计算机网络中一种规则,用来解决 ​​“多台设备如何共享同一根网线/信道传输数据”​ 的问题。你可以理解为: 想象一条只能容一辆车通过的独木桥(网络中的网线、Wi-Fi信道…

ERP系统五大生产模式概述

制造业中,选择合适的生产模式是企业高效运营的关键。 以下是ERP系统支持的五大核心生产模式及其特点总结: 1. MTS(按库存生产) - 定义:先生产后销售,基于需求预测提前备货。 - 适用场景:需求稳定、标准化程度高的产品(如日用品、家电)。 - 优点:交货快、生产…

ubantu操作笔记

安装ssh服务 1.1 基本安装 sudo apt update sudo apt install openssh-server -y sudo systemctl start ssh sudo systemctl enable ssh 1.2 配置远程root登陆 # 0. 设置root密码 sudo passwd root # 1. 安装vim依赖 sudo apt-get install vim -y # 2. 编辑配置文件 s…

2-vim编辑器的安装和使用

一.常用工具介绍 前言: 我们想要编写c语言代码,可以使用linux系统提供的工具才能进行代码的编辑。代码编写后,我们还需要验证代码的书写正确。这就需要借助编译器来进行验证。linux系统为我们提供了比较好的开发工具。 vim编辑器&#xff…