Canny边缘检测原理及其python实现
   
转载请注明出处:©️
Sylvan Ding
    
    
    Canny边缘检测算法
   
多数分割算法均基于灰度值的两个基本性质之一:不连续性和相似性。图像的边缘检测就是基于灰度的不连续性(灰度突变)来实现图像分割的。
边缘检测器是设计用来检测边缘像素的局部图像处理方法。一条线可视为一条边缘线段,该线两侧的背景灰度要么远亮于该线像素的灰度,要么远暗于该线像素的灰度,这样的线称之为“屋顶边缘”。
虽然Canny[1968]算法复杂,但其边缘检测的表现却相当优秀。
    
    
    工具介绍
   
为了方便计算,我们将所有灰度都标定到 [0,1](归一化),这样就无需考虑系数的问题了。
    
    
    二阶偏微分
   
    
     
      
       
        ∂ 
f
∂
x
=
f
(
x
+
1
)
−
f
(
x
)
         \frac{\partial f}{\partial x}=f(x+1)-f(x)
       
       
        
         
         
         
          
          
          
           
            
             
              
               
               
               
                
                 ∂
                
                
                 x
                
               
              
              
               
               
               
               
              
              
               
               
               
                
                 ∂
                
                
                 f
                
               
              
             
             
              
             
            
            
             
              
              
             
            
           
          
          
          
         
         
         
         
          =
         
         
         
        
        
         
         
         
          f
         
         
          (
         
         
          x
         
         
         
         
          +
         
         
         
        
        
         
         
         
          1
         
         
          )
         
         
         
         
          −
         
         
         
        
        
         
         
         
          f
         
         
          (
         
         
          x
         
         
          )
         
        
       
      
     
    
   
    
     
      
       
        ∂ 
2
f
∂
x
2
=
f
(
x
+
1
)
+
f
(
x
−
1
)
−
2
f
(
x
)
         \frac{\partial^{2} f}{\partial x^{2}}=f(x+1)+f(x-1)-2 f(x)
       
       
        
         
         
         
          
          
          
           
            
             
              
               
               
               
                
                 ∂
                
                
                 
                  x
                 
                 
                  
                   
                    
                     
                      
                      
                      
                       
                        
                         2
                        
                       
                      
                     
                    
                   
                  
                 
                
               
              
              
               
               
               
               
              
              
               
               
               
                
                 
                  ∂
                 
                 
                  
                   
                    
                     
                      
                      
                      
                       
                        
                         2
                        
                       
                      
                     
                    
                   
                  
                 
                
                
                 f
                
               
              
             
             
              
             
            
            
             
              
              
             
            
           
          
          
          
         
         
         
         
          =
         
         
         
        
        
         
         
         
          f
         
         
          (
         
         
          x
         
         
         
         
          +
         
         
         
        
        
         
         
         
          1
         
         
          )
         
         
         
         
          +
         
         
         
        
        
         
         
         
          f
         
         
          (
         
         
          x
         
         
         
         
          −
         
         
         
        
        
         
         
         
          1
         
         
          )
         
         
         
         
          −
         
         
         
        
        
         
         
         
          2
         
         
          f
         
         
          (
         
         
          x
         
         
          )
         
        
       
      
     
    
   
    在
    
     实验3: 拉普拉斯锐化
    
    中曾讨论过用差分定义的导数来表征和检测灰度的突变,同时得到了如下结论:
   
- 二阶导数仅在“灰度斜坡”的开始、结尾处不为零,一阶导数在整个“灰度斜坡”上均不为零,因此一阶导数产生的边缘粗于二阶导数
- 同时,二阶导数变化的激烈度明显高于一阶导数,因此二阶导数更能增强细节(包括噪声、孤立点、边缘等)
- 在“斜坡”和“台阶”边缘二阶导数的符号相反,导致了“双边缘效应”,也可用于确定边缘是从亮到暗过渡还是从暗到亮过渡
对于一条边缘来说,二阶导数具有如下性质:
- 对图像中的边缘,二阶导数生成两个值(双边缘效应)
- 二阶导数的零交叉点可用于定位粗边缘中心
     
   
     
   
    
    
    高斯低通滤波
   
不难证明,微弱的可见噪声会对边缘检测的上述两个关键导数产生严重影响,特别是对二阶偏导数的影响非常剧烈。所以在执行边缘检测前,需要对图像进行平滑处理(降噪)。
高斯滤波是一种线性平滑滤波,适用于消除高斯噪声,广泛应用于图像处理的减噪过程。通俗的讲,高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值经过加权平均后得到。
    二维高斯函数(
    
     
      
       μ 
=
0
        \mu=0
      
      
       
        
        
        
         μ
        
        
        
        
         =
        
        
        
       
       
        
        
        
         0
        
       
      
     
    
    , 中心点为原点)的定义如下:
   
    
     
      
       
        G 
(
x
,
y
)
=
e
−
x
2
+
y
2
2
σ
2
         G(x, y)=\mathrm{e}^{-\frac{x^{2}+y^{2}}{2 \sigma^{2}}}
       
       
        
         
         
         
          G
         
         
          (
         
         
          x
         
         
          ,
         
         
         
         
          y
         
         
          )
         
         
         
         
          =
         
         
         
        
        
         
         
         
          
           
            e
           
          
          
           
            
             
              
               
               
               
                
                 
                  −
                 
                 
                  
                  
                  
                   
                    
                     
                      
                       
                       
                       
                        
                         
                          2
                         
                         
                          
                           σ
                          
                          
                           
                            
                             
                              
                               
                               
                               
                                
                                 2
                                
                               
                              
                             
                            
                           
                          
                         
                        
                       
                      
                      
                       
                       
                       
                       
                      
                      
                       
                       
                       
                        
                         
                          
                           x
                          
                          
                           
                            
                             
                              
                               
                               
                               
                                
                                 2
                                
                               
                              
                             
                            
                           
                          
                         
                         
                          +
                         
                         
                          
                           y
                          
                          
                           
                            
                             
                              
                               
                               
                               
                                
                                 2
                                
                               
                              
                             
                            
                           
                          
                         
                        
                       
                      
                     
                     
                      
                     
                    
                    
                     
                      
                      
                     
                    
                   
                  
                  
                  
                 
                
               
              
             
            
           
          
         
        
       
      
     
    
   
注:
G(
x
,
y
)
G(x,y)
G
(
x
,
y
)
的系数
12
π
σ
2
\frac{1}{2\pi\sigma^2}
2
π
σ
2
1
可忽略,因为在计算得到权重矩阵后,还要对这个矩阵进行归一化。
    用
    
     
      
       G 
        G
      
      
       
        
        
        
         G
        
       
      
     
    
    和输入图像
    
     
      
       f 
        f
      
      
       
        
        
        
         f
        
       
      
     
    
    卷积形成平滑后的图像
    
     
      
       f 
