探秘OpenCV中的findContours函数
文章目录
- 导言
- findContours函数的作用
- 函数原型
- 原理分析
- 应用场景
- 代码示例
- 结语
导言
在计算机视觉领域,图像处理是一项重要的任务。而在图像处理的过程中,轮廓(Contours)的提取是一项基础且关键的操作。OpenCV库中的findContours函数就是用于找到图像中的轮廓的工具之一。本文将深入介绍findContours函数的作用、原理、应用场景,并结合C++和OpenCV提供一些简单的示例代码,方便读者入门。
findContours函数的作用
findContours函数的主要作用是在二值化图像中找到轮廓,这些轮廓是由相邻的像素组成的对象的边界。该函数能够识别并返回图像中所有的轮廓,并以一种易于处理的数据结构存储。
findContours函数详解
findContours是OpenCV中用于在二值化图像中查找轮廓的函数之一。下面详细介绍该函数的原型及参数作用。
函数原型
void findContours(InputOutputArray image, OutputArrayOfArrays contours, OutputArray hierarchy, int mode, int method, Point offset = Point());
参数说明
image:输入输出参数,是二值化的源图像。在函数执行后,该图像可能会被修改,以强调轮廓。注意,输入图像必须是8位单通道图像。
contours:输出参数,存储找到的轮廓的容器。它是一个向量的向量(vector<vector>),每个元素都代表一个轮廓,其中每个Point表示轮廓上的一个点。
hierarchy:输出参数,用于存储轮廓的层级信息。它是一个向量,每个元素包含了关于一个轮廓的层级关系,包括下一个轮廓、上一个轮廓、子轮廓和父轮廓的索引。
mode:表示轮廓的检索模式,是一个整数值。常见的模式有:
RETR_EXTERNAL:只检索最外层的轮廓。
RETR_LIST:检索所有轮廓并存储为列表。
RETR_CCOMP:检索所有轮廓并组织为两层的层级结构。
RETR_TREE:检索所有轮廓并完整重构轮廓层级。
method:表示轮廓的逼近方法,同样是一个整数值。常见的方法有:
CHAIN_APPROX_NONE:存储所有的轮廓点,不进行任何压缩。
CHAIN_APPROX_SIMPLE:压缩水平、垂直和对角方向,只保留终点。
CHAIN_APPROX_TC89_L1和CHAIN_APPROX_TC89_KCOS:应用 Teh-Chin 链逼近算法。
offset:可选参数,表示轮廓中所有点的偏移。默认为Point(),即无偏移。
函数作用
findContours函数的主要作用是根据给定的模式和方法,在二值化图像中找到并提取轮廓。以下是各参数的作用:
image:作为输入,传入函数的二值化图像。
contours:作为输出,包含找到的轮廓信息。
hierarchy:作为输出,包含了轮廓之间的关系信息,如子轮廓、父轮廓等。
mode:决定了轮廓的检索模式,即找到哪些轮廓。
method:决定了轮廓的逼近方法,即如何表示轮廓的形状。
offset:可选参数,用于指定轮廓中所有点的偏移。
通过使用findContours函数,我们可以方便地在图像中定位并提取感兴趣的对象轮廓,为后续的图像处理和分析提供了基础。
原理分析
findContours函数的工作原理主要基于图像的边缘检测和连接分析。它的实现步骤可以概括为以下几个步骤:
图像预处理:首先,输入图像通常需要进行二值化处理,将图像转换为黑白两色,以便更容易检测轮廓。
边缘检测:利用一些边缘检测算法(如Sobel、Canny等),找到图像中的边缘。
轮廓查找:根据边缘信息,找到轮廓的起点,并按照一定规则遍历整个轮廓,将轮廓上的点存储起来。
轮廓连接:将相邻的轮廓点连接成完整的轮廓。
存储结果:将找到的轮廓以一种数据结构(通常是向量)存储,以便后续使用。
应用场景
findContours函数在许多计算机视觉任务中都得到广泛应用,例如:
目标检测:用于识别图像中的物体轮廓,从而进行目标检测。
图像分割:通过轮廓提取,可以将图像分割成不同的区域,有助于进一步的分析。
手写体识别:在手写体数字或字符识别中,findContours可以用于提取数字的轮廓。
医学图像分析:在医学图像中,该函数可用于分割和分析组织结构。
代码示例
使用C++与OpenCV写代码
以下是一个简单的C++代码示例,演示了如何使用OpenCV的findContours函数来查找并绘制图像中的轮廓:
#include <opencv2/opencv.hpp>
#include <iostream>using namespace cv;
using namespace std;int main() {// 读取图像Mat image = imread("example.jpg", IMREAD_GRAYSCALE);if (image.empty()) {cerr << "Unable to read the image" << endl;return -1;}// 二值化图像Mat binaryImage;threshold(image, binaryImage, 128, 255, THRESH_BINARY);// 查找轮廓vector<vector<Point>> contours;vector<Vec4i> hierarchy;findContours(binaryImage, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);// 绘制轮廓Mat contourImage = Mat::zeros(image.size(), CV_8UC3);drawContours(contourImage, contours, -1, Scalar(0, 255, 0), 2);// 显示原始图像和带有轮廓的图像imshow("Original Image", image);imshow("Contours", contourImage);waitKey(0);return 0;
}
在这个示例中,首先读取一幅灰度图像,然后通过二值化处理。接着使用findContours函数找到图像中的轮廓,最后使用drawContours函数将轮廓绘制在一张空白图像上。最终,通过OpenCV的imshow函数显示原始图像和包含轮廓的图像。
结语
通过findContours函数,我们能够方便地在图像中找到并提取出对象的轮廓,为后续的图像处理和分析提供了基础。希望通过本文的介绍和代码示例,读者能够更好地理解并运用这一强大的函数。
相关文章:
探秘OpenCV中的findContours函数
文章目录 导言findContours函数的作用函数原型原理分析 应用场景代码示例结语 导言 在计算机视觉领域,图像处理是一项重要的任务。而在图像处理的过程中,轮廓(Contours)的提取是一项基础且关键的操作。OpenCV库中的findContours函…...

