python数字图像处理——边缘检测算子(Laplacian算子、Roberts算子、Prewitt算子和Sobel算子)

article/2025/11/9 3:44:13

1.Laplacian算子

拉普拉斯(Laplacian)算子是n维欧几里德空间中的一个二阶微分算子,常用于图像增强领域和边缘提取。它通过灰度差分计算邻域内的像素,基本流程是:判断图像中心像素灰度值与它周围其他像素的灰度值,如果中心像素的灰度更高,则提升中心像素的灰度;反之降低中心像素的灰度,从而实现图像锐化操作。在算法实现过程中,Laplacian算子通过对邻域中心像素的四方向或八方向求梯度,再将梯度相加起来判断中心像素灰度与邻域内其他像素灰度的关系,最后通过梯度运算的结果对像素灰度进行调整。Laplacian算子分为四邻域和八邻域,四邻域是对邻域中心像素的四方向求梯度,八邻域是对八方向求梯度。

kernel=np.array([[0,1,0],[1,-4,1],[0,1,0]],dtype=int)

在python中使用Laplacian() 函数实现,其函数用法如下:

dst = Laplacian(src, ddepth[, dst[, ksize[, scale[, delta[, borderType]]]]])

1.src 表示输入图像;

2.dst 表示输出的边缘图,其大小和通道数与输入图像相同;

3.ddepth 表示目标图像所需的深度;

4.ksize 表示用于计算二阶导数的滤波器的孔径大小,其值必须是正数和奇数,且默认值为1;

5.scale 表示计算拉普拉斯算子值的可选比例因子。默认值为1;

6.delta 表示将结果存入目标图像之前,添加到结果中的可选增量值,默认值为0;

7.borderType 表示边框模式。

注:在进行Laplacian算子处理之后,还需要调用 convertScaleAbs() 函数计算绝对值,并将图像转换为8位图进行显示。其函数用法如下:

dst = convertScaleAbs(src[, dst[, alpha[, beta]]])

1.src 表示原数组;

2.dst 表示输出数组,深度为8位;

3.alpha 表示比例因子;

4.beta 表示原数组元素按比例缩放后添加的值。

当ksize=1时,Laplacian() 函数采用 33 的孔径 (四邻域模板) 进行变换处理。代码如下所示:

 

2. Roberts算子

Roberts算子又称为交叉微分算法,它是基于交叉差分的梯度算法,通过局部差分计算检测边缘线条。常用来处理具有陡峭的低噪声图像,当图像边缘接近于正45度或负45度时,该算法处理效果更理想。其缺点是对边缘的定位不太准确,提取的边缘线条较粗。

kernelx = np.array([[-1,0],[0,1]], dtype=int)

kernely = np.array([[0,-1],[1,0]], dtype=int)

在Python中,Roberts算子主要通过numpy定义模板,再调用OpenCV的 filter2D() 函数实现边缘提取。该函数主要是利用内核实现对图像的卷积运算。filter2D() 函数用法如下所示:

dst = filter2D(src, ddepth, kernel[, dst[, anchor[, delta[, borderType]]]])

1.src 表示输入图像;

2.dst 表示输出的边缘图,其大小和通道数与输入图像相同;

3.ddepth 表示目标图像所需的深度;

4.kernel 表示卷积核,一个单通道浮点型矩阵;

5.anchor 表示内核的基准点,其默认值为 (-1,-1),位于中心位置;

6.delta 表示在储存目标图像前可选的添加到像素的值,默认值为0;

7.borderType 表示边框模式。

代码如下所示:

3. Prewitt算子

Prewitt算子是一种图像边缘检测的微分算子,其原理是利用特定区域内像素灰度值产生的差分实现边缘检测。由于Prewitt算子采用3x3模板对区域内的像素值进行计算,而Robert算子的模板为2x2,故Prewitt算子的边缘检测结果在水平方向和垂直方向均比Robert算子更加明显。Prewitt算子适合用来识别噪声较多、灰度渐变的图像。

kernelx = np.array([[1, 1, 1], [0, 0, 0], [-1, -1, -1]], dtype=int)

kernely = np.array([[-1, 0, 1], [-1, 0, 1], [-1, 0, 1]], dtype=int)

在Python中,Prewitt算子的实现过程与Roberts算子比较相似。通过Numpy定义模板,再调用OpenCV的filter2D() 函数实现对图像的卷积运算,最终通过 convertScaleAbs() 和 addWeighted() 函数实现边缘提取。

代码如下所示:

 4.Sobel算子