s
        f_s
      
      
       
        
        
        
         
          f
         
         
          
           
            
             
              
              
              
               
                s
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
       
      
     
    
    :
   
    
     
      
       
        f 
s
(
x
,
y
)
=
G
(
x
,
y
)
∗
f
(
x
,
y
)
         f_s(x,y)=G(x,y)\ast f(x,y)
       
       
        
         
         
         
          
           f
          
          
           
            
             
              
               
               
               
                
                 s
                
               
              
             
             
              
             
            
            
             
              
              
             
            
           
          
         
         
          (
         
         
          x
         
         
          ,
         
         
         
         
          y
         
         
          )
         
         
         
         
          =
         
         
         
        
        
         
         
         
          G
         
         
          (
         
         
          x
         
         
          ,
         
         
         
         
          y
         
         
          )
         
         
         
         
          ∗
         
         
         
        
        
         
         
         
          f
         
         
          (
         
         
          x
         
         
          ,
         
         
         
         
          y
         
         
          )
         
        
       
      
     
    
   
    
    
    梯度和梯度方向
   
    为了在
    
     
      
       f 
        f
      
      
       
        
        
        
         f
        
       
      
     
    
    中寻找边缘的强度和方向,所以引入梯度
    
     
      
       ∇ 
f
        \nabla f
      
      
       
        
        
        
         ∇
        
        
         f
        
       
      
     
    
    ,定义如下:
   
    
     
      
       
        ∇ 
f
≡
grad
(
f
)
≡
[
g
x
g
y
]
=
[
∂
f
∂
x
∂
f
∂
y
]
         \nabla f \equiv \operatorname{grad}(f) \equiv\left[\begin{array}{l} g_{x} \\ g_{y} \end{array}\right]=\left[\begin{array}{l} \frac{\partial f}{\partial x} \\ \frac{\partial f}{\partial y} \end{array}\right]
       
       
        
         
         
         
          ∇
         
         
          f
         
         
         
         
          ≡
         
         
         
        
        
         
         
         
          
           g
          
          
           r
          
          
           a
          
          
           d
          
         
         
          (
         
         
          f
         
         
          )
         
         
         
         
          ≡
         
         
         
        
        
         
         
         
          
           
            [
           
          
          
           
            
            
            
             
              
               
                
                 
                 
                 
                  
                   
                    g
                   
                   
                    
                     
                      
                       
                        
                        
                        
                         
                          
                           x
                          
                         
                        
                       
                      
                      
                       
                      
                     
                     
                      
                       
                       
                      
                     
                    
                   
                  
                 
                
                
                 
                 
                 
                  
                   
                    g
                   
                   
                    
                     
                      
                       
                        
                        
                        
                         
                          
                           y
                          
                         
                        
                       
                      
                      
                       
                      
                     
                     
                      
                       
                       
                      
                     
                    
                   
                  
                 
                
               
               
                
               
              
              
               
                
                
               
              
             
            
            
            
           
          
          
           
            ]
           
          
         
         
         
         
          =
         
         
         
        
        
         
         
         
          
           
            [
           
          
          
           
            
            
            
             
              
               
                
                 
                 
                 
                  
                   
                   
                   
                    
                     
                      
                       
                        
                        
                        
                         
                          
                           ∂
                          
                          
                           x
                          
                         
                        
                       
                       
                        
                        
                        
                        
                       
                       
                        
                        
                        
                         
                          
                           ∂
                          
                          
                           f
                          
                         
                        
                       
                      
                      
                       
                      
                     
                     
                      
                       
                       
                      
                     
                    
                   
                   
                   
                  
                 
                
                
                 
                 
                 
                  
                   
                   
                   
                    
                     
                      
                       
                        
                        
                        
                         
                          
                           ∂
                          
                          
                           y
                          
                         
                        
                       
                       
                        
                        
                        
                        
                       
                       
                        
                        
                        
                         
                          
                           ∂
                          
                          
                           f
                          
                         
                        
                       
                      
                      
                       
                      
                     
                     
                      
                       
                       
                      
                     
                    
                   
                   
                   
                  
                 
                
               
               
                
               
              
              
               
                
                
               
              
             
            
            
            
           
          
          
           
            ]
           
          
         
        
       
      
     
    
   
    
     
      
       ∇ 
f
        \nabla f
      
      
       
        
        
        
         ∇
        
        
         f
        
       
      
     
    
    表征了
    
     
      
       f 
        f
      
      
       
        
        
        
         f
        
       
      
     
    
    在该点
    
     
      
       ( 
x
,
y
)
        (x,y)
      
      
       
        
        
        
         (
        
        
         x
        
        
         ,
        
        
        
        
         y
        
        
         )
        
       
      
     
    
    处最大变化率方向,其大小用
    
     
      
       M 
        M
      
      
       
        
        
        
         M
        
       
      
     
    
    表示,方向角用
    
     
      
       α 
        \alpha
      
      
       
        
        
        
         α
        
       
      
     
    
    表示(方向角是与以左上角为原点的坐标轴 x 轴之间的夹角):
   
    
     
      
       
        M 
(
x
,
y
)
=
g
x
2
+
g
y
2
         M(x, y)=\sqrt{g_{x}^{2}+g_{y}^{2}}
       
       
        
         
         
         
          M
         
         
          (
         
         
          x
         
         
          ,
         
         
         
         
          y
         
         
          )
         
         
         
         
          =
         
         
         
        
        
         
         
         
          
           
            
             
              
              
              
               
                
                 g
                
                
                 
                  
                   
                    
                     
                     
                     
                      
                       
                        x
                       
                      
                     
                    
                    
                     
                     
                     
                      
                       
                        2
                       
                      
                     
                    
                   
                   
                    
                   
                  
                  
                   
                    
                    
                   
                  
                 
                
               
               
               
               
                +
               
               
               
               
                
                 g
                
                
                 
                  
                   
                    
                     
                     
                     
                      
                       
                        y
                       
                      
                     
                    
                    
                     
                     
                     
                      
                       
                        2
                       
                      
                     
                    
                   
                   
                    
                   
                  
                  
                   
                    
                    
                   
                  
                 
                
               
              
             
             
              
              
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
       
      
     
    
   
    
     
      
       
        α 
