opencv基础篇 ——(十二)轮廓提取与绘制

opencv基础篇 ——(十二)轮廓提取与绘制

findContours轮廓提取

void void findContours( InputArray image, OutputArrayOfArrays contours,OutputArray hierarchy, int mode,int method, Point offset = Point());

功能介绍

cv::findContours 是 OpenCV 中用于在图像中查找轮廓的函数之一。它可以帮助你找到图像中所有的轮廓,并且可以选择性地进行轮廓的过滤和处理。主要用于在二值图像中查找对象的边界轮廓。这些轮廓通常是对象之间的分界线,可以通过它们进行形状分析、对象检测等操作。

  • image: 输入图像,必须是单通道的二值图像,即像素值为0或255(或0或1)

  • contours: 输出轮廓的容器。函数会将检测到的轮廓信息存储在这个数据结构中。具体而言,contours应当是一个 std::vector<std::vectorcv::Point> 类型的容器,其中每个内部向量代表一个轮廓,由构成该轮廓的连续边界点(cv::Point)组成。

  • hierarchy: 参数是一个可选输出参数,用于存储轮廓之间的层级关系信息。如果用户不关心轮廓间的嵌套或层次结构,可以将其设置为 noArray() 或者忽略此参数。但若希望获取轮廓间的父子关系、内部轮廓与外部轮廓的关联等信息,应提供一个合适的输出容器(如 std::vector)来接收这些数据。
    每个轮廓在 hierarchy 中对应一个四元组 (h_next, v_next, h_prev, v_prev),其中:

    • h_next:指向同一级别下下一个轮廓的索引。
    • v_next:指向当前轮廓的直接内嵌子轮廓的索引。
    • h_prev:指向同一级别下前一个轮廓的索引。
    • v_prev:指向当前轮廓的直接父轮廓的索引。
      当某个值为 -1 时,表示没有对应的邻居或父/子轮廓。这种层次信息有助于分析图像中轮廓之间的包含关系,例如用于识别内部孔洞、独立对象以及构建多级轮廓树。
  • mode: 轮廓检索模式,指定如何组织和返回检测到的轮廓。常用的模式包括:

    • cv::RETR_EXTERNAL: 只返回最外层轮廓,忽略任何嵌套的轮廓(即内部空洞或子轮廓)。
    • cv::RETR_LIST: 返回所有轮廓,不建立任何层次关系,轮廓按检测顺序排列。
    • cv::RETR_CCOMP: 返回所有轮廓,并按照两个级别构建层次结构:外部轮廓(级别1)和它们的内嵌孔洞(级别2)。
    • cv::RETR_TREE: 返回所有轮廓,并以完整的嵌套层次结构形式组织,即每个轮廓可以有任意数量的直接子轮廓。
  • method: 轮廓逼近方法,用于决定如何将实际轮廓点集近似为更紧凑的点集,以减少轮廓点的数量。常用的逼近方法包括:

    • cv::CHAIN_APPROX_SIMPLE: 仅保留轮廓端点和拐点,将轮廓压缩为一系列直线段。
    • cv::CHAIN_APPROX_TC89_L1, cv::CHAIN_APPROX_TC89_KCOS: 使用 Teh-Chin 链码算法的变种进行更复杂的逼近。
    • cv::CHAIN_APPROX_NONE: 不进行任何压缩,保留轮廓上的所有原始点。
  • offset: 可选的偏移量,表示在检测轮廓前将输入图像平移的像素值。这对于从原图像中裁剪出的部分进行轮廓检测时特别有用,可以确保返回的轮廓坐标与原图像坐标系统保持一致。

功能与用途

cv::findContours 函数的主要功能如下:

  • 轮廓检测:在二值图像中识别并分离出各个连通的白色像素区域,即独立的物体或形状。

  • 轮廓提取:将每个检测到的物体或形状的边界点序列化为一个点集(cv::Point 向量),这些点集构成了轮廓。

  • 轮廓组织:根据指定的 mode 参数,可以将轮廓按不同的层次结构进行组织和返回,如仅返回最外层轮廓、返回所有轮廓的列表,或者构建完整的嵌套轮廓树。

  • 轮廓近似:根据指定的 method 参数,可以选择是否对原始轮廓点集进行近似处理,以减小存储和后续处理的复杂性。

