算法步骤:

(1) 高斯模糊,去噪;

(2)灰度转换

(3)计算梯度

(4)非最大信号压制;

(5)高低阈值的过滤,双阈值的办法,输出二值图像,提取边缘 

 

其中,(4)对梯度幅值进行非极大值抑制

        图像梯度幅值矩阵中的元素值越大,说明图像中该点的梯度值越大,但这不不能说明该点就是边缘(这仅仅是属于图像增强的过程)。在Canny算法中,非极大值抑制是进行边缘检测的重要步骤,通俗意义上是指寻找像素点局部最大值,将非极大值点所对应的幅值置为0,这样可以剔除掉一大部分非边缘的点(这是本人的理解)。

python opencv 网络进行分类_灰度

 

图1 非极大值抑制原理

        根据图1 可知,要进行非极大值抑制,就首先要确定像素点C的灰度值在其8值邻域内是否为最大。图1中蓝色的线条方向为C点的梯度方向,这样就可以确定其局部的最大值肯定分布在这条线上,也即出了C点外,梯度方向的交点dTmp1和dTmp2这两个点的值也可能会是局部最大值。因此,判断C点灰度与这两个点灰度大小即可判断C点是否为其邻域内的局部最大灰度点。如果经过判断,C点灰度值小于这两个点中的任一个,那就说明C点不是局部极大值,那么则可以排除C点为边缘。这就是非极大值抑制的工作原理。
实际上,我们只能得到C点邻域的8个点的值,而dTmp1和dTmp2并不在其中,要得到这两个值就需要对该两个点两端的已知灰度进行线性插值,也即根据图1中的g1和g2对dTmp1进行插值,根据g3和g4对dTmp2进行插值,这要用到其梯度方向,这是上文Canny算法中要求解梯度方向矩阵Theta的原因。

 

代码如下:
import numpy as np
import cv2 as cv

def edge_demo(image):
    blurred=cv.GaussianBlur(image,(3,3),0) #step1,降低噪声
    gray=cv.cvtColor(blurred,cv.COLOR_BGR2GRAY) #step2
    #step3, canny 算法对噪声敏感
    edge_out=cv.Canny(gray,50,150) #3:1
    cv.imshow('Canny edge',edge_out)

src=cv.imread('D:/opencv/meinv.jpg')
cv.imshow('src',src)
edge_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()