(
x
,
y
)
=
arctan
[
g
y
g
x
]
         \alpha(x, y)=\arctan \left[\frac{g_{y}}{g_{x}}\right]
       
       
        
         
         
         
          α
         
         
          (
         
         
          x
         
         
          ,
         
         
         
         
          y
         
         
          )
         
         
         
         
          =
         
         
         
        
        
         
         
         
          arctan
         
         
         
         
          
           
            [
           
          
          
           
           
           
            
             
              
               
                
                
                
                 
                  
                   g
                  
                  
                   
                    
                     
                      
                       
                       
                       
                        
                         
                          x
                         
                        
                       
                      
                     
                     
                      
                     
                    
                    
                     
                      
                      
                     
                    
                   
                  
                 
                
               
               
                
                
                
                
               
               
                
                
                
                 
                  
                   g
                  
                  
                   
                    
                     
                      
                       
                       
                       
                        
                         
                          y
                         
                        
                       
                      
                     
                     
                      
                     
                    
                    
                     
                      
                      
                     
                    
                   
                  
                 
                
               
              
              
               
              
             
             
              
               
               
              
             
            
           
           
           
          
          
           
            ]
           
          
         
        
       
      
     
    
   
    
     
      
       M 
(
x
,
y
)
        M(x,y)
      
      
       
        
        
        
         M
        
        
         (
        
        
         x
        
        
         ,
        
        
        
        
         y
        
        
         )
        
       
      
     
    
    、
    
     
      
       α 
(
x
,
y
)
        \alpha (x,y)
      
      
       
        
        
        
         α
        
        
         (
        
        
         x
        
        
         ,
        
        
        
        
         y
        
        
         )
        
       
      
     
    
    和
    
     
      
       f 
        f
      
      
       
        
        
        
         f
        
       
      
     
    
    的尺寸相同,
    
     
      
       ∇ 
f
        \nabla f
      
      
       
        
        
        
         ∇
        
        
         f
        
       
      
     
    
    和该点处的边缘正交,故梯度向量也称边缘法线。
   
    通过
    
     
      
       M 
(
x
,
y
)
        M(x,y)
      
      
       
        
        
        
         M
        
        
         (
        
        
         x
        
        
         ,
        
        
        
        
         y
        
        
         )
        
       
      
     
    
    和
    
     
      
       α 
(
x
,
y
)
        \alpha (x,y)
      
      
       
        
        
        
         α
        
        
         (
        
        
         x
        
        
         ,
        
        
        
        
         y
        
        
         )
        
       
      
     
    
    ,可以分别构造梯度幅值矩阵和方向矩阵。梯度幅值矩阵是梯度的大小,表征了边缘的强度。而梯度方向矩阵则表征了梯度的方向。但是在计算
    
     
      
       M 
(
x
,
y
)
        M(x,y)
      
      
       
        
        
        
         M
        
        
         (
        
        
         x
        
        
         ,
        
        
        
        
         y
        
        
         )
        
       
      
     
    
    时,涉及平方和平方根操作,计算开销大,所以经常使用绝对值来近似梯度幅值:
   
    
     
      
       
        M 
(
x
,
y
)
≈
∣
g
x
∣
+
∣
g
y
∣
         M(x, y) \approx\left|g_{x}\right|+\left|g_{y}\right|
       
       
        
         
         
         
          M
         
         
          (
         
         
          x
         
         
          ,
         
         
         
         
          y
         
         
          )
         
         
         
         
          ≈
         
         
         
        
        
         
         
         
          
           ∣
          
          
           
            g
           
           
            
             
              
               
                
                
                
                 
                  
                   x
                  
                 
                
               
              
              
               
              
             
             
              
               
               
              
             
            
           
          
          
           ∣
          
         
         
         
         
          +
         
         
         
        
        
         
         
         
          
           ∣
          
          
           
            g
           
           
            
             
              
               
                
                
                
                 
                  
                   y
                  
                 
                
               
              
              
               
              
             
             
              
               
               
              
             
            
           
          
          
           ∣
          
         
        
       
      
     
    
   
    
    
    Sobel算子
   
    梯度中偏导数
    
     
      
       g 
x
        g_x
      
      
       
        
        
        
         
          g
         
         
          
           
            
             
              
              
              
               
                x
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
       
      
     
    
    、
    
     
      
       g 
y
        g_y
      
      
       
        
        
        
         
          g
         
         
          
           
            
             
              
              
              
               
                y
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
       
      
     
    
    的计算需要使用模版(算子)对
    
     
      
       f 
        f
      
      
       
        
        
        
         f
        
       
      
     
    
    进行滤波。
   
    一维模版对x方向、y方向分别求偏导数,即求x方向、y方向的边缘,但未考虑对角线方向的偏导数。Roberts[1965]交叉梯度算子以求对角像素(
    
     
      
       4 
5
∘
,
−
4
5
∘
        45^\circ,-45^\circ
      
      
       
        
        
        
         4
        
        
         
          5
         
         
          
           
            
             
              
              
              
               
                ∘
               
              
             
            
           
          
         
        
        
         ,
        
        
        
        
         −
        
        
         4
        
        
         
          5
         
         
          
           
            
             
              
              
              
               
                ∘
               
              
             
            
           
          
         
        
       
      
     
    
    )之差为基础,但
    
     
      
       2 
×
2
        2\times 2
      
      
       
        
        
        
         2
        
        
        
        
         ×
        
        
        
       
       
        
        
        
         2
        
       
      
     
    
    大小的模版对于用关于中心点对称的模版来计算边缘方向不是很有用,为了考虑中心点对称数据的性质、并携带有关边缘方向的更多信息,Prewitt[1970] 算子被提出:
   
    
     
      
       
        P 