综上所述,cv::findContours 函数提供了一种通用且强大的工具,用于从二值图像中自动提取并结构化表示各种形状的轮廓信息。

drawContours 轮廓绘制

功能介绍

cv::drawContours 是 OpenCV 库中用于在图像上绘制轮廓的函数,常用于可视化检测到的轮廓或创建轮廓相关的图形输出。以下是该函数的功能介绍:

cv::drawContours(inputImage,           // InputOutputArray imagecontours,             // InputArrayOfArrays contourscontourIdx,           // int contourIdxcolor,                // const Scalar& colorthickness,            // int thicknesslineType,             // int lineTypehierarchy,            // InputArray hierarchymaxLevel,             // int maxLeveloffset                // Point offset
);

参数解释:

  • inputImage: 输入/输出图像(cv::Mat 类型),轮廓将在该图像上绘制。图像可以是任意通道数和深度的,但通常为单通道或三通道(彩色)的 8-bit 或 16-bit 图像。

  • contours: 输入的轮廓数组(std::vector<std::vectorcv::Point> 类型)。这是从 cv::findContours 函数或其他方式获取的一系列轮廓,每个轮廓由一组连续的边界点(cv::Point)组成。

  • contourIdx: 要绘制的轮廓索引。可以是单个整数,表示要绘制指定索引的单个轮廓;也可以是负数,此时绘制所有轮廓:

    • -1:绘制所有轮廓。
    • -2:绘制除了最大(面积最大)轮廓以外的所有轮廓。
    • -3:绘制除了最小(面积最小)轮廓以外的所有轮廓。
  • color: 绘制轮廓使用的颜色。对于单通道灰度图像,通常是一个标量值;对于彩色图像,通常是 cv::Scalar 类型的 BGR 或 BGRA 值。

  • thickness: 轮廓线的粗细。可以是正数(表示像素宽度)、负数(表示填充轮廓)或 CV_FILLED(完全填充轮廓,等同于负数的最大值)。

  • lineType: 线型。常见的选项包括:

    • cv::LINE_8:8-connected 直线(默认)。
    • cv::LINE_AA:抗锯齿线条,适用于高质量输出。
  • hierarchy: (可选)轮廓的层级信息。通常是从 cv::findContours 函数返回的,用于遵循轮廓之间的嵌套关系。如果未提供或为空,所有轮廓被视为无层级关系。

  • maxLevel: (仅当提供了 hierarchy 时有效)绘制轮廓的最大嵌套级别。例如,设置为 0 表示只绘制最外层轮廓;设置为 1 表示绘制最外层轮廓及其直接子轮廓,依此类推。

  • offset: (可选)绘制轮廓时应用的偏移量。如果提供了这个参数,所有轮廓将在原位置基础上加上这个偏移量。

功能与用途

cv::drawContours 函数的主要功能如下:

  • 轮廓绘制:在指定的输入图像上绘制给定的轮廓集合,可以是单个轮廓或多组轮廓。

  • 样式定制:允许用户控制轮廓的颜色、线宽(或填充方式)、线型等视觉属性,以满足不同应用场景的需求。

  • 层级支持:结合轮廓的层级信息(hierarchy),可以按照轮廓间的嵌套关系有选择地绘制部分轮廓,如仅绘制最外层轮廓、特定层级的轮廓或整个轮廓树。

  • 坐标变换:通过提供 offset 参数,可以在绘制轮廓时对轮廓坐标进行平移,适应图像裁剪、视窗调整等场景。

综上所述,cv::drawContours 函数为用户提供了一个灵活的工具,用于在图像上可视化表示轮廓数据,便于观察、分析和展示检测到的形状边界。该函数接受轮廓数据、绘制参数及可选的附加信息作为输入,将轮廓绘制到指定的输入图像上,生成包含轮廓图形的输出图像。

示例

