python+OpenCv笔记(十六):边缘检测原理(Sobel算子原理、Laplacian算子原理、Canny边缘检测原理)

本文主要是介绍python+OpenCv笔记(十六):边缘检测原理(Sobel算子原理、Laplacian算子原理、Canny边缘检测原理),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

一、边缘检测原理

二、Sobel检测算子原理

三、Laplacian算子原理

四、Canny边缘检测

1.噪声去除(高斯滤波)

2.计算图像的梯度与梯度方向

3.非极大值抑制NMS

4.双阈值筛选边界     

五、边缘检测示例及代码编写(跳转)


一、边缘检测原理

目的:

        边缘检测是图像处理和计算机视觉中的基本问题,边缘检测的目的是标识数字图像中亮度变化明显的点。

表现形式:

        图像属性中的显著变化通常反映了属性的重要事件和变化。边缘的表现形式如下图所示:

        图像边缘检测大幅度地减少了数据量,并且剔除了可以认为不相关的信息,保留了图像重要的结构属性。

分类:

        有许多方法用于边缘检测,他们的绝大部分可以划分为两类:基于搜索和基于零穿越。

        基于搜索∶通过寻找图像一阶导数中的最大值来检测边界,然后利用计算结果估计边缘的局部方向,通常采用梯度的方向,并利用此方向找到局部梯度模的最大值,代表算法是Sobel算子和Scharr算子。

(如若求图一中的边缘,这对图一曲线进行求导,得到图二的求导后曲线,图二中导数最大值的地方即为边界。)

         基于零穿越:通过寻找图像二阶导数零穿越来寻找边界,代表算法是Laplacian算子。

二、Sobel检测算子原理

本质:

Sobel算子是图像检测的重要算子之一,其本质是梯度运算。

那什么情况下会产生梯度呢?

例如,对于一张二维图像,

 当我们将卷积核放在图像中时,有三种位置关系,如图:

当卷积核放在纯黑或者纯白的图像上时,是没有梯度产生的,只有放在黑白交界处才会产生梯度,比如白色的灰度值为255,黑色的灰度值为0,那么从白色到黑色的梯度即为0-255=-255,当梯度值的大小超过一个阈值后,我们就认为此处为边缘,sobel算子的算法与其类似。(此处为理解,sobel算子算法相对更加复杂)。

原理:

对于不连续的函数,一阶导数可以写做

{f}'(x)=f(x)-f(x-1)

        或

{f}'(x)=f(x+1)-f(x)

        所以有

{f}'(x)=\frac{f(x+1)-f(x-1)}{2}

假设要处理的图像为 I ,在两个方向求导:

  1. 水平方向:将图像 I 与奇数大小的模板进行卷积,结果为\large _G{}_x,比如,模板大小为3时,有

    \large _G{}_x=\begin{bmatrix} -1 & 0 &+1 \\ -2& 0 &+2 \\ -1& 0 &+1 \end{bmatrix}*I
     
  2.   垂直方向:将图像 I 与奇数大小的模板进行卷积,结果为\large _G{}_y,比如,模板大小为3时,有

    \large _G{}_y=\begin{bmatrix} -1 & -2 &-1 \\ 0& 0 &0 \\ +1& +2 &+1 \end{bmatrix}*I

 那么在图像的每一点处,结合以上两个结果可以求出:

\large G=\sqrt{​{G{_x^{2}}}^{}+{G{_y^{2}}}^{}}

可以简化为:

\large \left | G \right |=\left | G{_x} \right |+\left | G{_y} \right |

统计极大值的位置,就是图像的边缘。

具体步骤:

1.

        例如,原图像为5*6的矩阵

         我们拿固定的3*3的sobel算子卷积核与原图像矩阵进行运算(5*5同理,但必须为奇数)

 2.

        将卷积核在原始图像上进行遍历
        第一次为:

         第二次为:

         最后一次为:

         遍历完毕之后,我们看卷积核的核心,它在原图像矩阵上的覆盖范围为:

        

         可以看出,在原图像中,橙色区域都可以经过与卷积核运算而得到相应的梯度值,而周围的白色区域则不能计算出梯度值,在OpenCv中目前不知道是如何处理的,但在深度学习中是这样处理的:我们将原图像的周围再扩展一圈,并填充值为0,如图:

         这时,我们再与卷积核运算,就可以将原图像的全部区域都计算出梯度值,如图:

 3.

        那么在每一次的遍历之中,sobel算子算法是如何求得梯度值的呢?
        首先,对于水平方向的梯度,根据上面的计算公式有:

         P5点x方向的梯度值为:

P5{_x}=(P3-P1)+2(P6-P4)+(P9-P7)

        在这儿,我们可以理解一下为什么卷积核会有1和2这两个值,1和2代表的是权值,因为对于中心点P5来说,离得越近,对其影响越大,反之越小,所以P4、P6赋予权值为2,其余点赋权值为1。

        那么,我们根据梯度计算式可以看出, P5{_x}是由右边一列减去左边一列(相应列乘以相应的权值)得出的,当左右两列差别特别大的时候,目标点的值会很大,说明该点为边界点。