r
e
w
i
t
t
x
=
[
−
1
−
1
−
1
0
0
0
1
1
1
]
,
P
r
e
w
i
t
t
y
=
[
−
1
0
1
−
1
0
1
−
1
0
1
]
         Prewitt_x = \begin{bmatrix} -1 & -1 & -1 \\ 0 & 0 & 0 \\ 1 & 1 & 1 \end{bmatrix}, Prewitt_y = \begin{bmatrix} -1 & 0 & 1 \\ -1 & 0 & 1 \\ -1 & 0 & 1 \end{bmatrix}
       
       
        
         
         
         
          P
         
         
          r
         
         
          e
         
         
          w
         
         
          i
         
         
          t
         
         
          
           t
          
          
           
            
             
              
               
               
               
                
                 x
                
               
              
             
             
              
             
            
            
             
              
              
             
            
           
          
         
         
         
         
          =
         
         
         
        
        
         
         
         
          
           
            
             
              
               
                
                
                
                 
                  ⎣
                 
                
               
               
                
                
                
                 
                  ⎡
                 
                
               
              
              
               
              
             
             
              
               
               
              
             
            
           
          
          
           
            
             
              
               
                
                 
                 
                 
                  
                   −
                  
                  
                   1
                  
                 
                
                
                 
                 
                 
                  
                   0
                  
                 
                
                
                 
                 
                 
                  
                   1
                  
                 
                
               
               
                
               
              
              
               
                
                
               
              
             
            
            
            
            
            
            
             
              
               
                
                 
                 
                 
                  
                   −
                  
                  
                   1
                  
                 
                
                
                 
                 
                 
                  
                   0
                  
                 
                
                
                 
                 
                 
                  
                   1
                  
                 
                
               
               
                
               
              
              
               
                
                
               
              
             
            
            
            
            
            
            
             
              
               
                
                 
                 
                 
                  
                   −
                  
                  
                   1
                  
                 
                
                
                 
                 
                 
                  
                   0
                  
                 
                
                
                 
                 
                 
                  
                   1
                  
                 
                
               
               
                
               
              
              
               
                
                
               
              
             
            
           
          
          
           
            
             
              
               
                
                
                
                 
                  ⎦
                 
                
               
               
                
                
                
                 
                  ⎤
                 
                
               
              
              
               
              
             
             
              
               
               
              
             
            
           
          
         
         
         
         
          ,
         
         
         
         
          P
         
         
          r
         
         
          e
         
         
          w
         
         
          i
         
         
          t
         
         
          
           t
          
          
           
            
             
              
               
               
               
                
                 y
                
               
              
             
             
              
             
            
            
             
              
              
             
            
           
          
         
         
         
         
          =
         
         
         
        
        
         
         
         
          
           
            
             
              
               
                
                
                
                 
                  ⎣
                 
                
               
               
                
                
                
                 
                  ⎡
                 
                
               
              
              
               
              
             
             
              
               
               
              
             
            
           
          
          
           
            
             
              
               
                
                 
                 
                 
                  
                   −
                  
                  
                   1
                  
                 
                
                
                 
                 
                 
                  
                   −
                  
                  
                   1
                  
                 
                
                
                 
                 
                 
                  
                   −
                  
                  
                   1
                  
                 
                
               
               
                
               
              
              
               
                
                
               
              
             
            
            
            
            
            
            
             
              
               
                
                 
                 
                 
                  
                   0
                  
                 
                
                
                 
                 
                 
                  
                   0
                  
                 
                
                
                 
                 
                 
                  
                   0
                  
                 
                
               
               
                
               
              
              
               
                
                
               
              
             
            
            
            
            
            
            
             
              
               
                
                 
                 
                 
                  
                   1
                  
                 
                
                
                 
                 
                 
                  
                   1
                  
                 
                
                
                 
                 
                 
                  
                   1
                  
                 
                
               
               
                
               
              
              
               
                
                
               
              
             
            
           
          
          
           
            
             
              
               
                
                
                
                 
                  ⎦
                 
                
               
               
                
                
                
                 
                  ⎤
                 
                
               
              
              
               
              
             
             
              
               
               
              
             
            
           
          
         
        
       
      
     
    
   
    索贝尔算子(Sobel operator)[1970]主要用作边缘检测,本质上是
    
     一阶离散性差分算子
    
    ,用来计算图像亮度函数的偏导数的近似值,因为它可以反应出灰度值剧烈变化的区域,而平滑灰度值变化缓慢的区域。Sobel 算子在中心位置使用 2 以平滑图像,更好的抑制噪声,Sobel 算子如下:
   
    
     
      
       
        S 
o
b
e
l
x
=
[
−
1
−
2
−
1
0
0
0
1
2
1
]
,
S
o
b
e
l
y
=
[
−
1
0
1
−
2
0
2
−
1
0
1
]
         Sobel_x = \begin{bmatrix} -1 & -2 & -1 \\ 0 & 0 & 0 \\ 1 & 2 & 1 \end{bmatrix}, Sobel_y = \begin{bmatrix} -1 & 0 & 1 \\ -2 & 0 & 2 \\ -1 & 0 & 1 \end{bmatrix}
       
       
        
         
         
         
          S
         
         
          o
         
         
          b
         
         
          e
         
         
          
           l
          
          
           
            
             
              
               
               
               
                
                 x
                
               
              
             
             
              
             
            
            
             
              
              
             
            
           
          
         
         
         
         
          =
         
         
         
        
        
         
         
         
          
           
            
             
              
               
                
                
                
                 
                  ⎣
                 
                
               
               
                
                
                
                 
                  ⎡
                 
                
               
              
              
               
              
             
             
              
               
               
              
             
            
           
          
          
           
            
             
              
               
                
                 
                 
                 
                  
                   −
                  
                  
                   1
                  
                 
                
                
                 
                 
                 
                  
                   0
                  
                 
                
                
                 
                 
                 
                  
                   1
                  
                 
                
               
               
                
               
              
              
               
                
                
               
              
             
            
            
            
            
            
            
             
              
               
                
                 
                 
                 
                  
                   −
                  
                  
                   2
                  
                 
                
                
                 
                 
                 
                  
                   0
                  
                 
                
                
                 
                 
                 
                  
                   2
                  
                 
                
               
               
                
               
              
              
               
                
                
               
              
             
            
            
            
            
            
            
             
              
               
                
                 
                 
                 
                  
                   −
                  
                  
                   1
                  
                 
                
                
                 
                 
                 
                  
                   0
                  
                 
                
                
                 
                 
                 
                  
                   1
                  
                 
                
               
               
                
               
              
              
               
                
                
               
              
             
            
           
          
          
           
            
             
              
               
                
                
                
                 
                  ⎦
                 
                
               
               
                
                
                
                 
                  ⎤
                 
                
               
              
              
               
              
             
             
              
               
               
              
             
            
           
          
         
         
         
         
          ,
         
         
         
         
          S
         
         
          o
         
         
          b
         
         
          e
         
         
          
           l
          
          
           
            
             
              
               
               
               
                
                 y
                
               
              
             
             
              
             
            
            
             
              
              
             
            
           
          
         
         
         
         
          =
         
         
         
        
        
         
         
         
          
           
            
             
              
               
                
                
                
                 
                  ⎣
                 
                
               
               
                
                
                
                 
                  ⎡
                 
                
               
              
              
               
              
             
             
              
               
               
              
             
            
           
          
          
           
            
             
              
               
                
                 
                 
                 
                  
                   −
                  
                  
                   1
                  
                 
                
                
                 
                 
                 
                  
                   −
                  
                  
                   2
                  
                 
                
                
                 
                 
                 
                  
                   −
                  
                  
                   1
                  
                 
                
               
               
                
               
              
              
               
                
                
               
              
             
            
            
            
            
            
            
             
              
               
                
                 
                 
                 
                  
                   0
                  
                 
                
                
                 
                 
                 
                  
                   0
                  
                 
                
                
                 
                 
                 
                  
                   0
                  
                 
                
               
               
                
               
              
              
               
                
                
               
              
             
            
            
            
            
            
            
             
              
               
                
                 
                 
                 
                  
                   1
                  
                 
                
                
                 
                 
                 
                  
                   2
                  
                 
                
                
                 
                 
                 
                  
                   1
                  
                 
                
               
               
                
               
              
              
               
                
                
               
              
             
            
           
          
          
           
            
             
              
               
                
                
                
                 
                  ⎦
                 
                
               
               
                
                
                
                 
                  ⎤
                 
                
               
              
              
               
              
             
             
              
               
               
              
             
            
           
          
         
        
       
      
     
    
   
