Opencv | 边缘检测 轮廓信息

目录

  • 一. 边缘检测
    • 1. 边缘的定义
    • 2. Sobel算子 边缘提取
    • 3. Scharr算子 边缘提取
    • 4. Laplacian算子 边缘提取
    • 5. Canny 边缘检测算法
      • 5.1 计算梯度的强度及方向
      • 5.2 非极大值抑制
      • 5.3 双阈值检测
      • 5.4 抑制孤立弱边缘
  • 二. 轮廓信息
    • 1. 获取轮廓信息
    • 2. 画轮廓

一. 边缘检测

1. 边缘的定义

在这里插入图片描述

	边缘:像素值快速变化的区域,也就是像素值函数一阶导数的极值区域
	边缘信息:像素值明显变化的区域, 具有非常丰富的语义信息,常用于物体识别等领域

2. Sobel算子 边缘提取

	Sobel滤波作用:相当于先高斯去燥,再使用一阶导数获取极值
				  导数对噪声非常敏感
	
	语法
	方法1:
		cv2.Sobel(src, ddepth, dx, dy[, ksize[, scale[, delta[, borderType]]]])
	参数:
		src:表示输入图像,即待处理的原始图像
		ddepth:表示输出图像的深度,当其值为负时(通常取-1),输出图像与输入图像有相同的深度
		dx:表示x方向上的求导阶数,若想计算水平方向的边缘,则设置为1
		dy:表示y方向上的求导阶数,若想计算垂直方向的边缘,则设置为1
		ksize:Sobel核的大小,默认为3,即3x3的矩阵
			   如果该值为-1,则会使用Scharr算子进行运算
		scale:计算导数值时所采用的缩放因子,默认情况下该值是1,即无缩放
		delta:在结果中加入的一个可选的常数项,用于调节输出图像的亮度
		borderType:像素外推法选择项,用于处理图像边缘的像素
	作用:计算图像的一阶导数,通常用于边缘检测
	
	方法2:
		cv.filter2D()函数

在这里插入图片描述
d d x ( f ∗ g ) = f ∗ d d x g \frac{d}{d x}(f * g)=f * \frac{d}{d x} g dxd(fg)=fdxdg

  • SobelX:水平梯度/垂直边缘,提取垂直的边缘信息
    在这里插入图片描述
    经过SobelX提取的边缘信息为:
    在这里插入图片描述

  • SobelY:垂直梯度/水平边缘,提取水平的边缘信息
    在这里插入图片描述
    经过SobelY提取的边缘信息为:
    在这里插入图片描述

3. Scharr算子 边缘提取

	Scharr是Sobel算子的改进版,具有更好的性能和更高的精度

4. Laplacian算子 边缘提取

Δ s r c = ∂ 2 s r c ∂ x 2 + ∂ 2 s r c ∂ y 2 \Delta s r c=\frac{\partial^{2} s r c}{\partial x^{2}}+\frac{\partial^{2} s r c}{\partial y^{2}} Δsrc=x22src+y22src

	cv2.Laplacian(src, ddepth, ksize, scale=1, delta=0, borderType=BORDER_DEFAULT)
	参数:
		src:表示原始输入图像
		ddepth:表示目标图像的深度
		ksize:
			用于计算二阶导数的核(kernel)尺寸大小
				必须是正的奇数
				如果该参数未指定,则默认使用3x3的核
		scale:表示计算Laplacian值的缩放比例因子,该参数是可选的
			   默认情况下,该值为1,表示不进行缩放
		delta:表示加到目标图像上的可选值,默认为0
		borderType:表示像素外推法选择项,用于处理图像边界
	作用:Laplacian滤波器在图像处理中常用于边缘检测和增强
	效果:
		块团检测:周边高于或者低于中心点的区域 
		边缘检测:像素值快速变化的区域

	特点:二阶微分算子作为梯度值
	不同点:与Sobel和Scharr滤波器不同,Laplacian滤波器对图像中的突变(即边缘)更加敏感,因为它使用的是二阶导数