同理有:

 P5{_y}=(P7-P1)+2(P8-P2)+(P9-P3)

4.

        如果目标像素点求得的值小于0或者大于255怎么办呢?

        因为原图像的灰度值是8位无符号数,即0-255。OpenCv默认的是截断操作,即小于0按0算,大于255按255算,这样显然是不合理的,比如-240是不能简单看做0来算的。

        在python-OpenCv中,我们可以使用16位有符号的数据类型(cv2.CV_16S),处理完图像后,再使用cv2.convertScaleAbs()函数将其转回原来的uint8格式。

        最终的处理结果是,对于小于0的数,取绝对值,对于大于255的数,取255。

 5.

        总梯度:

\bg_white \fn_cm \large G=\sqrt{​{G{_x^{2}}}^{}+{G{_y^{2}}}^{}}

        简化梯度:

\bg_white \fn_cm \large \left | G \right |=\left | G{_x} \right |+\left | G{_y} \right |

参考:
https://www.bilibili.com/video/BV11341127pe?from=search&seid=11602454197720109774&spm_id_from=333.337.0.0https://www.bilibili.com/video/BV11341127pe?from=search&seid=11602454197720109774&spm_id_from=333.337.0.0

三、Laplacian算子原理

原理:

        Laplacian是利用二阶导数来检测边缘,因为图像是二维的,我们需要在两个方向上求导,如下式所示:

\large \Delta src=\frac{ \partial ^{2}src} {\partial x^{2}}+\frac{ \partial ^{2}src} {\partial y^{2}}

在图像中,将该方程表示为离散的形式,

        一维情况:

        \large \bg_white \fn_phv \frac{ \partial ^{2}f} {\partial x^{2}} ={f}''(x)={f}'(x+1)-{f}'(x)

\large = f(x+1)-f(x)-(f(x)-f(x-1))

\large =f(x+1)+f(x-1)-2f(x)

\bg_white \fn_phv \frac{ \partial ^{2}f} {\partial y^{2}} =f(y+1)+f(y-1)-2f(y)

        二维情况:

\small \bigtriangledown ^{2}f(x,y)=[f(x+1,y)+f(x-1,y)+f(x,y+1),+f(x,y-1)]-4f(x,y)

        所以由方程可以得出,laplacian算子使用的卷积核为:

\large kernel=\begin{bmatrix} 0 &1 &0 \\ 1& -4& 1\\ 0& 1 & 0 \end{bmatrix}

具体步骤:

(具体步骤与Sobel算子基本相似,可参考上文的Sobel算子原理步骤)

        这里给出卷积核与图像的运算过程:

        例如,分别有卷积核与原图像矩阵:

        则P5点的梯度值为:

\large P5{_n}_e_w=(P2+P4+P6+P8)-4*P5

四、Canny边缘检测

Canny边缘检测主要由四步组成:

  1. 噪声去除(高斯滤波)
  2. 计算图像的梯度与梯度方向
  3. 非极大值抑制
  4. 双阈值筛选边界
     

1.噪声去除(高斯滤波)

        由于边缘检测容易受到噪声的影响,所以首先使用5*5高斯滤波器去除噪声。
        高斯滤波原理详见文章:
python+OpenCv笔记(十):高斯滤波https://blog.csdn.net/qq_45832961/article/details/122351534

2.计算图像的梯度与梯度方向

        对高斯滤波平滑后的图像使用Sobel算子计算水平和竖直方向的一阶导数(\bg_white \large G{_x}\small \bg_white \large G{_y}),根据得到的\bg_white \large G{_x}\small \bg_white \large G{_y}找到边界的梯度和方向,公式如下:

\bg_white \fn_cm \large G=\sqrt{​{G{_x^{2}}}^{}+{G{_y^{2}}}^{}}

\bg_white \fn_cm \LARGE \theta =arctan(\frac{G{y}}{G{x}})

        Sobel算子原理详见本文的第二篇:Sobel检测算子原理

        如果某个像素点是边缘,则其梯度方向总与边缘垂直,。

        梯度方向被分为四类:垂直、水平和两个对角线方向。

3.非极大值抑制NMS

        在获得梯度的大小和方向之后,对整幅图像进行扫描,去除那些非边界上的点。
        即对每一个像素进行检查,看这个点的梯度在周围具有相同梯度方向的点中是不是最大的
        如图:

         A点位于图像的边缘,在其梯度变化方向,选择像素点B和C,用来检验A点的梯度是否为极大值,若为极大值,则进行保留,否则A点被抑制,最终的结果是具有“细边”的二进制图像。

        (即我们第二步求得的边界可能是ABC,边缘较粗,这时如果A的梯度值均大于B、C,我们进行非极大值抑制后就只剩下了A,从而达到了边缘细化的效果。)

        当然,梯度方向被分为四类:垂直、水平和两个对角线方向,我们将其梯度方向近似为以下值中的一个(0,45,90,135,180,225,270,315),例如30度近似为45度。

         例如,当一个像素点的梯度方向为45度时,我们就在45度与225度(正反方向)两个方向上进行比较,从而决定保留还是抑制。