#include <opencv2/opencv.hpp>
#include <iostream>using namespace cv;
using namespace std;int main() {Mat image = imread("image.jpg", IMREAD_GRAYSCALE);if (image.empty()) {cout << "无法读取图像文件!" << endl;return -1;}Mat binary;threshold(image, binary, 128, 255, THRESH_BINARY);vector<vector<Point>> contours;vector<Vec4i> hierarchy;// 查找轮廓findContours(binary, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE);// 绘制轮廓Mat result = Mat::zeros(image.size(), CV_8UC3);drawContours(result, contours, -1, Scalar(0, 255, 0), 2);// 显示结果imshow("Contours", result);waitKey(0);return 0;
}

效果展示

  • RETR_EXTERNAL与RETR_CCOMP的区别
    在这里插入图片描述

设置RETR_CCOMP参数,会返回内部轮廓和内部轮廓,至于上图中thickness=-1的情况下,没有输出填充图,尚未找到缘由。

  • 调整参数,输出想要的格式
    在这里插入图片描述

  • 下图绘制某一图形的内外轮廓:
    在这里插入图片描述

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

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

相关文章

【python】商业数据聚类-回归数据分析可视化(源码+数据)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

ios CI/CD 持续集成 组件化专题四-(手动发布私有库-组件化搭建)

一 、创建私有索引库 1.1 、第一步 首先检查本地是否存在需要的私有索引库 pod repo list 例如&#xff1a;dp_base_ios_spec 在本地不存在该私有索引库 1.2 、第二步 在git下下创建一个新的库&#xff0c;这个库用来保存私有库的podspec文件&#xff0c;取名叫xxxSpec用以…

以更多架构核心专利,推进 SDS 产业创新创造

今天是第 24 个世界知识产权日&#xff0c;今年世界知识产权日活动的主题是&#xff1a;“知识产权和可持续发展目标&#xff1a;立足创新创造&#xff0c;构建共同未来。” 这也正是 XSKY 在软件定义存储领域的目标之一。以“数据常青”为使命的 XSKY&#xff0c;始终立足于软…

【MySQL | 第十篇】重新认识MySQL索引匹配过程

文章目录 10.重新认识MySQL索引匹配过程10.1匹配规则10.2举例&#xff1a;联合索引遇到范围查询&#xff08;>、<、between、like&#xff09;10.2.1例子一&#xff1a;>10.2.2例子二&#xff1a;>10.2.3例子三&#xff1a;between10.2.4例子四&#xff1a;like 10…

Unity SteamVR入门

概述 VR项目现在在当前已经是非常热门的技术&#xff0c;可以给玩家身临其境的感觉&#xff0c;接下来让我们学习这部分的内容吧&#xff01; SteamVR Input SteamVR绑定流程&#xff0c;在Windows窗口的点击SteamVR-input&#xff0c;图1&#xff0c;在这里可以选择你需要绑定…

SQL注入漏洞--报错/union/布尔盲注/时间盲注

之前介绍了数据库的基本操作&#xff0c;今天这篇文章就来实操SQL注入。 阅读本文前可以先看一下基本操作&#xff0c;有助于更换理解本文。。。 https://blog.csdn.net/weixin_60885144/article/details/138356410?spm1001.2014.3001.5502 what SQL---结构化查询语言---S…

探索AIGC技术:创新、挑战与责任

&#x1f3a5; 个人主页&#xff1a;Dikz12&#x1f4d5;格言&#xff1a;那些在暗处执拗生长的花&#xff0c;终有一日会馥郁传香欢迎大家&#x1f44d;点赞✍评论⭐收藏 #如何看待AIGC技术&#xff1f; 目录 AIGC简单介绍 创新 责任 未来展望和挑战 AIGC简单介绍 A…

【Linux系统】守护进程

一.进程组&#xff0c;会话 PGID&#xff1a;进程组id&#xff0c;一条命令启动的所有进程及其子进程属于同一个进程组。一条指令中最先创建的进程就是组长&#xff0c;组id就是组长的PID。./启动的SID&#xff1a;会话id&#xff0c;每次登录Linux&#xff0c;操作系统给登录的…

vue2(4)之scoped解决样式冲突/组件通信/非父子通信/ref和$refs/异步更新/.sync/事件总线/provide和inject