那么,
    
     
      
       
        G 
x
=
S
o
b
e
l
x
∗
f
s
,
G
y
=
S
o
b
e
l
y
∗
f
s
         G_x=Sobel_x\ast f_s\ ,\ G_y=Sobel_y\ast f_s
       
       
        
         
         
         
          
           G
          
          
           
            
             
              
               
               
               
                
                 x
                
               
              
             
             
              
             
            
            
             
              
              
             
            
           
          
         
         
         
         
          =
         
         
         
        
        
         
         
         
          S
         
         
          o
         
         
          b
         
         
          e
         
         
          
           l
          
          
           
            
             
              
               
               
               
                
                 x
                
               
              
             
             
              
             
            
            
             
              
              
             
            
           
          
         
         
         
         
          ∗
         
         
         
        
        
         
         
         
          
           f
          
          
           
            
             
              
               
               
               
                
                 s
                
               
              
             
             
              
             
            
            
             
              
              
             
            
           
          
         
         
         
         
          ,
         
         
         
         
         
         
          
           G
          
          
           
            
             
              
               
               
               
                
                 y
                
               
              
             
             
              
             
            
            
             
              
              
             
            
           
          
         
         
         
         
          =
         
         
         
        
        
         
         
         
          S
         
         
          o
         
         
          b
         
         
          e
         
         
          
           l
          
          
           
            
             
              
               
               
               
                
                 y
                
               
              
             
             
              
             
            
            
             
              
              
             
            
           
          
         
         
         
         
          ∗
         
         
         
        
        
         
         
         
          
           f
          
          
           
            
             
              
               
               
               
                
                 s
                
               
              
             
             
              
             
            
            
             
              
              
             
            
           
          
         
        
       
      
     
    
   
    
     
      
       
        M 
=
G
x
2
+
G
y
2
         M=\sqrt{G_{x}^{2}+G_{y}^{2}}
       
       
        
         
         
         
          M
         
         
         
         
          =
         
         
         
        
        
         
         
         
          
           
            
             
              
              
              
               
                
                 G
                
                
                 
                  
                   
                    
                     
                     
                     
                      
                       
                        x
                       
                      
                     
                    
                    
                     
                     
                     
                      
                       
                        2
                       
                      
                     
                    
                   
                   
                    
                   
                  
                  
                   
                    
                    
                   
                  
                 
                
               
               
               
               
                +
               
               
               
               
                
                 G
                
                
                 
                  
                   
                    
                     
                     
                     
                      
                       
                        y
                       
                      
                     
                    
                    
                     
                     
                     
                      
                       
                        2
                       
                      
                     
                    
                   
                   
                    
                   
                  
                  
                   
                    
                    
                   
                  
                 
                
               
              
             
             
              
              
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
       
      
     
    
   
    
     
      
       
        α 
=
arctan
[
G
y
G
x
]
         \alpha=\arctan \left[\frac{G_{y}}{G_{x}}\right]
       
       
        
         
         
         
          α
         
         
         
         
          =
         
         
         
        
        
         
         
         
          arctan
         
         
         
         
          
           
            [
           
          
          
           
           
           
            
             
              
               
                
                
                
                 
                  
                   G
                  
                  
                   
                    
                     
                      
                       
                       
                       
                        
                         
                          x
                         
                        
                       
                      
                     
                     
                      
                     
                    
                    
                     
                      
                      
                     
                    
                   
                  
                 
                
               
               
                
                
                
                
               
               
                
                
                
                 
                  
                   G
                  
                  
                   
                    
                     
                      
                       
                       
                       
                        
                         
                          y
                         
                        
                       
                      
                     
                     
                      
                     
                    
                    
                     
                      
                      
                     
                    
                   
                  
                 
                
               
              
              
               
              
             
             
              
               
               
              
             
            
           
           
           
          
          
           
            ]
           
          
         
        
       
      
     
    
   
    
    
    梯度阈值处理
   
为了减小噪声对梯度幅值矩阵的影响,即可以在计算梯度前,对图像进行低通滤波(平滑),也可以在计算梯度后,对梯度图像进行阈值处理,可以设置大于或等于梯度图像的最大值的 xx% 的像素显示为白色,而低于该阈值的像素则显示为黑色,以减小噪声的影响。但是,在阈值处理后,可能会导致部分边缘的断线。
    
    
    Canny边缘检测核心思想
   
    在Canny[1968]之前,Marr和Hildreth[1980]就用高斯拉普拉斯(LoG)函数生成模版来进行边缘检测,他们论证了滤波器
    
     
      
       ∇ 
2
G
        \nabla ^2G
      
      
       
        
        
        
         
          ∇
         
         
          
           
            
             
              
              
              
               
                2
               
              
             
            
           
          
         
        
        
         G
        
       
      
     
    
    的有效性。
   
Canny的三个目标:
- 低错误率。所有边缘都应被找到,并且没有伪响应;
- 边缘点被很好地定位。由检测器标记为边缘的点和真实边缘的中心之间的距离尽可能小;
- 单一的边缘点响应。对于真实的边缘点,检测器仅返回一个点,对于仅存一个单一边缘点的位置,检测器不应指出多个边缘像素
Canny基本步骤:
- 高斯滤波平滑输入图像
- 计算梯度幅值图像和角度图像
- 对梯度幅值图像应用非最大抑制(NMS)
- 双阈值处理,划分强、弱边缘
- 滞后边界跟踪,消除干扰(孤立弱边缘)
    
    
    NMS
   
    非最大值抑制(NMS)可以细化得到的边缘(梯度幅值),该方法本质上将边缘按梯度方向的范围进行离散化,定义了四个离散方向,分别是水平、垂直、
    
     
      
       4 
5
∘
        45^\circ
      
      
       
        
        
        
         4
        
        
         
          5
         
         
          
           
            
             
              
              
              
               
                ∘
               
              
             
            
           
          
         
        
       
      
     
    
    、
    
     
      
       − 
4
5
∘
        -45^\circ
      
      
       
        
        
        
         −
        
        
         4
        
        
         
          5
         
         
          
           
            
             
              
              
              
               
                ∘
               
              
             
            
           
          
         
        
       
      
     
    
    . 以梯度幅值矩阵上每个点为中心,寻找其对于梯度方向最靠近的离散方向,若
    
     
      
       M 
