openCV实战-系列教程5:边缘检测(Canny边缘检测/高斯滤波器/Sobel算子/非极大值抑制/线性插值法/梯度方向/双阈值检测 )、原理解析、源码解读

news2024/9/25 15:22:49

1、Canny边缘检测流程

Canny是一个科学家在1986年写了一篇论文,所以用自己的名字来命名这个检测算法,Canny边缘检测算法这里写了5步流程,会用到之前《openCV实战-系列教程》的内容。 

  1. 使用高斯滤波器,以平滑图像,滤除噪声。
  2. 计算图像中每个像素点的梯度强度和方向。
  3. 应用非极大值(Non-Maximum Suppression)抑制,以消除边缘检测带来的杂散响应。
  4. 应用双阈值(Double-Threshold)检测来确定真实的和潜在的边缘。
  5. 通过抑制孤立的弱边缘最终完成边缘检测。

滤波:Canny检测算法使用的滤波器是高斯滤波器,通过滤波器可以对图像进行平滑处理。所以第一步需要过滤噪声,当进行检测的时候,肯定需要计算梯度,当遇到噪音点也会发生梯度的变化,所以为了更好的做到边缘检测,第一步需要去噪。

梯度:之前我们计算梯度的时候,只需要计算大小就行了,但是现在需要计算一下方向,所以梯度计算包括强度和方向。

非极大值抑制:计算的梯度大小有不同,比如在一个3*3的卷积核中,有些梯度比较小,相对大的就会保留下来,小的梯度就不会保留,只留下最明显的。 比如在人脸检测中,需要把人脸部分打出一个框的标识,计算的时候会计算出多个框,每个框都有一个概率值,最后只保留概率最大的那个框,而其他的框就会被抑制掉。

双阈值:计算边界的时候,会计算出多个候选值,在候选值中会再进行计算,只保留最接近真实的那个候选值边界。

完成边缘检测:将前面的结果都组合起来,完成边缘检测。

2、高斯滤波器

在前面的内容中已经讲解过,中间点比较大,越边缘的点越小,图中的H对高斯滤波器的滤波核进行归一化处理,然后再将滤波核H框住的区域A对应位置相乘再求和得到一个结果e。

3、梯度方向

 

Canny计算梯度使用的是Sobel算子(前面已经讲过这个内容), Sobel算子中需要分别计算水平和竖直两个方向的Gx和Gy(Gx和Gy的计算如上图),将这个结果融合到一起G计算方法如上图

梯度方向就是θ值,通过Gx和Gy计算得到,计算方法如上图。

4、非极大值抑制

4.1 方法A

如图所示,C点是目标像素点,需要判断C是不是一个极大值点,然后红色方框是它的周围的8个像素,蓝色线是C点的梯度方向,梯度方向和边界方向应该是垂直的关系。

如图所示,g1、g2、g3、g4、c都是一个像素点,而Q、Z是梯度方向与方框的交点,Q和Z不是一个像素是一个亚像素,使用线性插值法计算这个亚像素。 

首先g1、g2、g3、g4的梯度(梯度幅值,上一节讲到的梯度计算)都能够计算出来, Q就是g1和g2之间的,用M(dtmp1)表示Q点梯度(梯度幅值),它的计算方法在上图的公式已经给出,w和(1-w)都是代表的是一个权重,是Q点到g1、g2点的距离比上g1到g2的距离。得到权重乘上g1和g2的梯度就得到了Q点的梯度。

通过比较C、Q、Z的梯度值,如果C比Q、Z都要大,则说明C点是一个极大值,就可以将C点保留下来。

4.2 方法B

由于方法A太复杂了,将它简化成方法B,将一个像素周围的8个像素分解成8个方向。在方法1中如果过了g1和g4就不需要做插值了。方法B就是判断当前的方向和这8个方向那个最近就是哪个方向。然后这个方向上除了目标像素值之外还有两个点,如图所示假如分别是A、B、C,如果目标点A比B、C的梯度都要小那么A点就是极大值点。