vue2 一、学习目标1.组件的三大组成部分&#xff08;结构/样式/逻辑&#xff09;2.组件通信3.综合案例&#xff1a;小黑记事本&#xff08;组件版&#xff09;4.进阶语法 二、scoped解决样式冲突**1.默认情况**&#xff1a;2.代码演示3.scoped原理4.总结 三、data必须是一个函数…

C语言-调试技巧

目录 一、调试介绍1.1 Debug和Release的介绍1.2 Windows环境调试介绍1.2.1 学会快捷键1.2.2 查看临时变量的值1.2.3 查看内存信息1.2.4 查看调用堆栈1.2.4 查看汇编信息1.2.5 查看寄存器信息 二、编程常见的错误2.1 编译型错误2.2 链接型错误2.3 运行时错误 三、易于调试的代码…

Redis---------实现更改数据业务包括缓存更新,缓存穿透雪崩击穿的处理

三种更新策略 内存淘汰是Redis内存的自动操作&#xff0c;当内存快满了就会触发内存淘汰。超时剔除则是在存储Redis时加上其有限期(expire)&#xff0c;有限期一过就会自动删除掉。而主动更新则是自己编写代码去保持更新&#xff0c;所以接下来研究主动更新策略。 主动更新策略…

配置 Trunk,实现相同VLAN的跨交换机通信

1.实验环境 公司的员工人数已达到 100 人&#xff0c;其网络设备如图所示。现在的网络环境导致广播较多网速慢&#xff0c;并且也不安全。公司希望按照部门划分网络&#xff0c;并且能够保证一定的网络安全性。 其网络规划如下。 PC1和 PC3为财务部&#xff0c;属于VLAN 2&…

npm详解:Node.js包管理器的奥秘

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

Ubuntu系统安装nvfortran详细步骤【笔记】

实践设备&#xff1a;华硕FX-PRO&#xff08;NVIDIA GeForce GTX 960M&#xff09; Ubuntu系统安装NVFORTRAN&#xff08;NVIDIA Fortran Compiler&#xff09;步骤如下&#xff1a; 安装依赖项&#xff1a;在安装NVFORTRAN之前&#xff0c;你需要确保系统已经安装了一些必要…

MyBatis-plus笔记——条件构造器和常用接口

wapper介绍 Wapper&#xff1a;条件构造抽象类 AbstractWapper&#xff1a;用于查询条件封装&#xff0c;生成 sql 的 where 条件 QueryWrapper&#xff1a;查询条件封装UpdateWrapper&#xff1a;Update 条件封装AbstractLambdaWrapper&#xff1a;使用Lambda语法 LambdaQuery…

IDEA启动项目报错:Error running ‘‘: Command line is too long.

1、在workspace.xml 2、 在标签 <component name"PropertiesComponent"> 添加 <property name"dynamic.classpath" value"true" />

天地图路径规划功能实现

目录 1、天地图路径规划2、路径规划3、参数说明4、Demo 1、天地图路径规划 天地图Web服务API为用户提供HTTP/HTTPS接口&#xff0c;即开发者可以通过这些接口使用各类型的地理信息数据服务&#xff0c;可以基于此开发跨平台的地理信息应用。 Web服务API对所有用户开放。使用本…

全栈开发之路——前端篇(3)setup和响应式数据

全栈开发一条龙——前端篇 第一篇&#xff1a;框架确定、ide设置与项目创建 第二篇&#xff1a;介绍项目文件意义、组件结构与导入以及setup的引入。 本文为该系列的第三篇&#xff0c;主要讲述Vue核心的setup语法&#xff0c;同时讲解再使用了setup后如何设置响应式数据。 辅助…

Linux专栏05:Linux基本指令之目录处理指令

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Linux专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ Linux基本指令之目录处理指令 编号&#xff1a;05 文章目录 Linux基…

Linux的基础IO:文件描述符 重定向本质

目录 前言 文件操作的系统调用接口 open函数 close函数 write函数 read函数 注意事项 文件描述符-fd 小补充 重定向 文件描述符的分配原则 系统调用接口-dup2 缓冲区 缓冲区的刷新策略 对于“2”的理解 小补充 前言 在Linux中一切皆文件&#xff0c;打开文件…