4.双阈值筛选边界     

        现在要确定真正的边界。我们设置两个阈值: 阈值下界(minVal)和 阈值上界(maxVal)。当图像的灰度梯度高于maxVal时被认为是真的边界(强边界),低于minVal的边界必然不是边界,会被抛弃。如果介于两者之间的话,我们称其为弱边界,和强边界相连的弱边界认为是边界,其他的弱边界则被抑制。如下图:

五、边缘检测示例及代码编写(跳转)

  1. Sobel算子
    python+OpenCv笔记(十三):边缘检测——Sobel检测算子https://blog.csdn.net/qq_45832961/article/details/122396761
  2. Laplacian算子
    python+OpenCv笔记(十四):边缘检测——laplacian算子https://blog.csdn.net/qq_45832961/article/details/122429117
  3. Canny边缘检测
    python+OpenCv笔记(十五):边缘检测——Canny边缘检测https://blog.csdn.net/qq_45832961/article/details/122441575

这篇关于python+OpenCv笔记(十六):边缘检测原理(Sobel算子原理、Laplacian算子原理、Canny边缘检测原理)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/180250

相关文章

使用Python实现IP地址和端口状态检测与监控

《使用Python实现IP地址和端口状态检测与监控》在网络运维和服务器管理中,IP地址和端口的可用性监控是保障业务连续性的基础需求,本文将带你用Python从零打造一个高可用IP监控系统,感兴趣的小伙... 目录概述:为什么需要IP监控系统使用步骤说明1. 环境准备2. 系统部署3. 核心功能配置系统效果展

基于Python打造一个智能单词管理神器

《基于Python打造一个智能单词管理神器》这篇文章主要为大家详细介绍了如何使用Python打造一个智能单词管理神器,从查询到导出的一站式解决,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 项目概述:为什么需要这个工具2. 环境搭建与快速入门2.1 环境要求2.2 首次运行配置3. 核心功能使用指

Python实现微信自动锁定工具

《Python实现微信自动锁定工具》在数字化办公时代,微信已成为职场沟通的重要工具,但临时离开时忘记锁屏可能导致敏感信息泄露,下面我们就来看看如何使用Python打造一个微信自动锁定工具吧... 目录引言:当微信隐私遇到自动化守护效果展示核心功能全景图技术亮点深度解析1. 无操作检测引擎2. 微信路径智能获

redis中使用lua脚本的原理与基本使用详解

《redis中使用lua脚本的原理与基本使用详解》在Redis中使用Lua脚本可以实现原子性操作、减少网络开销以及提高执行效率,下面小编就来和大家详细介绍一下在redis中使用lua脚本的原理... 目录Redis 执行 Lua 脚本的原理基本使用方法使用EVAL命令执行 Lua 脚本使用EVALSHA命令

Python中pywin32 常用窗口操作的实现

《Python中pywin32常用窗口操作的实现》本文主要介绍了Python中pywin32常用窗口操作的实现,pywin32主要的作用是供Python开发者快速调用WindowsAPI的一个... 目录获取窗口句柄获取最前端窗口句柄获取指定坐标处的窗口根据窗口的完整标题匹配获取句柄根据窗口的类别匹配获取句

利用Python打造一个Excel记账模板

《利用Python打造一个Excel记账模板》这篇文章主要为大家详细介绍了如何使用Python打造一个超实用的Excel记账模板,可以帮助大家高效管理财务,迈向财富自由之路,感兴趣的小伙伴快跟随小编一... 目录设置预算百分比超支标红预警记账模板功能介绍基础记账预算管理可视化分析摸鱼时间理财法碎片时间利用财

Python中的Walrus运算符分析示例详解

《Python中的Walrus运算符分析示例详解》Python中的Walrus运算符(:=)是Python3.8引入的一个新特性,允许在表达式中同时赋值和返回值,它的核心作用是减少重复计算,提升代码简... 目录1. 在循环中避免重复计算2. 在条件判断中同时赋值变量3. 在列表推导式或字典推导式中简化逻辑

python处理带有时区的日期和时间数据

《python处理带有时区的日期和时间数据》这篇文章主要为大家详细介绍了如何在Python中使用pytz库处理时区信息,包括获取当前UTC时间,转换为特定时区等,有需要的小伙伴可以参考一下... 目录时区基本信息python datetime使用timezonepandas处理时区数据知识延展时区基本信息

Python位移操作和位运算的实现示例

《Python位移操作和位运算的实现示例》本文主要介绍了Python位移操作和位运算的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 位移操作1.1 左移操作 (<<)1.2 右移操作 (>>)注意事项:2. 位运算2.1

使用Python和Pyecharts创建交互式地图

《使用Python和Pyecharts创建交互式地图》在数据可视化领域,创建交互式地图是一种强大的方式,可以使受众能够以引人入胜且信息丰富的方式探索地理数据,下面我们看看如何使用Python和Pyec... 目录简介Pyecharts 简介创建上海地图代码说明运行结果总结简介在数据可视化领域,创建交互式地