5. Canny 边缘检测算法

Canny边缘检测算法是从不同视觉对象中提取有用的结构信息,是传统计算机视觉中非常广泛应用的一种边缘提取算法

	语法:
		cv2.Canny(image, threshold1, threshold2[, apertureSize[, L2gradient]])
		参数:
			image:表示要进行边缘检测的输入图像
			threshold1:第一个阈值,用于边缘连接,较小的值会导致更多边缘被检测到
			threshold2:第二个阈值,用于检测强边缘,较大的值将导致仅检测到强边缘
			apertureSize:可选参数,表示Sobel算子的孔径大小,默认值为3
			L2gradient:可选参数,表示是否使用L2范数计算梯度幅值,默认值为False
	Canny边缘检测算法通过以下步骤实现:
		使用高斯滤波平滑图像,减少图像中的噪声
		计算图像的梯度幅值和方向
		对梯度幅值应用非最大抑制,以得到细化的边缘
		使用两个阈值(threshold1和threshold2)来确定潜在的边缘
		通过抑制孤立的弱边缘,最终得到边缘检测结果。
	作用:	
		Canny算法能够有效地识别图像中的弱边缘和强边缘,并结合它们的位置关系,给出图像整体的边缘信息
		由于其优越的性能,Canny算法是目前最常用的边缘检测算法之一

5.1 计算梯度的强度及方向

强度: G = G x 2 + G y 2 强度:G=\sqrt{G_{x}^{2}+G_{y}^{2}} 强度:G=Gx2+Gy2
方向: θ = arctan ⁡ ( G y / G x ) 方向:\theta=\arctan \left(G_{y} / G_{x}\right) 方向:θ=arctan(Gy/Gx)

其中,Sobel算子为:
S x = [ − 1 0 1 − 2 0 2 − 1 0 1 ] S y = [ 1 2 1 0 0 0 − 1 − 2 − 1 ] S_{x}=\left[\begin{array}{ccc} -1 & 0 & 1 \\ -2 & 0 & 2 \\ -1 & 0 & 1 \end{array}\right] S_{y}=\left[\begin{array}{ccc} 1 & 2 & 1 \\ 0 & 0 & 0 \\ -1 & -2 & -1 \end{array}\right] Sx= 121000121 Sy= 101202101

因此:
G x = S x ∗ A = [ − 1 0 1 − 2 0 2 − 1 0 1 ] ∗ [ a b c d e f g h i ] = sum ⁡ ( [ − a 0 c − 2 d 0 2 f − g 0 i ] ) G_{x}=S_{x} * A=\left[\begin{array}{ccc} -1 & 0 & 1 \\ -2 & 0 & 2 \\ -1 & 0 & 1 \end{array}\right] *\left[\begin{array}{lll} a & b & c \\ d & e & f \\ g & h & i \end{array}\right]=\operatorname{sum}\left(\left[\begin{array}{ccc} -a & 0 & c \\ -2 d & 0 & 2 f \\ -g & 0 & i \end{array}\right]\right) Gx=SxA= 121000121 adgbehcfi =sum a2dg000c2fi

G y = S y ∗ A = [ 1 2 1 0 0 0 − 1 − 2 − 1 ] ∗ [ a b c d e f g h i ] = sum ⁡ ( [ a 2 b c 0 0 0 − g − 2 h − i ] ) G_{y}=S_{y} * A=\left[\begin{array}{ccc} 1 & 2 & 1 \\ 0 & 0 & 0 \\ -1 & -2 & -1 \end{array}\right] *\left[\begin{array}{lll} a & b & c \\ d & e & f \\ g & h & i \end{array}\right]=\operatorname{sum}\left(\left[\begin{array}{ccc} a & 2 b & c \\ 0 & 0 & 0 \\ -g & -2 h & -i \end{array}\right]\right) Gy=SyA= 101202101 adgbehcfi =sum a0g2b02hc0i