5、双阈值检测 

 

maxVal即max value,意思是如果算出来的梯度值比maxVal(假如是100)大,那就是边界。

所以A点是边界,如果红色线下方还有一个D点,那么就舍弃这个点,这个点的梯度值比minVal小。

如果是在minval和maxval之间,就要分开讨论了,比如C点和边界点A连接在了一起,那么C点就可以判断为一个边界点,否则比如B点就不是了

6、边缘检测效果实现

这里的80和150就是minVal和maxVal

img=cv2.imread("lena.jpg",cv2.IMREAD_GRAYSCALE)

v1=cv2.Canny(img,80,150)
v2=cv2.Canny(img,50,100)

res = np.hstack((v1,v2))
cv_show(res,'res')

打印结果:

 所以minVal和maxVal的设定是比较重要的,第5节中如果对minval进行调整,那么提到的D点就有可能判定为边界点,因此会提取出更多的细节。

再导入一张图片,将两个参数设置的更大一些来对比:

img=cv2.imread("car.png",cv2.IMREAD_GRAYSCALE)

v1=cv2.Canny(img,120,250)
v2=cv2.Canny(img,50,100)

res = np.hstack((v1,v2))
cv_show(res,'res')

打印结果:

 

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

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

相关文章

揭开Android系统启动的神秘面纱

当有人问我们android中app启动流程的时候,我们总是会提到zygote。but,zygote又是从何而来?由此问题我想到了android系统的启动流程,zygote肯定是在系统初始化时创建的一个进程。带着这个疑问我去查询了一些android系统启动流程的资…

Linux配置nginx反向代理

在云服务器上部署高并发的服务,使用Nginx作为反向代理是一种常见的做法,可以实现流量分发、负载均衡,同时提升系统的可靠性和性能。 步骤概览: 安装Nginx: 确保服务器已安装Nginx。若未安装,可使用适用于你…

【c语言】文件操作 万字详解

目录 一,为什么使用文件 二,什么是文件 1,程序文件 2,数据文件 3,文件名 三,文件的打开和关闭 1,文件指针 2,文件的打开和关闭 四, 文件的顺序读写 1,顺序…

机器人制作开源方案 | 桌面级机械臂--本体说明+驱动及控制

一、本体说明 1. 机械臂整体描述 该桌面级机械臂为模块化设计,包含主机模块1个、转台模块1个、二级摆动模块1个、可编程示教盒1个、2种末端执行器、高清摄像头,以及适配器、组装工具、备用零件等。可将模块快速组合为一个带被动关节的串联3自由度机械臂…

用Python搭建个让你呼吸顺畅-ChatGPT

目录 ChatGPT使用时可能会遇到 1.请待命,我们正在检查您的浏览器... 2. 访问被拒绝。抱歉,您已被阻止 3. ChatGPT 目前已满负荷运转 4. 此内容可能违反我们的内容政策。 5.出了点问题。 6. 蹦字慢吞吞,卡顿不流畅,不知道的…

对称输出字符串(对称+递归)--夏令营

题目 tips: 1、巧思:类似于将输入的字符串按一个上一个下输出;所以可以用递归栈思考,第一个输入的直接输出,第二个存下来存进栈,如果没有字符串了,就可以输出第二个字符串,如果还有…

docker for window更改到非系统盘的使用记录

1、使用Hyper-v模式的docker安装 2、安装docker for windows后安装目录没办法自己选择,固定在c盘 卸载后通过命令行方式设置软连接方式后重新安装来让其安装到软连接的d盘,解决c盘空间问题 mklink /j "C:\Program Files\Docker" "D:\Pr…

制造执行系统(MES)在家具行业中的应用

制造执行系统(MES)在家具行业中有许多应用,它可以帮助家具制造商提高生产效率、质量控制和整体管理。以下是MES系统在家具行业中的一些应用领域: 1. 生产计划与调度:MES可以帮助家具制造商优化生产计划和调度&#xff…

php thinkphp 抖音支付,订单同步接口分享

