使用scipy应用Sobel滤波器
我正在尝试在一张图片上应用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'),所以每个像素只有一个值。
不幸的是,我现在还不能在这里发布图片(因为声望不够),但我提供了下面的链接:
原始图片(bike.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
显然我在某个地方出错了!能不能告诉我哪里有问题?谢谢。
3 个回答
1
或者你可以使用:
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
想了解更多,可以查看 这里
9
我无法对cgohlke的回答进行评论,所以我重复了他的回答并做了一个更正。参数0是用来表示垂直导数的,而1是用来表示水平导数的(图像数组的第一个轴是y/垂直方向 - 行,第二个轴是x/水平方向 - 列)。我只是想提醒其他用户,因为我花了一个小时在错误的地方寻找错误。
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)
32
1) 使用更高的精度。2) 你只是沿着零轴计算导数的近似值。2D Sobel算子可以在维基百科上找到详细解释。试试这段代码:
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)