(
x
,
y
)
        M(x,y)
      
      
       
        
        
        
         M
        
        
         (
        
        
         x
        
        
         ,
        
        
        
        
         y
        
        
         )
        
       
      
     
    
    至少小于沿该方向的两个邻居之一,则抑制(
    
     
      
       g 
N
(
x
,
y
)
=
0
        g_N(x,y)=0
      
      
       
        
        
        
         
          g
         
         
          
           
            
             
              
              
              
               
                N
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
        
         (
        
        
         x
        
        
         ,
        
        
        
        
         y
        
        
         )
        
        
        
        
         =
        
        
        
       
       
        
        
        
         0
        
       
      
     
    
    ),否则
    
     
      
       g 
N
(
x
,
y
)
=
M
(
x
,
y
)
        g_N(x,y)=M(x,y)
      
      
       
        
        
        
         
          g
         
         
          
           
            
             
              
              
              
               
                N
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
        
         (
        
        
         x
        
        
         ,
        
        
        
        
         y
        
        
         )
        
        
        
        
         =
        
        
        
       
       
        
        
        
         M
        
        
         (
        
        
         x
        
        
         ,
        
        
        
        
         y
        
        
         )
        
       
      
     
    
    .
   
NMS 的本质是对各点的由边缘法线确定的边缘进行细化,在该点处边缘的两侧和中心选取最大值,其余相邻像素位置零。
注意,查阅资料得知,NMS 也可以使用插值方法来精确计算,这里就用本书中提到的方法进行近似计算。
     
   
    
    
    双阈值处理
   
    最后对
    
     
      
       g 
N
        g_N
      
      
       
        
        
        
         
          g
         
         
          
           
            
             
              
              
              
               
                N
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
       
      
     
    
    进行双阈值处理,以减少伪边缘点(噪声)。
   
在用梯度幅值表征边缘时,用单阈值处理梯度幅值,若阈值过低,则会存在一些伪边缘,若阈值过高,则会删除有效边缘点,造成断线。
    改进方式是设置两个阈值:
    
     
      
       L 
T
        L_T
      
      
       
        
        
        
         
          L
         
         
          
           
            
             
              
              
              
               
                T
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
       
      
     
    
    和
    
     
      
       H 
T
        H_T
      
      
       
        
        
        
         
          H
         
         
          
           
            
             
              
              
              
               
                T
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
       
      
     
    
    .
   
创建高、低阈值图像:
    
     
      
       
        g 
N
H
(
x
,
y
)
=
g
N
(
x
,
y
)
≥
T
H
         g_{N H}(x, y)=g_{N}(x, y) \ge T_{H}
       
       
        
         
         
         
          
           g
          
          
           
            
             
              
               
               
               
                
                 
                  N
                 
                 
                  H
                 
                
               
              
             
             
              
             
            
            
             
              
              
             
            
           
          
         
         
          (
         
         
          x
         
         
          ,
         
         
         
         
          y
         
         
          )
         
         
         
         
          =
         
         
         
        
        
         
         
         
          
           g
          
          
           
            
             
              
               
               
               
                
                 
                  N
                 
                
               
              
             
             
              
             
            
            
             
              
              
             
            
           
          
         
         
          (
         
         
          x
         
         
          ,
         
         
         
         
          y
         
         
          )
         
         
         
         
          ≥
         
         
         
        
        
         
         
         
          
           T
          
          
           
            
             
              
               
               
               
                
                 
                  H
                 
                
               
              
             
             
              
             
            
            
             
              
              
             
            
           
          
         
        
       
      
     
    
   
    
     
      
       
        g 
N
L
(
x
,
y
)
=
g
N
(
x
,
y
)
≥
T
L
         g_{N L}(x, y)=g_{N}(x, y) \geq T_{L}
       
       
        
         
         
         
          
           g
          
          
           
            
             
              
               
               
               
                
                 
                  N
                 
                 
                  L
                 
                
               
              
             
             
              
             
            
            
             
              
              
             
            
           
          
         
         
          (
         
         
          x
         
         
          ,
         
         
         
         
          y
         
         
          )
         
         
         
         
          =
         
         
         
        
        
         
         
         
          
           g
          
          
           
            
             
              
               
               
               
                
                 
                  N
                 
                
               
              
             
             
              
             
            
            
             
              
              
             
            
           
          
         
         
          (
         
         
          x
         
         
          ,
         
         
         
         
          y
         
         
          )
         
         
         
         
          ≥
         
         
         
        
        
         
         
         
          
           T
          
          
           
            
             
              
               
               
               
                
                 
                  L
                 
                
               
              
             
             
              
             
            
            
             
              
              
             
            
           
          
         
        
       
      
     
    
   
    此时,
    
     
      
       g 
N
H
        g_{N H}
      
      
       
        
        
        
         
          g
         
         
          
           
            
             
              
              
              
               
                
                 N
                
                
                 H
                
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
       
      
     
    
    中的所有非零像素都包含在
    
     
      
       g 
N
L
        g_{N L}
      
      
       
        
        
        
         
          g
         
         
          
           
            
             
              
              
              
               
                
                 N
                
                
                 L
                
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
       
      
     
    
    中,则做如下运算得到“纯净的”
    
     
      
       g 
N
L
        g_{N L}
      
      
       
        
        
        
         
          g
         
         
          
           
            
             
              
              
              
               
                
                 N
                
                
                 L
                
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
       
      
     
    
    (其像素点的灰度值在两阈值之间):
   
    
     
      
       
        g 
N
L
(
x
,
y
)
=
g
N
L
(
x
,
y
)
−
g
N
H
(
x
,
y
)
         g_{N L}(x, y)=g_{N L}(x, y)-g_{N H}(x, y)
       
       
        
         
         
         
          
           g
          
          
           
            
             
              
               
               
               
                
                 
                  N
                 
                 
                  L
                 
                
               
              
             
             
              
             
            
            
             
              
              
             
            
           
          
         
         
          (
         
         
          x
         
         
          ,
         
         
         
         
          y
         
         
          )
         
         
         
         
          =
         
         
         
        
        
         
         
         
          
           g
          
          
           
            
             
              
               
               
               
                
                 
                  N
                 
                 
                  L
                 
                
               
              
             
             
              
             
            
            
             
              
              
             
            
           
          
         
         
          (
         
         
          x
         
         
          ,
         
         
         
         
          y
         
         
          )
         
         
         
         
          −
         
         
         
        
        
         
         
         
          
           g
          
          
           
            
             
              
               
               
               
                
                 
                  N
                 
                 
                  H
                 
                
               
              
             
             
              
             
            
            
             
              
              
             
            
           
          
         
         
          (
         
         
          x
         
         
          ,
         
         
         
         
          y
         
         
          )
         
        
       
      
     
    
   
    
     
      
       g 
