【问题标题】:Applying the Sobel filter using scipy使用 scipy 应用 Sobel 过滤器
【发布时间】:2017-04-14 10:04:45
【问题描述】:

我正在尝试对图像应用 Sobel 过滤器以使用 scipy 检测边缘。我在 Windows 7 Ultimate(64 位)上使用 Python 3.2(64 位)和 scipy 0.9.0。目前我的代码如下:

import scipy
from scipy import ndimage

im = scipy.misc.imread('bike.jpg')
processed = ndimage.sobel(im, 0)
scipy.misc.imsave('sobel.jpg', processed)

我不知道我做错了什么,但处理后的图像看起来不像它应该的那样。图像“bike.jpg”是灰度(模式“L”而不是“RGB”)图像,因此每个像素只有一个与之关联的值。

很遗憾,我还不能在这里发布图片(没有足够的声誉),但我在下面提供了链接:

原始图像(自行车.jpg): http://s2.postimage.org/64q8w613j/bike.jpg

Scipy 过滤(sobel.jpg): http://s2.postimage.org/64qajpdlb/sobel.jpg

预期输出: http://s1.postimage.org/5vexz7kdr/normal_sobel.jpg

我显然在某个地方出错了!有人可以告诉我在哪里。谢谢。

【问题讨论】:

    标签: python scipy edge-detection


    【解决方案1】:

    1) 使用更高的精度。 2)您只计算沿零轴的导数的近似值。 2D Sobel 算子在Wikipedia 上进行了解释。试试这个代码:

    import numpy
    import scipy
    from scipy import ndimage
    
    im = scipy.misc.imread('bike.jpg')
    im = im.astype('int32')
    dx = ndimage.sobel(im, 0)  # horizontal derivative
    dy = ndimage.sobel(im, 1)  # vertical derivative
    mag = numpy.hypot(dx, dy)  # magnitude
    mag *= 255.0 / numpy.max(mag)  # normalize (Q&D)
    scipy.misc.imsave('sobel.jpg', mag)
    

    【讨论】:

    • 是的,我想要跨 0 轴 (dx) 的导数。我实际上是在尝试实现 Canny 边缘检测器,并且在使用 Sobel 算子计算梯度时遇到了问题。非常感谢!我需要改变精度。
    • 在使用带有 skimage 的过滤器时,将 dtype 从 uint8 更改为 float 对我有用。
    【解决方案2】:

    我无法对 cgohlke 的回答发表评论,所以我用更正的方式重复了他的回答。参数0用于vertical导数,1用于horizo​​ntal导数(图像数组的第一轴为y/垂直方向 - 行,第二个轴是 x/水平方向 - 列)。只是想警告其他用户,因为我在错误的地方搜索错误浪费了 1 小时。

    import numpy
    import scipy
    from scipy import ndimage
    
    im = scipy.misc.imread('bike.jpg')
    im = im.astype('int32')
    dx = ndimage.sobel(im, 1)  # horizontal derivative
    dy = ndimage.sobel(im, 0)  # vertical derivative
    mag = numpy.hypot(dx, dy)  # magnitude
    mag *= 255.0 / numpy.max(mag)  # normalize (Q&D)
    scipy.misc.imsave('sobel.jpg', mag)
    

    【讨论】:

    • 为了清楚起见,梯度与边缘正交,水平导数检测垂直边缘。
    【解决方案3】:

    或者你可以使用:

    def sobel_filter(im, k_size):
    
        im = im.astype(np.float)
        width, height, c = im.shape
        if c > 1:
            img = 0.2126 * im[:,:,0] + 0.7152 * im[:,:,1] + 0.0722 * im[:,:,2]
        else:
            img = im
    
        assert(k_size == 3 or k_size == 5);
    
        if k_size == 3:
            kh = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]], dtype = np.float)
            kv = np.array([[1, 2, 1], [0, 0, 0], [-1, -2, -1]], dtype = np.float)
        else:
            kh = np.array([[-1, -2, 0, 2, 1], 
                       [-4, -8, 0, 8, 4], 
                       [-6, -12, 0, 12, 6],
                       [-4, -8, 0, 8, 4],
                       [-1, -2, 0, 2, 1]], dtype = np.float)
            kv = np.array([[1, 4, 6, 4, 1], 
                       [2, 8, 12, 8, 2],
                       [0, 0, 0, 0, 0], 
                       [-2, -8, -12, -8, -2],
                       [-1, -4, -6, -4, -1]], dtype = np.float)
    
        gx = signal.convolve2d(img, kh, mode='same', boundary = 'symm', fillvalue=0)
        gy = signal.convolve2d(img, kv, mode='same', boundary = 'symm', fillvalue=0)
    
        g = np.sqrt(gx * gx + gy * gy)
        g *= 255.0 / np.max(g)
    
        #plt.figure()
        #plt.imshow(g, cmap=plt.cm.gray)      
    
        return g
    

    更多信息请参见here

    【讨论】:

      猜你喜欢
      • 2019-03-27
      • 2019-03-11
      • 1970-01-01
      • 2019-03-11
      • 2015-07-29
      • 2016-06-16
      • 2015-07-31
      • 1970-01-01
      • 2015-11-11
      相关资源
      最近更新 更多