1. 抖音支付 需要获取抖音小程序的AppID,AppSecret,需要配置回调地址,Token获取SALT 官方地址:支付,订单同步 以下干货仅针对于有一定开发基础的精英,0基础的止步。 public function DouyinPay($openId,$id,$body 抖音担保支付…

微服务中间件--分布式搜索ES

分布式搜索ES 11.分布式搜索 ESa.介绍ESb.IK分词器c.索引库操作 (类似于MYSQL的Table)d.查看、删除、修改 索引库e.文档操作 (类似MYSQL的数据)1) 添加文档2) 查看文档3) 删除文档4) 修改文档 f.RestClient操作索引库1) 创建索引库2) 删除索引库/判断索引库 g.RestClient操作文…

用户端Web自动化测试_L3

目录: 浏览器复用Cookie 复用pageobject设计模式异常自动截图测试用例流程设计电子商务产品实战 1.浏览器复用 复用浏览器简介 为什么要学习复用浏览器? 自动化测试过程中,存在人为介入场景提高调试UI自动化测试脚本效率 复用已有浏览…

13. Docker实战之安装MySQL

目录 1、前言 2、部署MySQL 2.1、Docker仓库查看镜像 2.2、拉取MySQL镜像 2.3、创建持久化目录 2.4、启动MySQL容器 2.5、查看宿主机上的MySQL目录 2.6、本地MySQL测试 2.7、新建MySQL用户,配置远程访问 2.8、本地Navicat连接测试 3、为什么数据库不适合D…

长胜证券:a股交易时间是几点到几点?

股票商场是一个高速工作的场所,关于新手出资者来说,他们可能不知道A股买卖的时刻是什么时分开始和完毕,这将给他们在买卖过程中带来一些麻烦。本文将从不同的角度来分析A股买卖时刻,帮助读者更好地了解A股买卖时刻的相关规定。 A股…

Talk | 香港中文大学张懿元:由MetaTransformer探索统一的多模态学习

本期为TechBeat人工智能社区第524期线上Talk! 北京时间8月23日(周三)20:00,香港中文大学博士生—张懿元的Talk已准时在TechBeat人工智能社区开播! 他与大家分享的主题是: “探索模态通用感知”,介绍了多模态学习和发展统一的多模态…

espidf vscode 安装出错ERROR_INVALID_PIP

解决链接:https://www.cnblogs.com/xiaohuzaixue/p/17558731.html 注意 不要使用win11的右键打开终端,在文件管理器上方输入cmd打开终端才有用。

数据结构——栈和队列OJ题

栈和队列小提升! 前言一、用队列实现栈队列接口实现(1)栈的接口定义(2)栈的初始化(3)入栈函数的定义(4)出栈函数的定义(5)查找栈顶元素&#xff0…

数据清洗——气温历史数据

import pandas as pd import numpy as np import matplotlib.pyplot as plt from pylab import mpl mpl.rcParams["font.sans-serif"] ["HarmonyOS Sans SC"] %matplotlib inline读取数据 data pd.read_excel("气温历史数据.xlsx") data.head…

【golang】for语句和switch语句

使用携带range子句的for语句时需要注意哪些细节? numbers1 : []int{1, 2, 3, 4, 5, 6} for i : range numbers1 {if i 3 {numbers1[i] | i} } fmt.Println(numbers1)这段代码执行后会打印出什么内容? 答案:[1 2 3 7 5 6] 当for语句被执行…

【面试题系列】(一)

Redis有哪些数据结构?其底层是怎么实现的? Redis 系列(一):深入了解 Redis 数据类型和底层数据结构 字符串(String): 用于存储文本或二进制数据。可以执行字符串的基本操作&#xf…

只需五分钟,了解kafka的环境搭建

〇、前言 在Kafka系列的上一篇文章中,我们介绍了Kafka的体系结构,那么本篇文章呢,我们就着手来把Kafka的运行环境搭建起来。 此处 ,我们采用线上环境普遍使用的ZooKeeper作为管理存储和管理kafka集群元数据,或者辅助…