5.2 非极大值抑制

	属于一种边缘稀疏技术
	作用:主要作用就是构建“瘦”边 
	效果:非极大值抑制可以将局部最大值之外的所有梯度值抑制为0
	
	其构建过程:
		将当前像素的梯度强度与沿着正负梯度方向上的两个像素进行比较
			如果当前像素的梯度强度 > 另外两个像素,则该像素点保留为边缘点
			否则该像素点被抑制为0 

5.3 双阈值检测

在进行非极大值抑制后,剩余的像素可以更准确地表示图像中的实际边缘,但是有可能还是存在一些噪音数据形成的边缘像素,所以需要使用弱梯度值来过滤这些非实际的边缘像素,并保留高梯度的实际边缘值

	像素边缘的梯度值 > 高阈值,标记为强边缘像素
	高阈值 > 像素边缘的梯度值 > 低阈值,标记为弱边缘像素
	像素边缘的梯度值 < 低阈值,则会将其抑制

5.4 抑制孤立弱边缘

查看弱边缘像素及其周边的八个邻域像素:

	只要其中有一个为强边缘像素/真实边缘像素,则该弱边缘点被保留为真实边缘/强边缘像素

算法原理:真实的弱边缘像素一定是连接强边缘像素点的

二. 轮廓信息

轮廓信息可以简单的理解为从图像中获取图像曲线的连接点信息,在目标检测、目标识别等业务场景中,具有一定的效果

轮廓信息就是从图像中获取图像边缘信息

1. 获取轮廓信息

	contours, hierarchy = cv.findContours(image, mode, method[, contours[, hierarchy[, offset]]])
	参数:
		image:
			输入的单通道图像矩阵
			通常是经过边缘检测算子处理的二值图像
		contours:
			双重向量
				其中每个元素包含由连续的Point点构成的点的集合,代表一个轮廓
				有多少轮廓,这个向量就有多少元素
			hierarchy:
				包含4个整型的向量,定义了图像中各个轮廓之间的等级关系
			mode:
				定义轮廓的检索模式
					CV_RETR_EXTERNAL:只检测最外围轮廓,内围轮廓被忽略
					CV_RETR_LIST:检测所有轮廓,包括内围和外围轮廓,但检测到的轮廓不建立等级关系,彼此之间独立
					CV_RETR_CCOMP:检测所有轮廓,并建立两个等级的轮廓层次关系;顶层是外部轮廓,底层是内部轮廓
					CV_RETR_TREE:检测所有轮廓,并建立完整的等级树状结构,每个轮廓都有相应的父轮廓或子轮廓
			method:
				定义轮廓的近似方法
					CV_CHAIN_APPROX_NONE:存储所有轮廓点,即不进行任何近似
					CV_CHAIN_APPROX_SIMPLE:仅存储轮廓的拐点信息,即对于一条直线上的点而言,仅仅保留端点信息
					CV_CHAIN_APPROX_TC89_L1:使用Teh-Chin链逼近算法,将轮廓近似为一条折线
					CV_CHAIN_APPROX_TC89_KCOS:使用Teh-Chin链逼近算法,将轮廓近似为一条曲线
			offset:是可选参数,表示轮廓点相对于原始图像的偏移量
	返回值:contours和hierarchy
	操作:
		先对图像进行预处理:转为灰度图像,阈值分割或边缘检测算法来获取二值图像
		随后使用该函数进行检测和提取图像中的轮廓,为后续的图像分析、目标识别或形状匹配等任务提供基础

