4.RV1126-OPENCV 图像轮廓识别

article/2025/7/5 5:00:10

一.图像识别API

1.图像识别作用

        它常用于视觉任务、目标检测、图像分割等等。在 OPENCV 中通常使用 Canny
函数、findContours 函数、drawContours 函数
结合在一起去做轮廓的形检测。

2.常用的API 

  • findContours 函数:用于寻找图片的轮廓,并把所有的数据存储在向量里面                    

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

    第一个参数:image 输入的二值图像,这个图像通常是用在边缘检测、阈值处理等等
    第二个参数:contours 输出的轮廓集合,每一个轮廓都是由点组成,通常用vector<vector<Point>>来表示

    第三个参数:hierarchy 输出的轮廓层次结构,这通常表示轮廓之间的父子关系,这个是可选参数,通常用 vector<Vec4i> hierarchy来表示。比方说,第 i 个轮廓,hierarchy[i][0]、hierarchy[i][1]、hierarchy[i][2]、hierarchy[i][3], 依次为第 i 个轮廓[Next、Pervious、First_Child,Parent], 这表示的是相同等级下的下一轮廓、前一轮廓,第一个子轮廓和父轮廓的索引号。若轮廓 i 没有下一个,前一个或者父级轮廓,则层次相应的元素是负数。如下图:

    第四个参数:mode 轮廓检索模式,通常有以下选项,分别是:RETR_EXTERNAL(只检测最外层轮廓)、RETR_LIST(检测所有轮廓,包括内围、外围轮廓,但都是同等级的)、RETR_CCOMP(检测所有轮廓,但是所有的轮廓只建立两个等级关系,一个外层,一个内层(不管内层有多少个,都属于内层))、RETR_TREE(检测所有轮廓并建立轮廓树,这个模式下外围轮廓包含内层轮廓,内层还可以继续嵌套)。

    第 五 个 参 数 : method 轮 廓 近 似 方 法 , 通 常 有 以 下 的 几 种 方 法 , 分 别 是 CHAIN_APPROX_NONE( 存 储 所 有 顶 点 ) 、CHAIN_APPROX_SIMPLE(仅存储轮廓的拐点信息,并把所有轮廓拐点处的点保存到向量里面)、CHAIN_APPROX_TC89_L1(使用TEH_CHAIN 近似算法)。
    第六个参数:offset 轮廓点偏移量,默认(0,0)

    • drawContours 函数:用于绘制图像的轮廓,配合findContours 函数使用,用findContours 函数获取轮廓,用drawContours 函数画轮廓。

             CV_EXPORTS_W void drawContours( InputOutputArray image, InputArrayOfArrays contours,int contourIdx, const Scalar& color,int thickness = 1, int lineType = LINE_8,InputArray hierarchy = noArray(),int maxLevel = INT_MAX, Point offset = Point() );

    第一个参数:image 输出图像,即绘制轮廓后的图像
    第二个参数:contours 轮廓的集合,它是由一系列的点组成
    第三个参数:contourIdx、轮廓索引数组,指定要绘制哪些轮廓
    第四个参数:contourColor,轮廓颜色,使用 Scalar 类型表示
    第五个参数:thickness,轮廓线宽,默认 1
    第六个参数:lineType ,轮廓线类型,默认为 LINE_8

    第七个参数:hierarchy ,轮廓层次结构,用于绘制轮廓的父子关系。默认为 noArray()
    第八个参数:maxLevel ,表示绘制轮廓的最大层级数量。若 maxLevel 为 0,则只绘制指定的轮廓;若 maxLevel 为 1,则绘制轮廓极其所有嵌套轮廓;若 maxLevel 为 2,则绘制轮廓、所有嵌套轮廓、所有嵌套到嵌套的轮廓。
    第九个参数:轮廓点的偏移量,默认为(0,0) 

    • Canny 函数:用于边缘检测计算。效果如下:

             工作原理:就是一系类数学处理方法。高斯滤波(将图像转换为灰度图像,高斯滤波作用是平滑图像,让 Canny 检测的时候准确率更高)、梯度强度和方向的计算(计算图像中每个像素的强度和方向、强度表示像素点的边缘强度、梯度表示的是边缘方向这里的梯度需要用到 sobel 因子)、非极大抑制(经过 NMS 操作后,会除去一些不是边缘的像素点)、双阈值处理(给出一个阈值,若超过这个阈值的边缘则会被保留)、边缘链接(经过双阈值处理过后,强边缘则会留下来,弱边缘则会被抑制,并会把所有的强边缘全部连接起来)。

             工作原理白话文:把3通道图片(也就是彩色图片)转化成双通道图片(也就是灰色图像),然后用高斯滤波去除细小杂物让它更好识别轮廓;梯度强度和方向的计算,就是不同程度扫描轮廓,扫描很多轮廓;非极大抑制,去除边边角角不是边缘的像素点;双阈值处理,就是在之前扫描不同程度轮廓上设置两个阈值(Max,Min),大于Max值被认为是轮廓保留下来,小于Min被认为不是轮廓去除掉,在两值中间的是边缘保留,不是去掉;边缘链接,就是一个完整轮廓。

            CV_EXPORTS_W void Canny( InputArray image, OutputArray edges,double threshold1, double threshold2,int apertureSize = 3, bool L2gradient = false ); 

    第一个参数:image 输入的图像,这个图像一定要单通道灰度图
    第二个参数:edges 输出的边缘图像,这个图像也必须是单通道黑白图
    第三个参数:threshold1 第一个滞后性阈值,低阈值,小于低阈值则认为是弱边缘,就是需要抛弃的边缘。
    第四个参数:threshold2 第二个滞后性阈值,高阈值,大于高阈值被认为强边缘,需要保留的边缘
    第五个参数:apertureSize 指的是 Sobel 算子大小,这个值默认为 3,代表的是 3*3 的矩阵大小。
    第六个参数:L2gradient 是计算图像梯度幅度值的情况,这个值默认为 False;若选择 True,则使用更精确的 L2 范数进行计算

    二. 代码实战扫描物体轮廓

    1.扫描轮廓步骤

            分别是 imread 读取图片(这个图片默认是 3 通道)、利用 cvtColor 把 8VU3 的三通道图片转换成灰度图(8VU1)、调用 Canny 对灰度图像进行边缘检测、调用 findContours 去查找轮廓、循环轮廓数量然后调用 drawContours 进行画框操作。

    2.代码

    #include <opencv2/opencv.hpp>
    #include <opencv2/dnn.hpp>
    #include <opencv2/imgcodecs.hpp>
    #include <opencv2/imgproc.hpp>
    #include <iostream>using namespace cv;
    using namespace std;int main()
    {//读取图片Mat img = imread("zjl.jpg");//彩色图片转化灰度图片Mat imgGray;cvtColor(img, imgGray, COLOR_RGB2GRAY);//灰度图片边缘检测轮廓Mat imgCanny;Canny(imgGray, imgCanny, 25, 75); //Canny对图像进行边缘检测,弱阈值25,强阈值75//查询轮廓vector<vector<Point>> contours; //定义轮廓vector<Vec4i> hierarchy; //定义层次结构findContours(imgCanny, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_NONE); //查询轮廓,RETR_EXTERNAL表示只检测外部轮廓,CHAIN_APPROX_NONE表示存储所有的轮廓点//绘制轮廓Mat drawing = Mat::zeros(imgCanny.size(), CV_8UC3);//创建一个空白图像,用于绘制轮廓for (int i = 0; i < contours.size(); i++)   //遍历所有轮廓{Scalar color = Scalar(255, 255, 0); //随机生成颜色drawContours(drawing, contours, i, color, 1, 8, hierarchy); //对图像轮廓进行画框}//显示图像imwrite("zjl1.jpg", drawing);return 0;
    }

    3.效果


    http://www.hkcw.cn/article/bGLIjUppEo.shtml

    相关文章

    Cursor从入门到精通实战指南(五):一键生成流程图/架构图,开发者必备收藏!

    解锁Cursor&#xff1a;开启高效开发新境界 结合了GPT-4、Claude 3.5等强大的大语言模型&#xff0c;能够通过自然语言交互实现代码生成、原型设计、流程优化等功能。无论是编程新手还是经验丰富的开发者&#xff0c;都能借助Cursor的智能特性&#xff0c;快速完成复杂的编码任…

    postman工具使用

    基本功能操作 常用断言 定义&#xff1a;postman 断言借助 JavaScript - js 语言编写代码&#xff0c;自动判断预期结果与实际结果是否一致。&#xff08; 注意断言 代码写在 Tests 的标签中&#xff09; 断言响应状态码 断言响应体是否包含某个字符串&#xff08;Response bo…

    【Elasticsearch】Elasticsearch 核心技术(一):索引

    Elasticsearch 核心技术&#xff08;一&#xff09;&#xff1a;索引 1.索引的定义2.索引的命名规范3.索引的增、删、改、查3.1 创建索引3.1.1 创建空索引 3.2 删除索引3.3 文档操作3.3.1 添加/更新文档&#xff08;指定ID&#xff09;3.3.2 添加文档&#xff08;自动生成ID&am…

    玩客云 OEC/OECT 笔记(2) 运行RKNN程序

    目录 玩客云 OEC/OECT 笔记(1) 拆机刷入Armbian固件玩客云 OEC/OECT 笔记(2) 运行RKNN程序 RKNN OEC/OEC-Turbo 使用的芯片是 RK3566/RK3568, 这个系列是内建神经网络处理器 NPU 的, 利用 RKNN 可以部署运行 AI 模型利用 NPU 硬件加速模型推理. 要使用 NPU, 首先需要在电脑使…

    【音视频】FFmpeg 硬件(NVDIA)编码H264

    FFmpeg 与x264的关系 ffmpeg软编码是使⽤x264开源项⽬&#xff0c;也就是说ffmpeg软编码H264最终是调⽤了x264开源项⽬&#xff0c;所以我们要先理解ffmpeg和x264的调⽤关系&#xff0c;这⾥我们主要关注x264_init。对于x264的参数都在 ffmpeg\libavcodec \libx264.c x264\co…

    深度学习和神经网络 卷积神经网络CNN

    1.什么是卷积神经网络 一种前馈神经网络&#xff1b;受生物学感受野的机制提出专门处理网格结构数据的深度学习模型 核心特点&#xff1a;通过卷积操作自动提取空间局部特征&#xff08;如纹理、边缘&#xff09;&#xff0c;显著降低参数量 2.CNN的三个结构特征 局部连接&a…

    论文略读:LIMO: Less is More for Reasoning

    202502 arxiv 在数学推理领域&#xff0c;论文提出的LIMO仅用 817 条精心设计的训练样本&#xff0c;借助简单的监督微调&#xff0c;就全面超越了使用十万量级数据训练的主流模型 最近的大模型在预训练阶段已纳入海量数学知识&#xff08;比如Llama 3 仅在数学推理上的训练数…

    web架构3------(nginx的return跳转,gzip压缩,目录浏览,访问控制和location符号优先级)

    一.前言 本期继续来介绍nginx的各项配置&#xff0c;看着内容很多&#xff0c;但是主要还是介绍&#xff0c;内容还是很少的。 二.return和rewrite跳转 在我们配置ssl证书之后&#xff0c;如果把https的s去掉&#xff0c;就相当于去访问80端口了&#xff0c;https默认找的是…

    大楼智能化建设设计方案(Word)

    第一章 智能化设计 4 1.1 项目概况 4 1.2 设计原则 4 1.3 设计依据 6 1.4 项目总体规划 7 1.5 综合布线系统 8 1.5.1 综合布线系统 8 1.5.2 楼宇分机房系统 20 1.5.3 有线电视网 27 1.6 建筑智能化系统 37 1.6.1 周界防范系统 37 1.6.2 电子巡更系统 38 1.6.3…

    Spring AI 之检索增强生成(Retrieval Augmented Generation)

    检索增强生成&#xff08;RAG&#xff09;是一种技术&#xff0c;有助于克服大型语言模型在处理长篇内容、事实准确性和上下文感知方面的局限性。 Spring AI 通过提供模块化架构来支持 RAG&#xff0c;该架构允许自行构建自定义的 RAG 流程&#xff0c;或者使用 Advisor API 提…

    【C++/Linux】TinyWebServer前置知识之IP协议详解

    目录 IPv4地址 分类 IP数据报分片 IP 协议在传输数据报时&#xff0c;将数据报分为若干分片&#xff08;小数据报&#xff09;后进行传输&#xff0c;并在目的系统中进行重组&#xff0c;这一过程称为分片&#xff08;Fragmentation&#xff09;。 IP模块工作流程​编辑 I…

    破局软件开发困境:一套‘一模到底‘的功能模型,如何撬动软件工程全数字化管控?

    软件工程如同一场复杂的交响乐&#xff0c;功能模型是乐谱的主旋律&#xff0c;而需求、设计、开发、测试、运维、用户反馈、Bug、版本、状态等则是丰富的配器和节奏。传统模式下&#xff0c;这些元素常常各自为营&#xff0c;声部混乱&#xff0c;难以奏出和谐的乐章。如何才能…

    RAG入门 - Retriever(1)

    文章目录 环境准备知识库加载1. Retriever - embeddings &#x1f5c2;️1.1 将文档拆分为chunks1.2 词嵌入1.3 构建向量数据库Nearest Neighbor search algorithm &#xff08;最近邻搜索算法&#xff09;Distances &#xff08;距离&#xff09;点积&#xff08;Dot Product&…

    Pyomo中线性规划接口的使用

    之前在 Pyomo介绍-CSDN博客 中以饮食为例介绍过Pyomo的使用&#xff0c;执行以下命令&#xff1a; pyomo solve --solverglpk test_pyomo_linear_programming.py ../test_data/diet.dat 直接执行以上命令&#xff0c;不便之处有以下几点&#xff1a; (1).不能直接解析python文…

    打开一个新的Maven工程要做的事情

    新导入项目变成maven 1、检查环境配置 2.看有没有maven 3.在idea中配置maven 4、让配置文件添加到maven项目中 变成这样基本就成功了 调出service界面 可以同时选中启动多个项目 这里可以同时关闭多个项目

    GNURadio实现MIMO OFDM文件传输

    文章目录 前言一、理论基础二、使用方法1、打开虚拟机2、输入密码3、运行 grc 文件4、运行 三、流图及运行结果1、MIMO_simulation.grc2、MIMO_tx.grc3、MIMO_rx.grc 四、资源自取 前言 使用 GNU Radio Companion 驱动 USRP N320 实现 MIMO OFDM 收发测试。&#xff08;Ubuntu…

    达梦数据库 Windows 系统安装教程

    &#x1f9d1; 博主简介&#xff1a;CSDN博客专家、CSDN平台优质创作者&#xff0c;高级开发工程师&#xff0c;数学专业&#xff0c;10年以上C/C, C#, Java等多种编程语言开发经验&#xff0c;拥有高级工程师证书&#xff1b;擅长C/C、C#等开发语言&#xff0c;熟悉Java常用开…

    【Day43】

    DAY 43 复习日 作业&#xff1a; kaggle找到一个图像数据集&#xff0c;用cnn网络进行训练并且用grad-cam做可视化 进阶&#xff1a;并拆分成多个文件 今天代码见个人 Gitee仓库&#xff1a;LOVE/Python学习库https://gitee.com/love_hub/python-learning-library Github仓库&a…

    贪心算法应用:装箱问题(BFD算法)详解

    贪心算法应用&#xff1a;装箱问题(BFD算法)详解 1. 装箱问题与BFD算法概述 1.1 装箱问题定义 装箱问题(Bin Packing Problem)是组合优化中的经典问题&#xff0c;其定义为&#xff1a; 给定n个物品&#xff0c;每个物品有大小wᵢ (0 < wᵢ ≤ C)无限数量的箱子&#xf…

    mysql(十五)

    目录 子查询 1.准备工作 2--创建表格 3--插入数据 2.where 子查询单列单个数据 格式 查询 3.where 子查询单列多个数据(in) 格式 查询 使用子查询 4.from 多行多数据 格式 查询 子查询 将select的查询的返回结果 当成另外一个selet语句的内容去使用。 子查询放在()里面 注意…