iOS 17.2更新:15Pro支持拍摄空间视频!
苹果又为开发者预览版用户推送了iOS 17.2 Beta2测试版的更新,已经注册Apple Beta版软件计划的用户只需打开设置--通用--软件更新即可在线OTA升级至最新的iOS 17.2测试版。 本次更新包大小为750M左右,内部版本号为(21C5040g)&#…...
keep-alive缓存,三级路由不生效
此文章讲诉在vue中使用keep-alive缓存,三级路由缓存失败处理方案。 一二级路由缓存无任何问题,三级以上就会失败,因此我们在路由守卫中对matched做出如下优化 Router.beforeEach((to, from, next)>{if(to.matched && to.matched.l…...

从Hadoop到对象存储,抛弃Hadoop,数据湖才能重获新生?
Hadoop与数据湖的关系 1、Hadoop时代的落幕2、Databricks和Snowflake做对了什么3、Hadoop与对象存储(OSD)4、Databricks与Snowflake为什么选择对象存储5、对象存储面临的挑战 1、Hadoop时代的落幕 十几年前,Hadoop是解决大规模数据分析的“白…...

电脑小Tip---外接键盘F1-F12快捷键与笔记本不同步
当笔记本外接一款非常好用的静音键盘后,会出现一些问题。例如:外接键盘F1-F12与笔记本不同步。具体一个例子就是,在运行matlab程序时,需要点编辑器—运行,这样就很麻烦,直接运行的快捷键是笔记本键盘上的F5…...

跨域:利用CORS实现跨域访问
跨域知识点:跨域知识点 iframe实现跨域的四种方式:iframe实现跨域 JSONP和WebSocket实现跨域:jsonp和websocket实现跨域 目录 cors介绍 简介 两种请求 简单请求 基本流程 withCredentials 属性 非简单请求 预检请求 预检请求的回应 …...

【Linux】Centos7 shell实现MySQL5.7 tar 一键安装
🦄 个人主页——🎐个人主页 🎐✨🍁 🪁🍁🪁🍁🪁🍁🪁🍁 感谢点赞和关注 ,每天进步一点点!加油!&…...

一步一步详细介绍如何使用 OpenCV 制作低成本立体相机
在这篇文章中,我们将学习如何创建定制的低成本立体相机(使用一对网络摄像头)并使用 OpenCV 捕获 3D 视频。我们提供 Python 和 C++ 代码。文末并附完整的免费代码下载链接 我们都喜欢观看上面所示的 3D 电影和视频。您需要如图 1 所示的红青色 3D 眼镜才能体验 3D 效果。它是…...
Zookeeper篇---第四篇
系列文章目录 文章目录 系列文章目录一、ZooKeeper 集群中个服务器之间是怎样通信的?二、ZooKeeper 分布式锁怎么实现的?三、了解Zookeeper的系统架构吗?一、ZooKeeper 集群中个服务器之间是怎样通信的? Leader 服务器会和每一个 Follower/Observer 服务器都建立 TCP 连接…...

Seata之TCC模式解读
目录 基本介绍 起源 概述 案例流程分析 TCC注意事项 空回滚 幂等 悬挂 具体使用 LocalTCC TwoPhaseBusinessAction 小结 基本介绍 起源 关于TCC的概念,最早是由Pat Helland于2007年发表的一篇名为《Life beyond Distributed Transactions:an Apost…...

算法--数据结构
这里写目录标题 本节内容链表与邻接表链表主要思想链表操作初始化在head结点后面插入普通插入删除操作 例子 双链表(双向循环链表)主要思想操作初始化双向插入删除第k个点 邻接表主要思想 栈和队列栈主要思想主要操作 队列主要思想操作 单调栈与单调队列…...

关系型数据库Redis安装与写入数据
文章目录 安装和初步选择数据库创建键值对数据类型 安装和初步 安装 Redis是开源的跨平台非关系型数据库,特点是占用资源低、查询速度快。 首先,在Github上下载最新发布的Redis-xxxx.zip压缩文件,下载之后解压,并将解压后的路径…...

《红蓝攻防对抗实战》十二.内网穿透之利用ICMP协议进行隧道穿透
内网穿透之利用ICMP协议进行隧道穿透 一.前言二.前文推荐三.利用ICMP协议进行隧道穿透1.ICMPsh获取反弹shell2.PingTunnel 搭建隧道 四.本篇总结 一.前言 本文介绍了利用ICMP协议进行隧道穿透的方法。ICMP协议不需要开放端口,可以将TCP/UDP数据封装到ICMP的Ping数据…...
【海德教育】国家开放大学和函授区别有:学校不同、入学门槛不同、学习方式不同、招生对象不同、学习年限不同,具体如下:
一、学校不同。 国家开放大学的招收学校是中央电大和各省市、自治州、市辖区及单设的国家开放大学。函授是成人高考学习方式,成考是普通高等院校举行的、单设的成人高等学校。 二、入学门槛不同。 国家开放大学对入学者的年龄、职业、地区和学习资历等方面都没有太多…...

单片机启动流程
存储器 一个单片机中存在rom和ram,Soc也有rom和ram(ddrx),部分Soc还包含MMU(Memory Manage Unit 内存管理单元)— (用于系统内存管理,比如说虚拟内存空间,内存区间的…...

Linux学习教程(第二章 Linux系统安装)2
第二章 Linux系统安装 四、使用U盘安装Linux系统 前面章节介绍了如何通过虚拟机 VMware 安装 Linux 系统,而实际开发中,我们更多的是要将 Linux 系统直接安装到电脑上。 直接在电脑上安装 Linux 系统的常用方法有 2 种,分别是用光盘安装和用…...

操作系统 | proc文件系统
🌈个人主页:Sarapines Programmer🔥 系列专栏:《操作系统实验室》🔖少年有梦不应止于心动,更要付诸行动。 目录结构 1. 操作系统实验之proc文件系统 1.1 实验目的 1.2 实验内容 1.3 实验步骤 1.4 实验…...
刷题笔记(第五天)
1. 给定一个罗马数字,将其转换成整数。 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。 字符 数值 I 1 V 5 X 10 L 50 C 100 …...
【OpenHarmony内核】Harmony内核互斥性信号量
文章目录 前言一、互斥性信号量是什么?二、互斥性信号量2.1 osSemaphoreNew函数创建并初始化一个信号量对象2.2 osSemaphoreGetName获取信号量对象的名称2.3 osSemaphoreAcquire获取一个信号量令牌2.4 osSemaphoreRelease2.5 osSemaphoreGetCount获取当前信号量令牌的数量2.6 …...
给OFFICE增加一个功能搜索
OFFICE功能几乎是无限的。不论你怎么熟悉,总有出乎意料的功能。前几天我使用EXCEL时,发现一个功能改名了。于是我就想,OFFICE应该增加一个功能搜索: 提供一个搜索输入栏。这个已经有了。输入搜索字串弹出一个面板,附带…...

龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法
树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...

EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...

使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...

HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...
AGain DB和倍数增益的关系
我在设置一款索尼CMOS芯片时,Again增益0db变化为6DB,画面的变化只有2倍DN的增益,比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析: 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...

搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...