2. 画轮廓

	cv.drawContours(image, contours, contourIdx, color[, thickness[, lineType[, hierarchy[, maxLevel[, offset]]]]])
	参数:
		image:输入单通道图像矩阵,通常是经过边缘检测算子处理的二值图像
		contours:双重向量
		contourIdx:
			要绘制的轮廓的索引
			如果为负数,则绘制所有轮廓
		color:表示绘制轮廓的颜色
		thickness:
			绘制轮廓的线条粗细
			如果为负数,则填充轮廓内部
		lineType:	表示绘制轮廓的线条类型,如:实线、虚线等
		hierarchy:包含4个整型的向量,定义了图像中各个轮廓之间的等级关系
		maxLevel:
			绘制轮廓的最大层级
				如果为0,则只绘制指定索引的轮廓
				如果大于0,则绘制指定索引及其子轮廓
		offset:可选参数,表示轮廓点相对于原始图像的偏移量
	作用:在图像中直观地显示轮廓信息

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【QT】Ubuntu22.04 配置 QT6.5 LTS

【QT】Ubuntu22.04 配置 QT6.5 LTS 文章目录 【QT】Ubuntu22.04 配置 QT6.5 LTS1.注册QT Group的账号2.安装QT Creator3.启动QT Creator报错from 6.5.0, xcb-cursor0 or libxcb-cursor0 is needed to load the Qt xcb platform plugin.4.运行QT的demoReference 1.注册QT Group的…

mysql buffer pool详解

介绍 缓冲池是InnoDB在访问表和索引数据时缓存的主内存区域。缓冲池允许直接从内存访问频繁使用的数据&#xff0c;这加快了处理速度。在专用服务器上&#xff0c;通常会将多达80%的物理内存分配给缓冲池。 为了提高大容量读操作的效率&#xff0c;缓冲池被划分为可能包含多行…

类与对象(三) 拷贝构造与赋值运算符重载

目录 1.拷贝构造 2.运算符重载&#xff08;日期类举例&#xff09; 1. 2.和 3. > > < < 4.赋值运算符重载 5.- 与- 6. -- 7.日期 - 日期 3.const成员函数 4.<<和>>重载 5.取地址重载 1.拷贝构造 拷贝构造也是一个构造函数。我们前…

Linux:动静态库介绍

动静态库 库的介绍开发环境 & 编译器库存在的意义库的实现库的命名静态库制作和使用总结 动态库的制作和使用动态库的使用方法方法一方法二方法三 库加载问题静态库加载问题动态库的加载问题与位置无关码 C/C静态库下载方式 库的介绍 静态库&#xff1a;程序在编译链接的时…

C++初识--------带你从不同的角度理解引用的巧妙之处

1.对于展开的理解 我们这里的展开包括命名空间的展开和头文件的展开&#xff0c;两者的含义是不一样的&#xff1a; 头文件的展开就是把头文件拷贝到当前的文件里面&#xff1b; 命名空间的展开不是拷贝&#xff0c;而是因为编译器本身默认是到全局里面去找&#xff0c;当我…

一些常见的Windows命令

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言看版本号查找端口启动程序杀死某个端口查看全部端口看ip进入目录就是总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 例如&#x…

Linux——匿名管道

为什么要有进程间通信&#xff1f; 在操作系统中&#xff0c;进程是独立运行的程序&#xff0c;多个进程之间要想互相协作完成任务&#xff0c;就需要进程间通信。 什么是进程间通信&#xff1f; 数据传输&#xff1a;一个进程需要将它的数据发送给另一个进程资源共享&#…

03-JAVA设计模式-解析器模式

解释器模式 什么是解析器模式 在Java中&#xff0c;解释器模式&#xff08;Interpreter Pattern&#xff09;是一种行为设计模式&#xff0c;它给定一个语言&#xff0c;定义它的文法的一种表示&#xff0c;并定义一个解释器&#xff0c;该解释器使用该表示来解释语言中的句子…

六、e2studio VS STM32CubeIDE之代码自动补全

目录 一、概述/目的 二、eclipse c/c自动补全 2.1 修改实现原理 2.2 修改插件cdt.ui的方法 2.2.1 资料来源 2.2.2 修改的主要流程或逻辑 2.2.3 失败的原因 三、呼吁st和Renesas厂家支持自动补全代码 六、e2studio VS STM32CubeIDE之代码自动补全 一、概述/目的 eclipse…

解决:前端bootstrap的fileInput插件

