精华内容
下载资源
问答
  • 目录 1 边缘检测的基本原理 2 边缘检测算子分类 ...5 Prewitt 算子 5.1 基本原理 5.2 代码示例 6 Sobel 算子 6.1 基本原理 6.2 代码示例 7 Laplacian 算子 7.1 基本原理 7.2 代码示例 8 小结 8...

    目录

    1 边缘检测的基本原理

    2 边缘检测算子分类

    3 梯度

    3.1 图像梯度

    3.2 梯度算子

    4 Roberts 算子

    4.1 基本原理

    4.2 代码示例

    5 Prewitt 算子

    5.1 基本原理

    5.2 代码示例

    6 Sobel 算子

    6.1 基本原理

    6.2 代码示例

    7 Laplacian 算子

    7.1 基本原理

    7.2 代码示例

    8 小结

    8.1 各类算子实验比较

    8.2 各类算子的优缺点

    参考资料


     

    1 边缘检测的基本原理

    图像边缘是图像最基本的特征,所谓边缘(Edge) 是指图像局部特性的不连续性。灰度或结构等信息的突变处称之为边缘。例如,灰度级的突变、颜色的突变,、纹理结构的突变等。边缘是一个区域的结束,也是另一个区域的开始,利用该特征可以分割图像。

    如图1所示,当我们看到一个有边缘的物体时,首先感受到的就是边缘

    图1 灰度级跃变的边缘模型

    图1(a)是一个理想的边缘所具备的特性。每个灰度级跃变到一个垂直的台阶上。而实际上,在图像采集系统的性能、采样率和获取图像的照明条件等因素的影响,得到的边缘往往是模糊的,边缘被模拟成具有“斜坡面”的剖面,如图1(b)所示,在这个模型中,模糊的边缘变得“宽”了,而清晰的边缘变得“窄”了。

    图像的边缘有方向和幅度两种属性。边缘通常可以通过一阶导数二阶导数检测得到。一阶导数是以最大值作为对应的边缘的位置,而二阶导数则以过零点作为对应边缘的位置。


     

    2 边缘检测算子分类

    (1)一阶导数的边缘算子

    通过模板作为核与图像的每个像素点做卷积和运算,然后选取合适的阈值来提取图像的边缘。常见的有Roberts算子、Sobel算子和Prewitt算子。

     

    (2)二阶导数的边缘算子

    依据于二阶导数过零点,常见的有Laplacian 算子,此类算子对噪声敏感。

     

    (3)其他边缘算子

    前面两类均是通过微分算子来检测图像边缘,还有一种就是Canny算子,其是在满足一定约束条件下推导出来的边缘检测最优化算子。


     

    3 梯度

    3.1 图像梯度

    为了达到寻找边缘的目的,检测灰度变化可用一阶导数二阶导数来完成。下面将讨论一阶导数

    为了在一幅图像f 的(x,y)位置处寻找边缘的强度和方向,所以选择的工具就是梯度,梯度用\nabla f来表示,并用向量来定义,定义如下所示:

                                                                                 \nabla f\equiv \text{grad}(f)\equiv \left[ \begin{matrix} {​{g}_{x}} \\ {​{g}_{y}} \\ \end{matrix} \right]\equiv \left[ \begin{matrix} \frac{\partial f}{\partial x} \\ {} \\ \frac{\partial f}{\partial y} \\ \end{matrix} \right]

     

    其中,梯度\nabla f 为一个向量,它表示f 在位置(x,y) 处的最大变化率的方向。

    梯度\nabla f 的大小用M(x,y) 表示,则:

                                                                              M(x,y)=mag(\nabla f)=\sqrt{g_{x}^{2}+g_{y}^{2}}

    其中,M(x,y) 表示梯度向量方向变化率的值。

     

    数学梯度的简单推导

    对于以为函数f(x) 在点 x 处的导数的近似:将函数f(x+\Delta x) 展开为 x 的泰勒级数,令\Delta x=1,且只保该级数的线性项,则函数f(x) 的梯度\nabla f 计算为:

                                                                          \nabla f=\frac{\partial f}{\partial x}={​{f}^{'}}(x)=f(x+1)-f(x)

     

    3.2 梯度算子

    由上面的数学推导可知,要得到一幅图像的梯度,则要求在图像的每个像素点位置处计算偏导数。我们处理的是数字量,因此要求关于一点的邻域上的偏导数的数字近似,因此一幅图像f ,在 (x,y) 位置处的 x 和 y 方向上的梯度大小 {g}_{x}} 和 {g}_{y}} 分别计算为:

                                                                           {​{g}_{x}}=\frac{\partial f(x,y)}{\partial x}=f(x+1,y)-f(x,y)

                                                                           {​{g}_{y}}=\frac{\partial f(x,y)}{\partial y}=f(x,y+1)-f(x,y)

    上述两个公式对所有 x 和 y 的有关值可用下图的一维模板对 f(x,y) 的滤波得到。

    用于计算梯度偏导数的滤波器模板,通常称之为梯度算子边缘算子边缘检测子等。

    对于不同的滤波器模板得到的梯度是不同的,这也就衍生出很多算子,如Roberts、Prewitt、Sobel和Laplacian算子等。下面将详细介绍不同的算子。


     

    4 Roberts 算子

    4.1 基本原理

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

    Roberts算子的模板分为水平方向和垂直方向,如下式所示,从其模板可以看出,Roberts算子能较好的增强正负45度的图像边缘。

                                                                              {​{d}_{x}}=\left[ \begin{matrix} -1 & 0 \\ 0 & 1 \\ \end{matrix} \right]\begin{matrix} {} & {} \\ {} & {} \\ \end{matrix}{​{d}_{y}}=\left[ \begin{matrix} 0 & -1 \\ 1 & 0 \\ \end{matrix} \right]

    例如,下面给出Roberts算子模板,在像素点P5处 x 和 y 方向上的梯度大小 {g}_{x}} 和 {g}_{y}} 分别计算为:

                                                                                       {​{g}_{x}}=\frac{\partial f}{\partial x}=\text{P9-P5}

                                                                                       {​{g}_{y}}=\frac{\partial f}{\partial y}=\text{P8-P6}

     

     

    4.2 代码示例

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

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

    其中,参数:

    src 表示输入图像;

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

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

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

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

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

    borderType 表示边框模式。

    代码如下所示:

    # -*- coding: utf-8 -*-
    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    
    # 读取图像
    img = cv2.imread('zxp.jpg')
    img_RGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) #转成RGB 方便后面显示
    
    # 灰度化处理图像
    grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    # Roberts算子
    kernelx = np.array([[-1, 0], [0, 1]], dtype=int)
    kernely = np.array([[0, -1], [1, 0]], dtype=int)
    x = cv2.filter2D(grayImage, cv2.CV_16S, kernelx)
    y = cv2.filter2D(grayImage, cv2.CV_16S, kernely)
    # 转uint8
    absX = cv2.convertScaleAbs(x)
    absY = cv2.convertScaleAbs(y)
    Roberts = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)
    
    # 用来正常显示中文标签
    plt.rcParams['font.sans-serif'] = ['SimHei']
    
    # 显示图形
    # titles = [u'原始图像', u'Roberts算子']
    # images = [img_RGB, Roberts]
    # for i in range(2):
    #     plt.subplot(1, 2, i + 1), plt.imshow(images[i], 'gray')
    #     plt.title(titles[i])
    #     plt.xticks([]), plt.yticks([])
    
    # plt.show()
    
    # 显示图形
    plt.subplot(121),plt.imshow(img_RGB),plt.title('原始图像'), plt.axis('off') #坐标轴关闭
    plt.subplot(122),plt.imshow(Roberts, cmap=plt.cm.gray ),plt.title('Roberts算子'), plt.axis('off')
    plt.show()

     

    运行结果如下图所示:

     


     

    5 Prewitt 算子

    5.1 基本原理

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

                                                                      {​{d}_{y}}=\left[ \begin{matrix} -1 & 0 & 1 \\ -1 & 0 & 1 \\ -1 & 0 & 1 \\ \end{matrix} \right]\begin{matrix} {} & {} & {} \\ {} & {} & {} \\ {} & {} & {} \\ \end{matrix}{​{d}_{x}}=\left[ \begin{matrix} -1 & -1 & -1 \\ 0 & 0 & 0 \\ 1 & 1 & 1 \\ \end{matrix} \right]

    例如,下面给出Prewitt算子模板,在像素点P5处 x 和 y 方向上的梯度大小 {g}_{x}} 和 {g}_{y}} 分别计算为:

                                                                    {​{g}_{x}}=\frac{\partial f}{\partial x}=(\text{P7+P8+P9)-}(\text{P1+P2+P3)}

                                                                    {​{g}_{y}}=\frac{\partial f}{\partial y}=(\text{P3+P6+P9)-}(\text{P1+P4+P7)}

     

    5.2 代码示例

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

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

    其中,参数:

    src 表示输入图像;

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

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

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

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

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

    borderType 表示边框模式。

     

    代码如下所示:

    # -*- coding: utf-8 -*-
    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    
    # 读取图像
    img = cv2.imread('zxp.jpg')
    img_RGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    
    # 灰度化处理图像
    grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    # 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)
    x = cv2.filter2D(grayImage, cv2.CV_16S, kernelx)
    y = cv2.filter2D(grayImage, cv2.CV_16S, kernely)
    # 转uint8
    absX = cv2.convertScaleAbs(x)
    absY = cv2.convertScaleAbs(y)
    Prewitt = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)
    
    # 用来正常显示中文标签
    plt.rcParams['font.sans-serif'] = ['SimHei']
    
    # 显示图形
    # titles = [u'原始图像', u'Prewitt算子']
    # images = [img_RGB, Prewitt]
    # for i in range(2):
    #     plt.subplot(1, 2, i + 1), plt.imshow(images[i], 'gray')
    #     plt.title(titles[i])
    #     plt.xticks([]), plt.yticks([])
    # plt.show()
    
    
    # 显示图形
    plt.subplot(121),plt.imshow(img_RGB),plt.title('原始图像'), plt.axis('off') #坐标轴关闭
    plt.subplot(122),plt.imshow(Prewitt, cmap=plt.cm.gray ),plt.title('Prewitt算子'), plt.axis('off')
    plt.show()

     

    运行结果如下图所示:

    由上图可以看出Prewitt算子的边缘检测结果在水平方向和垂直方向均比Robert算子更加明显。

     


     

    6 Sobel 算子

    6.1 基本原理

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

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

    Sobel算子的边缘定位更准确,常用于噪声较多、灰度渐变的图像。其算法模板如下面的公式所示,其中 {​{d}_{x}} 表示水平方向,{​{d}_{y}} 表示垂直方向。

                                                                     {​{d}_{x}}=\left[ \begin{matrix} -1 & 0 & 1 \\ -2 & 0 & 2 \\ -1 & 0 & 1 \\ \end{matrix} \right]\begin{matrix} {} & {} & {} \\ {} & {} & {} \\ {} & {} & {} \\ \end{matrix}{​{d}_{y}}=\left[ \begin{matrix} -1 & -2 & -1 \\ 0 & 0 & 0 \\ 1 & 2 & 1 \\ \end{matrix} \right]

    例如,下面给出Sobel算子模板,在像素点P5处 x 和 y 方向上的梯度大小 {g}_{x}} 和 {g}_{y}} 分别计算为:

                                                                  {​{g}_{x}}=\frac{\partial f}{\partial x}=(\text{P7+2P8+P9)-}(\text{P1+2P2+P3)}

                                                                  {​{g}_{y}}=\frac{\partial f}{\partial y}=(\text{P3+2P6+P9)-}(\text{P1+2P4+P7)}

     

    6.2 代码示例

    Sobel() 函数用法如下所示:

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

    其中,参数:

    src 表示输入图像;

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

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

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

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

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

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

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

    borderType 表示边框模式,更多详细信息查阅BorderTypes。

     

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

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

    其中,参数:

    src 表示原数组;

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

    alpha 表示比例因子;

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

     

    代码如下所示:

    # -*- coding: utf-8 -*-
    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    
    # 读取图像
    img = cv2.imread('zxp.jpg')
    img_RGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    
    # 灰度化处理图像
    grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    # Sobel算子
    x = cv2.Sobel(grayImage, cv2.CV_16S, 1, 0)  # 对x求一阶导
    y = cv2.Sobel(grayImage, cv2.CV_16S, 0, 1)  # 对y求一阶导
    absX = cv2.convertScaleAbs(x)
    absY = cv2.convertScaleAbs(y)
    Sobel = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)
    
    # 用来正常显示中文标签
    plt.rcParams['font.sans-serif'] = ['SimHei']
    
    # # 显示图形
    # titles = [u'原始图像', u'Sobel算子']
    # images = [lenna_img, Sobel]
    # for i in xrange(2):
    #     plt.subplot(1, 2, i + 1), plt.imshow(images[i], 'gray')
    #     plt.title(titles[i])
    #     plt.xticks([]), plt.yticks([])
    # plt.show()
    
    # 显示图形
    plt.subplot(121),plt.imshow(img_RGB),plt.title('原始图像'), plt.axis('off') #坐标轴关闭
    plt.subplot(122),plt.imshow(Sobel, cmap=plt.cm.gray ),plt.title('Sobel算子'), plt.axis('off')
    plt.show()

     

    运行结果如下图所示:

     


     

    7 Laplacian 算子

    7.1 基本原理

    拉普拉斯(Laplacian) 算子是 n 维欧几里德空间中的一个二阶微分算子,常用于图像增强领域和边缘提取。它通过灰度差分计算邻域内的像素。

    算法基本流程

    1)判断图像中心像素灰度值与它周围其他像素的灰度值,如果中心像素的灰度更高,则提升中心像素的灰度;反之降低中心像素的灰度,从而实现图像锐化操作;

    2)在算法实现过程中,Laplacian算子通过对邻域中心像素的四方向或八方向求梯度,再将梯度相加起来判断中心像素灰度与邻域内其他像素灰度的关系;

    3)最后通过梯度运算的结果对像素灰度进行调整。

    Laplacian算子分为四邻域和八邻域,四邻域是对邻域中心像素的四个方向求梯度,八邻域是对八个方向求梯度。

    其中,Laplacian算子四邻域模板如下所示:

                                                                                  \text{H}=\left[ \begin{matrix} 0 & -1 & 0 \\ -1 & 4 & -1 \\ 0 & -1 & 0 \\ \end{matrix} \right]

    Laplacian算子的八邻域模板如下所示:

                                                                                  \text{H}=\left[ \begin{matrix} -1 & -1 & -1 \\ -1 & 8 & -1 \\ -1 & -1 & -1 \\ \end{matrix} \right]

    通过Laplacian算子的模板可以发现:

    1)当邻域内像素灰度相同时,模板的卷积运算结果为0;

    2)当中心像素灰度高于邻域内其他像素的平均灰度时,模板的卷积运算结果为正数;

    3)当中心像素的灰度低于邻域内其他像素的平均灰度时,模板的卷积为负数。对卷积运算的结果用适当的衰弱因子处理并加在原中心像素上,就可以实现图像的锐化处理。

                                                                                  

     

    7.2 代码示例

    Python和OpenCV将Laplacian算子封装在 Laplacian() 函数中,其函数用法如下所示:

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

    其中,参数:

    src 表示输入图像;

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

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

    ksize 表示用于计算二阶导数的滤波器的孔径大小,其值必须是正数和奇数,且默认值为1,更多详细信息查阅getDerivKernels ;

    scale 表示计算拉普拉斯算子值的可选比例因子。默认值为1,更多详细信息查阅getDerivKernels;

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

    borderType 表示边框模式,更多详细信息查阅BorderTypes。

    :Laplacian算子其实主要是利用Sobel算子的运算,通过加上Sobel算子运算出的图像 x 方向和 y 方向上的导数,得到输入图像的图像锐化结果。同时,在进行Laplacian算子处理之后,还需要调用 convertScaleAbs() 函数计算绝对值,并将图像转换为8位图进行显示。其函数用法如下:

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

    其中,参数:

    src 表示原数组;

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

    alpha 表示比例因子;

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

    当ksize=1时,Laplacian() 函数采用 3\times3 的孔径 (四邻域模板) 进行变换处理。下面的代码是采用 ksize=3 的Laplacian算子进行图像锐化处理。

     

    代码如下所示:

    # -*- coding: utf-8 -*-
    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    
    # 读取图像
    img = cv2.imread('zxp.jpg')
    img_RGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    
    # 灰度化处理图像
    grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    # 拉普拉斯算法
    dst = cv2.Laplacian(grayImage, cv2.CV_16S, ksize=3)
    Laplacian = cv2.convertScaleAbs(dst)
    
    # 用来正常显示中文标签
    plt.rcParams['font.sans-serif'] = ['SimHei']
    
    # # 显示图形
    # titles = [u'原始图像', u'Laplacian算子']
    # images = [lenna_img, Laplacian]
    # for i in xrange(2):
    #     plt.subplot(1, 2, i + 1), plt.imshow(images[i], 'gray')
    #     plt.title(titles[i])
    #     plt.xticks([]), plt.yticks([])
    # plt.show()
    
    
    # 显示图形
    plt.subplot(121),plt.imshow(img_RGB),plt.title('原始图像'), plt.axis('off') #坐标轴关闭
    plt.subplot(122),plt.imshow(Laplacian, cmap=plt.cm.gray ),plt.title('Laplacian算子'), plt.axis('off')
    plt.show()

     

    运行结果如下图所示:

     


     

    8 小结

    8.1 各类算子实验比较

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

     

    代码如下所示:

    # -*- coding: utf-8 -*-
    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    
    #读取图像
    img = cv2.imread('zxp.jpg')
    img_RGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) #转成RGB 方便后面显示
    
    #灰度化处理图像
    grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    #高斯滤波
    gaussianBlur = cv2.GaussianBlur(grayImage, (3,3), 0)
    
    #阈值处理
    ret, binary = cv2.threshold(gaussianBlur, 127, 255, cv2.THRESH_BINARY)
    
    #Roberts算子
    kernelx = np.array([[-1,0],[0,1]], dtype=int)
    kernely = np.array([[0,-1],[1,0]], dtype=int)
    x = cv2.filter2D(binary, cv2.CV_16S, kernelx)
    y = cv2.filter2D(binary, cv2.CV_16S, kernely)
    absX = cv2.convertScaleAbs(x)
    absY = cv2.convertScaleAbs(y)
    Roberts = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)
    
    #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)
    x = cv2.filter2D(binary, cv2.CV_16S, kernelx)
    y = cv2.filter2D(binary, cv2.CV_16S, kernely)
    absX = cv2.convertScaleAbs(x)
    absY = cv2.convertScaleAbs(y)
    Prewitt = cv2.addWeighted(absX,0.5,absY,0.5,0)
    
    #Sobel算子
    x = cv2.Sobel(binary, cv2.CV_16S, 1, 0)
    y = cv2.Sobel(binary, cv2.CV_16S, 0, 1)
    absX = cv2.convertScaleAbs(x)
    absY = cv2.convertScaleAbs(y)
    Sobel = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)
    
    #Laplacian算子
    dst = cv2.Laplacian(binary, cv2.CV_16S, ksize = 3)
    Laplacian = cv2.convertScaleAbs(dst)
    
    # #效果图
    # titles = ['Source Image', 'Binary Image', 'Roberts Image',
    #           'Prewitt Image','Sobel Image', 'Laplacian Image']
    # images = [lenna_img, binary, Roberts, Prewitt, Sobel, Laplacian]
    # for i in np.arange(6):
    #    plt.subplot(2,3,i+1),plt.imshow(images[i],'gray')
    #    plt.title(titles[i])
    #    plt.xticks([]),plt.yticks([])
    # plt.show()
    
    # 用来正常显示中文标签
    plt.rcParams['font.sans-serif'] = ['SimHei']
    
    # # 显示图形
    plt.subplot(231),plt.imshow(img_RGB),plt.title('原始图像'), plt.axis('off') #坐标轴关闭
    plt.subplot(232),plt.imshow(binary, cmap=plt.cm.gray ),plt.title('二值图'), plt.axis('off')
    plt.subplot(233),plt.imshow(Roberts, cmap=plt.cm.gray ),plt.title('Roberts算子'), plt.axis('off')
    plt.subplot(234),plt.imshow(Prewitt, cmap=plt.cm.gray ),plt.title('Prewitt算子'), plt.axis('off')
    plt.subplot(235),plt.imshow(Sobel, cmap=plt.cm.gray ),plt.title('Sobel算子'), plt.axis('off')
    plt.subplot(236),plt.imshow(Laplacian, cmap=plt.cm.gray ),plt.title('Laplacian算子'), plt.axis('off')
    
    plt.show()

     

    运行结果如下图所示:

     

    为了比较不同算子,多测试了几张图像,如下图所示:

     

     

     

    由上面的结果所示,不同的算子进行了比较。可知:

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

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

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

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

     

    8.2 各类算子的优缺点

    (1)Roberts 算子 

    Roberts算子利用局部差分算子寻找边缘,边缘定位精度较高,但容易丢失一部分边缘,不具备抑制噪声的能力。该算子对具有陡峭边缘且含噪声少的图像效果较好,尤其是边缘正负45度较多的图像,但定位准确率较差;

     

    (2)Sobel 算子

    Sobel算子考虑了综合因素,对噪声较多的图像处理效果更好,Sobel 算子边缘定位效果不错,但检测出的边缘容易出现多像素宽度。

     

    (3) Prewitt 算子

    Prewitt算子对灰度渐变的图像边缘提取效果较好,而没有考虑相邻点的距离远近对当前像素点的影响,与Sobel 算子类似,不同的是在平滑部分的权重大小有些差异;

     

    (4)Laplacian 算子

    Laplacian 算子不依赖于边缘方向的二阶微分算子,对图像中的阶跃型边缘点定位准确,该算子对噪声非常敏感,它使噪声成分得到加强,这两个特性使得该算子容易丢失一部分边缘的方向信息,造成一些不连续的检测边缘,同时抗噪声能力比较差,由于其算法可能会出现双像素边界,常用来判断边缘像素位于图像的明区或暗区,很少用于边缘检测;

     

     

    参考资料

    [1] https://blog.csdn.net/Eastmount/article/details/89001702

    [2] 杨帆. 数字图像处理与分析(第三版). 北京航空航天大学出版社

    [3] 冈萨雷斯. 数字图像处理(第三版) 

     


    如果觉得内容还不错的话,欢迎点赞、转发、收藏,还可以关注微信公众号、CSDN博客、知乎。
     

    1. 微信公众号:

    2. CSDN博客:https://xiongyiming.blog.csdn.net/

    3. 知乎:https://www.zhihu.com/people/xiongyiming

     

     

     

    展开全文
  • Prewitt算子边缘检测原理及实现

    万次阅读 2019-06-10 18:22:36
    写在前面 Prewitt算子同样也是一种一阶微分算子,利用像素点上下左右邻点灰度...相比Roberts算子,Prewitt算子对噪声有抑制作用,抑制噪声的原理是通过像素平均,因此噪声较多的图像处理得比较好,但是像素平均相当...

    写在前面

    Prewitt算子同样也是一种一阶微分算子,利用像素点上下左右邻点灰度差,在边缘处达到极值检测边缘,对噪声具有平滑的作用。

    原理

    其原理是在图像空间利用两个方向模板与图像进行邻域卷积来完成的,这两个方向模板一个检测水平边缘,一个检测垂直边缘。

    相比Roberts算子,Prewitt算子对噪声有抑制作用,抑制噪声的原理是通过像素平均,因此噪声较多的图像处理得比较好,但是像素平均相当于对图像的低通滤波,所以Prewitt算子对边缘的定位却不如Roberts算子。

    那么为啥Prewitt算子对噪声有抑制作用呢?请看Prewitt算子的卷积核:

    ââ

                                                             Prewitt_X                                     Prewitt_Y 

    图像与Prewitt_X卷积后可以反映图像的垂直边缘,与Prewitt_Y卷积后可以反映图像的水平边缘。最重要的是,这两个卷积是可分离的:

                                        Prewitt_X =\begin{bmatrix}1 \\ 1 \\ 1 \end{bmatrix} *\begin{bmatrix} -1 & 0 &1 \end{bmatrix}        ,          Prewitt_Y =\begin{bmatrix} 1 & 1 &1 \end{bmatrix}*\begin{bmatrix}1 \\ 0 \\ -1 \end{bmatrix}

    从分离的结果来看, Prewitt_X算子实际上是先对图像进行垂直方向的非归一化的均值平滑,然后进行水平方向的差分; 然而Prewitt_Y算子实际上是先对图像进行水平方向的非归一化的均值平滑,然后进行垂直方向的差分。这就是Prewitt算子能够抑制噪声的原因。

    同理,我们也可以得到对角上的Prewitt算子算子,见代码即可。

     

    代码实现

    #include <iostream>
    #include <opencv2/core.hpp>
    #include <opencv2/highgui.hpp>
    #include <opencv2/imgproc.hpp>
    
    void getPrewitt_oper(cv::Mat& getPrewitt_horizontal, cv::Mat& getPrewitt_vertical, cv::Mat& getPrewitt_Diagonal1,cv::Mat& getPrewitt_Diagonal2){
    	//水平方向
    	getPrewitt_horizontal = (cv::Mat_<float>(3, 3) << -1, -1, -1, 0, 0, 0, 1, 1, 1);
    	//垂直方向
    	getPrewitt_vertical = (cv::Mat_<float>(3, 3) << -1, 0, 1, -1, 0, 1, -1, 0, 1);
    	//对角135°
    	getPrewitt_Diagonal1 = (cv::Mat_<float>(3, 3) << 0, 1, 1, -1, 0, 1, -1, -1, 0);
    	//对角45°
    	getPrewitt_Diagonal2 = (cv::Mat_<float>(3, 3) << -1, -1, 0, -1, 0, 1, 0, 1, 1);
    
    	//逆时针反转180°得到卷积核
    	cv::flip(getPrewitt_horizontal, getPrewitt_horizontal, -1);
    	cv::flip(getPrewitt_vertical, getPrewitt_vertical, -1);
    	cv::flip(getPrewitt_Diagonal1, getPrewitt_Diagonal1, -1);
    	cv::flip(getPrewitt_Diagonal2, getPrewitt_Diagonal2, -1);
    }
    
    void edge_Prewitt(cv::Mat& src, cv::Mat& dst1, cv::Mat& dst2, cv::Mat& dst3, cv::Mat& dst4, cv::Mat& dst, int ddepth, double delta = 0, int borderType = cv::BORDER_DEFAULT){
    	//获取Prewitt算子
    	cv::Mat getPrewitt_horizontal;
    	cv::Mat getPrewitt_vertical;
    	cv::Mat getPrewitt_Diagonal1;
    	cv::Mat getPrewitt_Diagonal2;
    	getPrewitt_oper(getPrewitt_horizontal, getPrewitt_vertical, getPrewitt_Diagonal1, getPrewitt_Diagonal2);
    
    	//卷积得到水平方向边缘
    	cv::filter2D(src, dst1, ddepth, getPrewitt_horizontal, cv::Point(-1, -1), delta, borderType);
    
    	//卷积得到4垂直方向边缘
    	cv::filter2D(src, dst2, ddepth, getPrewitt_vertical, cv::Point(-1, -1), delta, borderType);
    
    	//卷积得到45°方向边缘
    	cv::filter2D(src, dst3, ddepth, getPrewitt_Diagonal1, cv::Point(-1, -1), delta, borderType);
    
    	//卷积得到135°方向边缘
    	cv::filter2D(src, dst4, ddepth, getPrewitt_Diagonal2, cv::Point(-1, -1), delta, borderType);
    
    	//边缘强度(近似)
    	cv::convertScaleAbs(dst1, dst1); //求绝对值并转为无符号8位图
    	cv::convertScaleAbs(dst2, dst2);
    
    	cv::convertScaleAbs(dst3, dst3); //求绝对值并转为无符号8位图
    	cv::convertScaleAbs(dst4, dst4);
    	dst = dst1 + dst2 ;
    
    }
    
    
    int main(){
    	cv::Mat src = cv::imread("I:\\Learning-and-Practice\\2019Change\\Image process algorithm\\Img\\(embedded_square_noisy_512).tif");
    	if (src.empty()){
    		return -1;
    	}
    	if (src.channels() > 1) cv::cvtColor(src, src, CV_RGB2GRAY);
    	cv::Mat dst, dst1, dst2, dst3, dst4;
    
    	//注意:要采用CV_32F,因为有些地方卷积后为负数,若用8位无符号,则会导致这些地方为0
    	edge_Prewitt(src, dst1, dst2, dst3, dst4, dst, CV_32F);
    
    	cv::namedWindow("src", CV_WINDOW_NORMAL);
    	imshow("src", src);
    	cv::namedWindow("水平边缘", CV_WINDOW_NORMAL);
    	imshow("水平边缘", dst1);
    	cv::namedWindow("垂直边缘", CV_WINDOW_NORMAL);
    	imshow("垂直边缘", dst2);
    	cv::namedWindow("45°边缘", CV_WINDOW_NORMAL);
    	imshow("45°边缘", dst3);
    	cv::namedWindow("135°边缘", CV_WINDOW_NORMAL);
    	imshow("135°边缘", dst4);
    	cv::namedWindow("边缘强度", CV_WINDOW_NORMAL);
    	imshow("边缘强度", dst);
    	cv::waitKey(0);
    	return 0;
    }

    效果

     

    展开全文
  • 图像边缘检测之Prewitt算子

    千次阅读 2020-05-10 19:45:49
    Prewitt算子是一种图像边缘检测的微分算子,其原理是利用特定区域内像素灰度值产生的差分实现边缘检测。由于Prewitt算子采用 3x3 模板对区域内的像素值进行计算,而Robert算子的模板为 2x2,故Prewitt算子的边缘检测...

    Prewitt 算子

    1. 原理

    Prewitt算子是一种图像边缘检测的微分算子,其原理是利用特定区域内像素灰度值产生的差分实现边缘检测。由于Prewitt算子采用 3x3 模板对区域内的像素值进行计算,而Robert算子的模板为 2x2,故Prewitt算子的边缘检测结果在水平方向和垂直方向均比Robert算子更加明显。Prewitt算子适合用来识别噪声较多、灰度渐变的图像,其计算公式如下所示:
    在这里插入图片描述
    例如,下面给出Prewitt算子的模板,在像素点P5处 x 和 y 方向上的梯度大小 g_x 和 g_y 分别计算为:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    2. pytohn代码

    # -*- coding: utf-8 -*-
    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
     
    # 读取图像
    img = cv2.imread('C:/Users/123/Pictures/66.png')
    img_RGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
     
    # 灰度化处理图像
    grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
     
    # 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)
    x = cv2.filter2D(grayImage, cv2.CV_16S, kernelx)
    y = cv2.filter2D(grayImage, cv2.CV_16S, kernely)
    # 转uint8
    absX = cv2.convertScaleAbs(x)
    absY = cv2.convertScaleAbs(y)
    Prewitt = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)
     
    # 用来正常显示中文标签
    plt.rcParams['font.sans-serif'] = ['SimHei']
     
    # 显示图形
    plt.subplot(121),plt.imshow(img_RGB),plt.title('原始图像'), plt.axis('off') #坐标轴关闭
    plt.subplot(122),plt.imshow(Prewitt, cmap=plt.cm.gray ),plt.title('Prewitt算子'), plt.axis('off')
    plt.show()
    

    效果图:
    在这里插入图片描述

    3. matlab代码

    I =imread('C:/Users/123/Pictures/66.png');
    I0=rgb2gray(I);
    BW1 =edge(I0,'prewitt');
    subplot(121),imshow(I0);title('原始图像');
    subplot(122),imshow(BW1);title('prewitt算子');
    

    效果图:
    在这里插入图片描述

    展开全文
  • 文章目录10.1 Python图像处理之边缘算子-Sobel算子、Roberts算子、拉普拉斯算子、Canny算子、Prewitt算子、高斯拉普拉斯算子1 算法原理1.1 Sobel 算子1.2 Roberts 算子1.3 拉普拉斯(Laplacian) 算子1.4 Canny 算法...

    10.1 Python图像处理之边缘算子-Sobel算子、Roberts算子、拉普拉斯算子、Canny算子、Prewitt算子、高斯拉普拉斯算子

    1 算法原理

    图像边缘是图像最基本的特征,所谓边缘(Edge) 是指图像局部特性的不连续性。灰度或结构等信息的突变处称之为边缘。例如,灰度级的突变、颜色的突变,、纹理结构的突变等。边缘是一个区域的结束,也是另一个区域的开始,利用该特征可以分割图像。图像的边缘有方向和幅度两种属性。边缘通常可以通过一阶导数或二阶导数检测得到。一阶导数是以最大值作为对应的边缘的位置,而二阶导数则以过零点作为对应边缘的位置。

    边缘检测算子分类

    一阶导数的边缘算子

    通过模板作为核与图像的每个像素点做卷积和运算,然后选取合适的阈值来提取图像的边缘。常见的有 Roberts 算子、Sobel 算子和 Prewitt 算子。

    二阶导数的边缘算子依据于二阶导数过零点,常见的有 Laplacian 算子,此类算子对噪声敏感。

    其他边缘算子

    前面两类均是通过微分算子来检测图像边缘,还有一种就是 Canny 算子,其是在满足一定约束条件下推导出来的边缘检测最优化算子。

    1.1 Sobel 算子

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

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

    Sobel 算子的边缘定位更准确,常用于噪声较多、灰度渐变的图像。其算法模板如下面的公式所示,其中 dx 表示水平方向,dy 表示垂直方向。

    image-20210808215835555

    1.2 Roberts 算子

    Roberts 算子又称为交叉微分算法,它是基于交叉差分的梯度算法,通过局部差分计算检测边缘线条。常用来处理具有陡峭的低噪声图像,当图像边缘接近于正 45 度或负 45 度时,该算法处理效果更理想。其缺点是对边缘的定位不太准确,提取的边缘线条较粗。Roberts 算子的模板分为水平方向和垂直方向,如下式所示,从其模板可以看出,Roberts 算子能较好的增强正负 45 度的图像边缘。

    image-20210808215851665

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

    1.3 拉普拉斯(Laplacian) 算子

    拉普拉斯(Laplacian) 算子是 n 维欧几里德空间中的一个二阶微分算子,常用于图像增强领域和边缘提取。它通过灰度差分计算邻域内的像素。算法基本流程为:

    1. 判断图像中心像素灰度值与它周围其他像素的灰度值,如果中心像素的灰度更高,则提升中心像素的灰度;反之降低中心像素的灰度,从而实现图像锐化操作;

    2. 在算法实现过程中,Laplacian 算子通过对邻域中心像素的四方向或八方向求梯度,再将梯度相加起来判断中心像素灰度与邻域内其他像素灰度的关系;

    3. 最后通过梯度运算的结果对像素灰度进行调整。

    1.4 Canny 算法

    Canny 算法是一种被广泛应用于边缘检测的标准算法,其目标是找到一个最优的边缘检测解或找寻一幅图像中灰度强度变化最强的位置。最优边缘检测主要通过低错误率、高定位性和最小响应三个标准进行评价。Canny 算子的简要步骤如下:

    1. 去噪声:应用高斯滤波来平滑图像,目的是去除噪声;

    2. 梯度:找寻图像的梯度;

    3. 非极大值抑制:应用非最大抑制技术来过滤掉非边缘像素,将模糊的边界变得清晰。该过程保留了每个像素点上梯度强度的极大值,过滤掉其他的值;

    4. 应用双阈值的方法来决定可能的(潜在的)边界;

    5. 利用滞后技术来跟踪边界。若某一像素位置和强边界相连的弱边界认为是边界,其他的弱边界则被删除。

    1.5 Prewitt 算子

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

    image-20210808220047293

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

    1.6 高斯拉普拉斯算子(LOG 算子)

    高斯拉普拉斯算子(LOG 算子):是高斯和拉普拉斯的双结合,即集平滑和边沿于一身的算子模型。LoG 算子是由拉普拉斯算子改进而来。拉普拉斯算子是一个单纯的二阶导数算子,是一个标量,具有线性、位移不变性,其传函在频域空间的原点为 0。所有经过拉普拉斯算子滤波的图像具有零平均灰度。但是该算子的缺点是 对噪声具有无法接受的敏感性,因此在实际应用中,一般先要对图像进行平滑滤波,再用拉氏算子进行图像的边缘检测。这就是 LOG 算子的产生的背景(最后的梯度表达式为 高斯函数和原图像卷积,再去二阶微分算子)。以 0 为中心,高斯标准差为 σ 的二维的 LOG 函数的表达式如下所示:

    image-20210808220118685

    2 代码

    运行代码说明

    1.要改变代码中的图片地址(地址不能有中文)

    更改put(path)函数中的路径put(r'../image/image1.jpg')

    2.注意最后的plt.savefig('1.new.jpg')是保存plt图像,如果不使用可以注释掉

    代码依赖包:

    matplotlib  3.4.2
    numpy  1.20.3
    opencv-python  4.1.2.30
    
    # pip安装
    pip install matplotlib numpy opencv-python
    
    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    
    def put(path):
        # 读取图像
        img = cv2.imread(path)
        b, g, r = cv2.split(img)
        img2 = cv2.merge([r, g, b])
    
        # 灰度化处理图像
        grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
        # 高斯滤波
        gaussianBlur = cv2.GaussianBlur(grayImage, (3, 3), 0)
    
        # 二值化
        ret, binary = cv2.threshold(grayImage, 127, 255, cv2.THRESH_BINARY)
    
        # Sobel算子
        x = cv2.Sobel(grayImage, cv2.CV_16S, 1, 0)  # 对x求一阶导
        y = cv2.Sobel(grayImage, cv2.CV_16S, 0, 1)  # 对y求一阶导
        absX = cv2.convertScaleAbs(x)
        absY = cv2.convertScaleAbs(y)
        Sobel = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)
    
        # Roberts算子
        kernelx = np.array([[-1, 0], [0, 1]], dtype=int)
        kernely = np.array([[0, -1], [1, 0]], dtype=int)
        x = cv2.filter2D(grayImage, cv2.CV_16S, kernelx)
        y = cv2.filter2D(grayImage, cv2.CV_16S, kernely)
        # 转uint8
        absX = cv2.convertScaleAbs(x)
        absY = cv2.convertScaleAbs(y)
        Roberts = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)
    
        # 拉普拉斯算子
        dst = cv2.Laplacian(grayImage, cv2.CV_16S, ksize=3)
        Laplacian = cv2.convertScaleAbs(dst)
    
        # 高斯滤波降噪
        gaussian = cv2.GaussianBlur(grayImage, (5, 5), 0)
    
        # Canny算子
        Canny = cv2.Canny(gaussian, 50, 150)
    
        # 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)
        x = cv2.filter2D(grayImage, cv2.CV_16S, kernelx)
        y = cv2.filter2D(grayImage, cv2.CV_16S, kernely)
        # 转uint8
        absX = cv2.convertScaleAbs(x)
        absY = cv2.convertScaleAbs(y)
        Prewitt = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)
    
        # 高斯拉普拉斯算子
        gaussian = cv2.GaussianBlur(grayImage, (3, 3), 0)  # 先通过高斯滤波降噪
        dst = cv2.Laplacian(gaussian, cv2.CV_16S, ksize=3)  # 再通过拉普拉斯算子做边缘检测
        LOG = cv2.convertScaleAbs(dst)
    
        # 用来正常显示中文标签
        plt.rcParams['font.sans-serif'] = ['SimHei']
    
        # 显示图形
        plt.subplot(241), plt.imshow(img2), plt.title('原始图像'), plt.axis('off')
        plt.subplot(242), plt.imshow(binary, plt.cm.gray), plt.title('二值图'), plt.axis('off')
        plt.subplot(243), plt.imshow(Sobel, plt.cm.gray), plt.title('Sobel算子'), plt.axis('off')
        plt.subplot(244), plt.imshow(Roberts, plt.cm.gray), plt.title('Roberts算子'), plt.axis('off')
        plt.subplot(245), plt.imshow(Laplacian, plt.cm.gray), plt.title('拉普拉斯算子'), plt.axis('off')
        plt.subplot(246), plt.imshow(Canny, plt.cm.gray), plt.title('Canny算子'), plt.axis('off')
        plt.subplot(247), plt.imshow(Prewitt, plt.cm.gray), plt.title('Prewitt算子'), plt.axis('off')
        plt.subplot(248), plt.imshow(LOG, plt.cm.gray), plt.title('高斯拉普拉斯算子'), plt.axis('off')
    
        # plt.savefig('1.new-2.jpg')
        plt.show()
    
    # 图像处理函数,要传入路径
    put(r'../image/image3.jpg')
    

    3 效果

    image-20210808220308754

    展开全文
  • Prewitt算子

    千次阅读 2013-11-18 13:54:13
    Prewitt算子是一种一阶微分算子的边缘检测,利用像素点上下、左右邻点的灰度差,在边缘处达到 极值检测边缘,去掉部分伪边缘,对噪声具有平滑作用 。其原理是在图像空间利用两个方向模板与图 像进行邻域卷积来完成的...
  • Prewitt算子计算图像梯度

    千次阅读 2018-11-28 08:52:33
    Prewitt算子是一阶微分算子的边缘检测,利用像素点上下、左右邻点的灰度差,在边缘处达到极值检测边缘,去掉部分伪边缘,对噪声具有平滑作用。其原理是在图像空间利用两个方向模板与图像进行邻域卷积来完成,这两个...
  • prewitt算子实现

    2021-06-13 14:07:32
    //获取Prewitt算子 Mat getPrewitt_horizontal = (Mat_<float>(3, 3) << -1, -1, -1, 0, 0, 0, 1, 1, 1); //水平方向 Mat getPrewitt_vertical = (Mat_<float>(3, 3) << -1, 0, 1, -1, 0...
  • Prewitt算子的运用

    千次阅读 2015-07-15 14:46:57
    Prewitt算子折叠 是一种一阶微分算子的边缘检测,利用像素点上下、左右邻点的灰度差,在边缘处达到 极值检测边缘,去掉部分伪边缘,对噪声具有平滑作用 。其原理是在图像空间利用两个方向模板与图 像...
  • Robert算子、sobel算子、Prewitt算子、canny边缘检测算子 之前做的笔记,懒得再敲一遍了,先传上来,方便自己以后加深记忆
  • 在OpenCV里实现Prewitt算子

    千次阅读 2019-10-04 10:22:54
    Prewitt算子是一种一阶微分算子的边缘检测,利用像素点上下、左右邻点的灰度差,在边缘处达到极值检测边缘,去掉部分伪边缘,对噪声具有平滑作用 。其原理是在图像空间利用两个方向模板与图像进行邻域卷积来完成的,...
  • 原理使用prewitt算子找到图像边缘。设定阈值,并根据阈值将边缘转化成二值数组。将二值数组中值为1的像素以原灰度值显示,值为0的像素灰度值置0显示。注:因为选择的是白纸黑字的图像,所以边缘实际上就是图像前景,...
  • 目录 方法对比 ... 算子:非微分边缘检测算子 公式对比 算子:, 算子:, 算子:, 算子:领域:;邻域: 算子:实现步骤:1. 用高斯滤波器平滑图像 2. 计算图像中每个像素点的梯度强度和方向...
  • dsp图像处理Prewitt算子边缘检测

    千次阅读 2013-07-11 19:47:33
    Prewitt算子边缘检测 一、实验背景与意义 图像处理就是对信息加工以满足人的视觉心理或应用需求的方法。图像处理的方法有光学方法和电子学方法。从20世纪60年代起随着电子计算机和计算技术的不断提高和普及,数字...
  • 学习DIP第47天 转载请标明本文出处:http://blog.csdn.net/tonyshengtan ,出于尊重文章作者的劳动,转载请标明出处!文章代码已托管,欢迎共同开发:... ... ...依然是废话,这篇主要想对比下Sobel,Prewitt和Scharr...
  • Prewitt算子对噪声有抑制作用,抑制噪声的原理是通过像素平均,但是像素平均相当于对图像的低通滤波,所以Prewitt算子对边缘的定位不如Roberts算子。 因为平均能减少或消除噪声,Prewitt梯度算子法就是先求平均,再...
  • Roberts算子Roberts算子即为交叉微分算法,它是基于交叉差分的梯度算法,通过局部差分计算检测边缘线条。常用来处理具有陡峭的第噪声图像,当图像边缘接近于正45度或负45度时,该算法处理效果更理想,其缺点时对边缘...
  • read_image (Image, 'C:/Users/ShineZhang/Desktop/img/IMG_20200109_155410.jpg...prewitt_dir (Image, ImageEdgeAmp, ImageEdgeDir) nonmax_suppression_dir (ImageEdgeAmp, ImageEdgeAmp, ImageResult, 'nms') th...
  •  prewitt算子是加权平均算子,对噪声有抑制作用,但是像素平均相当于对图像进行的同滤波,所以prewitt算子对边缘的定位不如robert算子。 cv2.filter2D实现 import cv2 import numpy as np import matplotlib.pyplot...
  • sobel算子原理与实践

    千次阅读 2019-04-01 22:21:03
    它是prewitt算子的改进形式,改进之处在于sobel算子认为,邻域的像素对当前像素产生的影响不是等价的,所以距离不同的像素具有不同的权值,对算子结果产生的影响也不同。一般来说,距离越远,产生的影响越小。 ...
  • Prewitt边缘检测算子

    2020-07-23 16:55:49
    Prewitt算子也是一种一阶微分算子,用于边缘检测。与Robert使用22的模板不同,Prewitt算子使用的是33的模板,利用像素点上下、左右邻点的灰度差来检测边缘,故其边缘检测结果在水平方向和垂直方向均比Robert算子更加...
  • 原理详解请查看另一篇文章 Canny import cv2 import numpy as np from matplotlib import pyplot as plt img = cv2.imread('/Users/。。。/Desktop/test.jpg',0) edges = cv2.Canny(img,100,200) plt.subplot(121...
  • 图像处理中的微分算子原理与实现 一阶微分边缘算子:经典算子比如:Roberts(罗伯特)、Prewitt(普鲁伊特)、Sobel(索贝尔),Canny(坎尼)等。 二阶微分边缘算子:Laplacian算子,LoG( Laplace of Gaussian ...
  • 一、算子简介   在一维连续数集上有函数f(x),我们可以通过求导...  Prewitt算子是一种一阶微分算子的边缘检测,利用像素点上下、左右邻点的灰度差,在边缘处达到极值检测边缘,去掉部分伪边缘,对噪声具有平...
  • Sobel算子 原理

    2017-03-22 14:56:52
    这就是所谓的Prewitt算子。这样近似X方向导数就求出来了。Y方向导数与X方向导数求法相似,只不过是用第三行元素之和减去第一行元素之和。X方向和Y方向导数有了,那么梯度也就出来了。这样就可以找出一幅图中的边缘了...
  • Sobel算子边缘检测原理及实现

    千次阅读 2019-06-10 22:33:27
    Prewitt算子同样是一种一阶微分算子,它的卷积算子和Prewitt算子非常类似,仅仅是系数不同,但Sobel算子对于像素位置的影响做了加权,与Prewitt算子、Roberts算子相比效果更好。 优点 对边缘定位较为准确,能较好...
  • 一、sobel算子 sobel算子的核心是像素矩阵的卷积,而卷积本质就是对指定的图像区域的像素值进行加权求和的过程,其计算过程为图像区域中的每个像素值分别与卷积模板的每个元素对应相乘,将卷积的结果作求和运算,...
  • 图像处理算法中,边缘检测是非常有用的...因此边缘检测算子也可在视为一种“滤波算法”,只保留了图像的边缘结构信息。  边缘检测算子一般分为三个步骤。  1.滤波  边缘检测的算法主要是基于图像强度的一阶和...
  • Sobel算子原理及OpenCv实现

    千次阅读 2015-04-23 10:07:09
    索贝尔算子(Sobeloperator)主要用于获得数字图像的一阶梯度,常见的应用和物理意义是边缘检测。 在技术上,它是一个离散的一阶差分算子,用来计算图像亮度函数的一阶梯度之近似值,用来运算图像亮度函数的灰度...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,368
精华内容 547
关键字:

prewitt算子原理