Sobel算子是一种用于边缘检测的离散微分算子,它结合了高斯平滑和微分求导。该算子用于计算图像明暗程度近似值,根据图像边缘旁边明暗程度把该区域内超过某个数的特定点记为边缘。Sobel算子在Prewitt算子的基础上增加了权重的概念,认为相邻点的距离远近对当前像素点的影响是不同的,距离越近的像素点对应当前像素的影响越大,从而实现图像锐化并突出边缘轮廓。Sobel算子的边缘定位更准确,常用于噪声较多、灰度渐变的图像。

kernelx = np.array([[1, 0, -1], [2, 0, -2], [1, 0, -1]], dtype=int)

kernely = np.array([[-1, -2, -1], [0, 0, 0], [1,2, 1]], dtype=int)

Sobel算子根据像素点上下、左右邻点灰度加权差,在边缘处达到极值这一现象检测边缘。对噪声具有平滑作用,提供较为精确的边缘方向信息。因为Sobel算子结合了高斯平滑和微分求导(分化),因此结果会具有更多的抗噪性,当对精度要求不是很高时,Sobel算子是一种较为常用的边缘检测方法。

在python中使用Sobel()函数实现,其函数用法如下:

dst = Sobel(src, ddepth, dx, dy[, dst[, ksize[, scale[, delta[, borderType]]]]])

1.src 表示输入图像;

2.dst 表示输出的边缘图,其大小和通道数与输入图像相同;

3.ddepth 表示目标图像所需的深度,针对不同的输入图像,输出目标图像有不同的深度;

4.dx 表示 x方向上的差分阶数,取值1或 0;

5.dy 表示 y方向上的差分阶数,取值1或0;

6.ksize 表示Sobel算子的大小,其值必须是正数和奇数;

7.scale 表示缩放导数的比例常数,默认情况下没有伸缩系数;

8.delta 表示将结果存入目标图像之前,添加到结果中的可选增量值;

9.borderType 表示边框模式。

注:在进行Sobel算子处理之后,还需要调用 convertScaleAbs() 函数计算绝对值,并将图像转换为8位图进行显示。
代码如下:

 5.平滑滤波器

除了以上4种锐化滤波算子,在这里还简单提一下平滑滤波器。主要是高斯滤波器和中值滤波器。代码如下所示:

6.总结

Laplacian算子对噪声比较敏感,由于其算法可能会出现双像素边界,常用来判断边缘像素位于图像的明区或暗区,很少用于边缘检测;

Robert算子对陡峭的低噪声图像效果较好,尤其是边缘正负45度较多的图像,但定位准确率较差;

Prewitt算子对灰度渐变的图像边缘提取效果较好,而没有考虑相邻点的距离远近对当前像素点的影响;

Sobel算子考虑了综合因素,对噪声较多的图像处理效果更好。

边缘检测算法主要是基于图像强度的一阶导数二阶导数,但导数通常对噪声很敏感,因此需要采用滤波器来过滤噪声,并调用图像增强或阈值化算法进行处理,最后再进行边缘检测。例如:可以采用高斯滤波去噪和阈值化处理之后,再进行边缘检测 。


http://chatgpt.dhexx.cn/article/5w6lDP2M.shtml

相关文章

Prewitt算子边缘检测原理及实现

写在前面 Prewitt算子同样也是一种一阶微分算子,利用像素点上下左右邻点灰度差,在边缘处达到极值检测边缘,对噪声具有平滑的作用。 原理 其原理是在图像空间利用两个方向模板与图像进行邻域卷积来完成的,这两个方向模板一个检测…

Prewitt和Sobel算子

在3*3模板中: 我如下定义水平、垂直和两对角线方向的梯度: 该定义下的算子称之为Prewitt算子: Sobel算子是在Prewitt算子的基础上改进的,在中心系数上使用一个权值2,相比较Prewitt算子,Sobel模板能够较好…

Prewitt边缘检测算子

Prewitt算子也是一种一阶微分算子,用于边缘检测。与Robert使用22的模板不同,Prewitt算子使用的是33的模板,利用像素点上下、左右邻点的灰度差来检测边缘,故其边缘检测结果在水平方向和垂直方向均比Robert算子更加明显。 其数学表…

图像边缘检测之Prewitt算子

Prewitt 算子 1. 原理 Prewitt算子是一种图像边缘检测的微分算子,其原理是利用特定区域内像素灰度值产生的差分实现边缘检测。由于Prewitt算子采用 3x3 模板对区域内的像素值进行计算,而Robert算子的模板为 2x2,故Prewitt算子的边缘检测结果…

华为--配置本地环回接口地址

该实验紧接上一节实验 网络拓扑图如下 AR1环回接口配置 AR2环回接口配置 AR3环回接口配置 配置AR1回环接口路由 配置AR2回环接口路由 配置AR3回环接口路由 在AR1上测试回环接口的连通性 在AR2上测试回环接口的连通性 在AR3上测试回环接口的连通性 测试成功 转载于:https://my.o…