N
H
        g_{N H}
      
      
       
        
        
        
         
          g
         
         
          
           
            
             
              
              
              
               
                
                 N
                
                
                 H
                
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
       
      
     
    
    中的所有强像素均被认定为有效边缘像素,立即标记。而由于
    
     
      
       T 
H
        T_H
      
      
       
        
        
        
         
          T
         
         
          
           
            
             
              
              
              
               
                H
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
       
      
     
    
    通常较大,故
    
     
      
       g 
N
H
        g_{N H}
      
      
       
        
        
        
         
          g
         
         
          
           
            
             
              
              
              
               
                
                 N
                
                
                 H
                
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
       
      
     
    
    中的边缘会有缝隙。
   
    
    
    滞后边界跟踪
   
弱边缘点则可能是真的边缘,也可能是噪声或颜色变化引起的。为得到精确的结果,后者引起的弱边缘点应该去掉。通常认为真实边缘引起的弱边缘点和强边缘点是连通的,而噪声引起的弱边缘点则不会。
滞后边界跟踪算法检查一个弱边缘点的 8 连通领域像素,只要有强边缘点存在,那么这个弱边缘点被认为是真是边缘保留下来。
这个算法搜索所有连通的弱边缘,如果一条连通的弱边缘的任何一个点和强边缘点连通,则保留这条弱边缘,否则抑制这条弱边缘。搜索时可以用广度优先或者深度优先算法。
算法说明如下:
- 
     输入:图像,计算其
 
 
 
 gN L , g N H g_{NL},g_{NH} 
 
 
 
 
 
 
 
 g
 
 
 
 
 
 
 
 
 
 
 
 N
 
 
 L
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 ,
 
 
 
 
 
 g
 
 
 
 
 
 
 
 
 
 
 
 N
 
 
 H
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
- 
     建立
 
 visited
 
 矩阵(和输入图像同形),表征每个像素是否在 DFS 中被访问,初始化该矩阵为零矩阵
- 
     建立
 
 gnl_filtered
 
 矩阵,表征
 
 
 
 gN L g_{NL} 
 
 
 
 
 
 
 
 g
 
 
 
 
 
 
 
 
 
 
 
 N
 
 
 L
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 中连通的弱边缘,且该弱边缘也和
 
 
 
 gN H g_{NH} 
 
 
 
 
 
 
 
 g
 
 
 
 
 
 
 
 
 
 
 
 N
 
 
 H
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 中任意强边缘连通,即过滤调不符合条件的弱边缘后所剩下的符合条件的弱边缘(被认为是真边缘)。初始化该矩阵为零矩阵,不符合条件的弱边缘被抑制(置零)
- 
     从上到下,自左向右,遍历所有强边缘
 
 
 
 gN H g_{NH} 
 
 
 
 
 
 
 
 g
 
 
 
 
 
 
 
 
 
 
 
 N
 
 
 H
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 ,若该像素已经被访问,则继续访问访问下一个像素,直到所有强边缘都被访问。若像素未被访问,进入 DFS.
- 
     DFS 中,搜索该强边缘的连通弱边缘。先标记该点已被访问,如果该点的
 
 
 
 gN L ( x , y ) > 0 g_{NL}(x,y)\gt 0 
 
 
 
 
 
 
 
 g
 
 
 
 
 
 
 
 
 
 
 
 N
 
 
 L
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 (
 
 
 x
 
 
 ,
 
 
 
 
 y
 
 
 )
 
 
 
 
 >
 
 
 
 
 
 
 
 
 0
 
 
 
 
 
 ,即该点是弱边缘,将
 
 gnl_filtered
 
 对应位置改为该点的灰度值(弱边缘符合条件保留),再一次递归搜索该点的8领域(寻找连通弱边缘)。DFS 的退出条件为已被标记(即
 
 visited
 
 矩阵对应位置为True)或访问的点超出边界。
- 输出:经过双阈值处理的强边缘矩阵、弱边缘矩阵,滞后边界跟踪的连通弱边缘矩阵
之后可对该灰度图像进行二值化并展示。
    
    
    编码实现和结果分析
   
import cv2
import numpy as np
import matplotlib.pyplot as plt
img0 = 'house.tif'
f = cv2.imread(img0, cv2.IMREAD_GRAYSCALE)
plt.imshow(f, cmap='gray')
plt.show()
     
   
def gauss_seperate_kernel(kernel_size, sigma=1):
    """
    create gaussian kernel use separable vector, because gaussian kernel is symmetric and separable.
    param: kernel_size: input, the kernel size you want to create, normally is uneven number, such as 1, 3, 5, 7
    param: sigma: input, sigma of the gaussian function, default is 1
    return a desired size 2D gaussian kernel
    """
    m = kernel_size[0]
    n = kernel_size[1]
    x_m = np.arange(m) - m // 2
    y_m = np.exp(-(x_m ** 2) / (2 * sigma ** 2)).reshape(-1, 1)
    x_n = np.arange(n) - n // 2
    y_n = np.exp(-(x_n ** 2) / (2 * sigma ** 2)).reshape(-1, 1)
    kernel = y_m * y_n.T
    return kernel
n = 3  # gauss kernel size
sigma = 1  # sigma of the gaussian function
gauss_kernel = gauss_seperate_kernel((n, n), sigma=sigma)
fs = cv2.filter2D(f, ddepth=cv2.CV_32FC1, kernel=gauss_kernel, borderType=cv2.BORDER_DEFAULT)
plt.imshow(fs, cmap='gray')
plt.show()
     
   
sobelx = [[-1, -2, -1], [0, 0, 0], [1, 2, 1]]
sobelx = np.asarray(sobelx)
sobely = sobelx.T
Gx = cv2.filter2D(fs, -1, kernel=sobelx, borderType=cv2.BORDER_DEFAULT)
Gy = cv2.filter2D(fs, -1, kernel=sobely, borderType=cv2.BORDER_DEFAULT)
fig, axs = plt.subplots(1, 2, figsize=(10, 5))
axs[0].set_title('Gx')
axs[0].imshow(Gx, cmap='gray')
axs[1].set_title('Gy')
axs[1].imshow(Gy, cmap='gray')
plt.show()
     
   
    很明显,
    
     
      
       G 
x
        G_x
      
      
       
        
        
        
         
          G
         
         
          
           
            
             
              
              
              
               
                x
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
       
      
     
    
    表征
    
     
      
       x 
        x
      
      
       
        
        
        
         x
        
       
      
     
    
    方向上的边界,
    
     
      
       G 
