自适应Canny边缘检测算法

时间:2018-01-20 12:01:34

标签: python image-processing computer-vision edge-detection

我正试图从头开始使用python实现Canny算法。

我正在按照步骤

  1. 双边过滤图片

  2. 使用4个不同方向的高斯导数的梯度计算

  3. def deroGauss(w=5,s=1,angle=0):

        wlim = (w-1)/2
        y,x = np.meshgrid(np.arange(-wlim,wlim+1),np.arange(-wlim,wlim+1))
        G = np.exp(-np.sum((np.square(x),np.square(y)),axis=0)/(2*np.float64(s)**2))
        G = G/np.sum(G)
        dGdx = -np.multiply(x,G)/np.float64(s)**2
        dGdy = -np.multiply(y,G)/np.float64(s)**2
    
        angle = angle*math.pi/180 #converting to radians
    
        dog = math.cos(angle)*dGdx + math.sin(angle)*dGdy
    
        return dog
    
    1. 所有4个渐变图像中的非最大抑制
    2. def nonmaxsup(I,gradang):

          dim = I.shape
          Inms = np.zeros(dim)
          weak = np.zeros(dim)    
          strong = np.zeros(dim)
          final = np.zeros(dim)
          xshift = int(np.round(math.cos(gradang*np.pi/180)))
          yshift = int(np.round(math.sin(gradang*np.pi/180)))
          Ipad = np.pad(I,(1,),'constant',constant_values = (0,0))
          for r in xrange(1,dim[0]+1):
              for c in xrange(1,dim[1]+1):
                  maggrad = [Ipad[r-xshift,c-yshift],Ipad[r,c],Ipad[r+xshift,c+yshift]]
                  if Ipad[r,c] == np.max(maggrad):
                      Inms[r-1,c-1] = Ipad[r,c]
          return Inms
      
      1. 双重阈值和迟滞:现在这里出现了真正的问题。
      2. 我正在使用Otsu的方法来计算阈值。

        我应该使用灰度图像还是渐变图像来计算阈值?

        因为在梯度图像中,在双边滤波之后像素强度值被降低到非常低的值,然后在与高斯衍生物卷积之后,它进一步减小。例如:: 28,15

        使用灰度计算的阈值远高于使用渐变图像计算的阈值。

        此外,如果我使用灰度或甚至渐变图像来计算阈值,结果图像不够好,并且不包含所有边缘。

        所以实际上,我没有什么可以用来应用迟滞。

        我试过了

        img_edge = img_edge*255/np.max(img_edge)

        缩放值但结果保持不变

        但如果我对cv2.Canny使用相同的阈值,结果非常好。

        实际上可能出现什么问题?

1 个答案:

答案 0 :(得分:0)

从原始图像应用Otsu阈值没有意义,它与梯度强度完全无关。

Otsu从梯度强度来看并不完美,因为噪声和边缘的统计分布是倾斜的并且重叠很多。

您可以尝试Otsu的一些小倍数或平均值的一些小倍数。但在任何情况下,您都不会通过简单或滞后阈值来获得完美的结果。边缘检测是一个不适定的问题。