【LINUX】ifconfig只有本地环回地址问题的解决方法

问题描述: ifconfig只有lo,没有看到ens33 ifconfig -a看到了ens33,但是没有地址 解决方法: (1)stop network-manager sudo service network-manager stop (2)删除旧有的网络配置…

怎么判断一个ipv4地址是 私有地址,环回地址,实验地址,TEST-NET地址,本地链路地址?

问题的提出: 理论讲解(黄色的为上题的答案): IP地址分为五类: A类保留给政府机构,B类分配给中等规模的公司,C类分配给任何需要的人,D类用于组播,E类用于实验,各类可容纳…

回环地址 127.0.0.1

控制台输入ping 127.0.0.1。 $ ping 127.0.0.1 PING 127.0.0.1 (127.0.0.1): 56 data bytes 64 bytes from 127.0.0.1: icmp_seq0 ttl64 time0.080 ms 64 bytes from 127.0.0.1: icmp_seq1 ttl64 time0.093 ms 64 bytes from 127.0.0.1: icmp_seq2 ttl64 time0.074 ms 64 byte…

环回接口 环回地址 环回路由

网络协议的数据链路层的一些重点我们来讲解一下。这此我们主要讲解的是环回接口的问题。环回接口(loopback):路由器上的一个逻辑、虚拟接口.路由器默认没有任何环回接口.此接口允许运行在同一台主机上的客户程序和服务器程序通过TCP/IP进行通信.一般系统…

什么是环回接口(Loopback Interface、环回地址)

2.7 环回接口 大多数的产品都支持环回接口(Loopback Interface),以允许运行在同一台主机上的客户程序和服务器程序通过TCP/IP进行通信。 A类网络号 127就是为环回接口预留的。根据惯例,大多数系统把 IP地址127.0.0.1分配给这个接…

特殊IP地址——环回地址

环回地址(Loopback Address)127.0.0.1---127.255.255.254 是一种特殊的 IP 地址,它允许计算机的软件组件在本地主机上进行网络通信,也称作本地回环地址。 在计算机网络中,环回地址是一个虚拟地址,它不属于任…

“谁告诉你环回地址就是127.0.0.1?” “老师就是这么说的。”

「作者主页」:士别三日wyx 「作者简介」:CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「专栏简介」:此文章已录入专栏《计算机网络零基础快速入门》 环回地址是本地的「虚拟接口」,默认不会宕掉。 我们经…

带头结点单链表、不带头结点单链表(头指针单链表)

1、头结点和头指针的区别 1.1区别: 头指针表明了链表的结点,可以唯一确定一个单链表。 头指针指向链表的第一个结点,其记录第一个存储数据的结点的地址。 头结点是点链表的第一个结点,若单链表有头结点,则头指针指向头…

不带头结点的单链表------C语言实现

1 /****************************************************/ 3 File name:no_head_link.c4 Author:SimonKly Version:0.1 Date: 2017.5.205 Description:不带头节点的单链表6 Funcion List: 7 ***************************************…

单链表的头结点的作用

问题:在单链表中使用“头结点”,这个哑结点始终是链表的第一个元素,这个技巧的利与弊? 链表中第一个结点的存储位置叫做头指针,那么整个链表的存取就必须从头指针开始进行了。之后的每一个结点,其实就是上…

【数据结构】单链表之带头结点的单链表

一、单链表相关知识点介绍: 1. 结点:结点就是单链表中研究的数据元素,结点中存储数据的部分称为数据域,存储直接后继地址的部分称为指针域。 2. 头结点:引入头结点的目的是,将链表首元结点的插入和删除操作…

【链表】带头节点和不带头节点单链表的区别

目录 🍔当链表的结点只包含一个指针域时,叫做单链表 🍔不论带不带头节点,所有的链表都要有个头指针! 🍟带头结点的链表的头指针指向的是头结点,头结点的指针域指向首元结点 🍟不带…

带头结点的单链表的操作(C语言)

初始化 先了解头结点 头结点是一个特殊的结点,它的数据域不存储信息,通常情况下,头指针指向的结点为头结点,由于头结点不存储信息,所以不是数据结构中的实际结点,第一个实际结点其实是head->next指示的…

单链表(不带头结点)

单链表不带头结点结构体设计: //不带头结点的结构体设计: typedef int ELEM_TYPE;//有效数据节点结构体设计 typedef struct Node {ELEM_TYPE data;//数据域 (1.头结点:不保存任何数据 2.有效数据节点:保存有效值…

数据结构之不带头结点的单链表

我们都知道不管是单链表、双向链表还是循环链表,都带有头结点,这个头结点相当于一个起始的位置。我们在设计带头结点的单链表的时候,我们会在主函数中设计一个头结点,并把它的指针域置为空,这样我们就可以进行增删查改…