y
        G_y
      
      
       
        
        
        
         
          G
         
         
          
           
            
             
              
              
              
               
                y
               
              
             
            
            
             
            
           
           
            
             
             
            
           
          
         
        
       
      
     
    
    表征
    
     
      
       y 
        y
      
      
       
        
        
        
         y
        
       
      
     
    
    方向上的边界.
   
M = np.sqrt(np.square(Gx) + np.square(Gy))
alpha = np.arctan(np.divide(Gy, Gx, where=Gx!=0))
fig, axs = plt.subplots(1, 2, figsize=(10, 5))
axs[0].set_title('M')
axs[0].imshow(M, cmap='gray')
axs[1].set_title(r'\alpha')
axs[1].imshow(alpha, cmap='gray')
plt.show()
     
   
左图为梯度幅值,右图为梯度方向。
梯度幅值表征了边缘强度,梯度方向较好地识别了背景和房子,背景的梯度方向一致。
t = .33 # single threshold
Mt = M.copy()
Mt[Mt < t * np.max(Mt)] = np.min(Mt)
plt.imshow(Mt, cmap='gray')
plt.show()
     
   
可以看到,用单阈值直接处理梯度赋值图像得到的边缘中,一部分砖瓦的缝隙(我们不希望的)消失了,但也造成了部分边缘断线,且此时边缘仍然较粗。
def NMS(gradients, direction):
    """ Non-maxima suppression
    Args:
        gradients: the gradients of each pixel
        direction: the direction of the gradients of each pixel
    Returns:
        the output image
    """
    W, H = gradients.shape
    nms = np.copy(gradients)
    for i in range(1, W - 1):
        for j in range(1, H - 1):
            theta = direction[i, j]
            if np.abs(theta) < np.pi / 8:
                d = [0, 1]  # d1
            elif np.abs(theta) > np.pi * 3 / 8:
                d = [1, 0]  # d3
            elif np.pi / 8 <= theta:
                d = [1, 1]  # d2
            else:
                d = [1, -1]  # d4
            g1 = gradients[i + d[0], j + d[1]]
            g2 = gradients[i - d[0], j - d[1]]
            if g1 > gradients[i, j] or g2 > gradients[i, j]:
                nms[i, j] = 0
    return nms
Mn = NMS(M, alpha)
# binarization
Mn_b = np.copy(Mn)
threshold = 0.3 * np.max(Mn_b)
Mn_b[Mn_b < threshold] = 0
Mn_b[Mn_b >= threshold] = 1
fig, axs = plt.subplots(1, 2, figsize=(10, 5))
axs[0].set_title('Mn')
axs[0].imshow(Mn, cmap='gray')
axs[1].set_title('Mn_binarized')
axs[1].imshow(Mn_b, cmap='gray')
plt.show()
     
   
上图为经过 NMS 后的边缘梯度图像,边缘被细化了。接下来进行双阈值处理和滞后边缘跟踪,进一步细化边缘。
def double_threshold(gn, tl, th):
    """ Double Threshold
    Use two thresholds to compute the edge.
    Args:
        gn: the input image
        tl: the low threshold
        th: the high threshold
    Returns:
        gnh, gnl, and true_gnl
    """
    gnh, gnl = np.copy(gn), np.copy(gn)
    tl = np.max(gn) * tl
    th = np.max(gn) * th
    gnh[gnh < th] = .0
    gnl[gnl < tl] = .0
    gnl = gnl - gnh
    visited = np.zeros_like(gn)
    gnl_filtered = np.zeros_like(gn).astype('float')
    W, H = gn.shape
    def dfs(i, j):
        if i >= W or i < 0 or j >= H or j < 0 or visited[i, j] == 1:
            return
        visited[i, j] = 1
        if gnl[i, j] > 0 or gnh[i, j] > 0:
            gnl_filtered[i, j] = gnl[i, j]
            dfs(i - 1, j - 1)
            dfs(i - 1, j)
            dfs(i - 1, j + 1)
            dfs(i, j - 1)
            dfs(i, j + 1)
            dfs(i + 1, j - 1)
            dfs(i + 1, j)
            dfs(i + 1, j + 1)
    for w in range(W):
        for h in range(H):
            if visited[w, h] == 1:
                continue
            if gnh[w, h] > 0:
                dfs(w, h)
    return gnh, gnl, gnl_filtered
def draw_double_threshold(gn, tl, th):
    """
    draw result pictures
    :return: gNH_b+gNL_true_b
    """
    gNH, gNL, gNL_true = double_threshold(gn=gn, tl=tl, th=th)
    gNH_b = gNH.copy()
    gNL_b = gNL.copy()
    gNL_true_b = gNL_true.copy()
    gNH_b[gNH_b > 0] = np.max(gNH_b)
    gNL_b[gNL_b > 0] = np.max(gNL_b)
    gNL_true_b[gNL_true_b > 0] = np.max(gNL_true_b)
    combination = gNH_b + gNL_true_b
    combination[combination > 0] = np.max(combination)
    fig, axs = plt.subplots(2, 2, figsize=(10, 10))
    axs[0][0].set_title('gNH_b')
    axs[0][0].imshow(gNH_b, cmap='gray')
    axs[0][1].set_title('gNL_b')
    axs[0][1].imshow(gNL_b, cmap='gray')
    axs[1][0].set_title('gNL_true_b')
    axs[1][0].imshow(gNL_true_b, cmap='gray')
    axs[1][1].set_title('combination: gNH_b+gNL_true_b')
    axs[1][1].imshow(combination, cmap='gray')
    plt.suptitle('tl={}, th={}'.format(tl, th))
    plt.show()
    return combination
tl0 = 0.05
th0 = 0.4
binarized_res0 = draw_double_threshold(Mn, tl0, th0)
tl1 = 0.1
th1 = 0.5
binarized_res1 = draw_double_threshold(Mn, tl1, th1)
     
   
     
   
    适当提高双阈值后(
    
     (0.05, 0.4)->(0.1, 0.5)
    
    ),对噪声的过滤增强,对强边缘的要求提高,故强边缘像素减少、弱边缘中噪声也减少。
   
    过滤弱边缘中非连通边缘,再将过滤后的弱边缘和强边缘二值化图相加,得到最终的二值化边缘结果
    
     gNH_b+gNL_true_b
    
    .
   
# 和cv2库Canny函数对比
tl2 = 255 * 0.1
th2 = 255 * 0.5
g = cv2.Canny(f, tl2, th2)
plt.imshow(g, cmap='gray')
plt.show()
     
   
    
    
    参考文献
   
- 数字图像处理:第3版,北京:电子工业出版社
- 
     
 图像滤波之高斯滤波
 
- 
     
 边缘检测之Sobel检测算子
 
- 
     
 Canny边缘检测算法的python实现
 
- 
     
 常用测试数据集下载:“Standard” test images
 
 