项目场景&#xff1a; 帮朋友做一个后台管理系统遇到文件上传回显异常的问题。 项目是单体架构&#xff0c;没有前后端分离&#xff0c;前端使用的bootstrap3Thymeleaf。上传插件用的是fileInput。 问题描述&#xff1a; 上传没有问题&#xff0c;完成后点击编辑再次进入无…

从本地创建项目到 Gitee 提交的完整教程

1、本地创建一个新项目 2.进入想上传的项目的文件夹&#xff0c;然后右键点击git bash 3.初始化本地环境&#xff0c;把该项目变成可被git管理的仓库 4.添加该项目下的所有文件到暂存区 5.使用如下命令将文件添加到仓库中去 6.在gitee上创建以自己项目名称命名的空项目 7.将本地…

springboot结合elasticJob

先说一说什么是elasticJob。 ElasticJob是一个分布式任务调度的解决方案&#xff0c;它由俩个相互独立的子项目Elastic-job-lite和Elastic- job-cloud组成。 任务调度&#xff1a;是指系统为了自动完成特定任务&#xff0c;在任务的特定时刻去执行任务的过程。 分布式&#xf…

窗函数的选择

不同的窗函数实质上时对矩形窗进行了不同程度的加权得到的不同类型的窗函数。 将模拟角频率转换为了数字角频率 矩形窗旁瓣过大&#xff0c;两个频率的峰值相差较大&#xff0c;因此无法识别&#xff0c;可以使用旁瓣非常小的窗函数来进行分辨&#xff0c;只是想要达到相同的分…

(C++) this_thread 函数介绍

文章目录 &#x1f6a9;前言⭐std::this_thread&#x1f579;️get_id()&#x1f5a5;️Code&#x1f516;get_id介绍&#x1f3f7;️其他介绍 &#x1f579;️sleep_for<>()&#x1f5a5;️Code&#x1f516;sleep_for介绍&#x1f3f7;️其他介绍 &#x1f579;️sleep…

python基础语法--列表

一、列表的概念 列表&#xff08;List&#xff09;是一种有序、可变、允许重复元素的数据结构。列表用于存储一组相关的元素&#xff0c;并且可以根据需要动态地进行增加、删除、修改和访问。以下是列表的主要特点和操作&#xff1a; 有序性&#xff1a; 列表中的元素是按照它…

最新AI创作系统ChatGPT网站源码Midjourney-AI绘画系统,Suno-v3-AI音乐生成大模型。

一、前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图文教程吧。已支持GPT…

【CVPR2024】文本到图像的行人再识别中的噪声对应学习

这篇论文的标题是《Noisy-Correspondence Learning for Text-to-Image Person Re-identification》,作者是来自中国四川大学、英国诺森比亚大学、新加坡A*STAR前沿人工智能研究中心和高性能计算研究所的研究人员。论文主要研究了文本到图像的行人再识别(Text-to-Image Person…

Unity进阶之ScriptableObject

目录 ScriptableObject 概述ScriptableObject数据文件的创建数据文件的使用非持久数据让其真正意义上的持久ScriptableObject的应用配置数据复用数据数据带来的多态行为单例模式化的获取数据 ScriptableObject 概述 ScriptableObject是什么 ScriptableObject是Unity提供的一个…

Windows抛弃历史包袱:可能带来哪些改善?

在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「 Windows的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01;性能提升固然重要&#xff0…

[NSSCTF]-Reverse:[HUBUCTF 2022 新生赛]simple_RE(base64换表)

无壳 查看ida 可以看得出是base64&#xff0c;而且是换表的。 完整exp&#xff1a; import base64 result5Mc58bPHLiAx7J8ocJIlaVUxaJvMcoYMaoPMaOfg15c475tscHfM/8 biaostr.maketrans(qvEJAfHmUYjBacu8Ph5n9Od17FrICL/X0gVtM4Qk6T2z3wNSsyoebilxWKGZpRD,ABCDEFGHIJKLMNOPQR…