2011-08-25 21 views
10

我試圖在圖像上應用Sobel濾鏡來使用scipy檢測邊緣。我在Windows 7旗艦版(64位)上使用Python 3.2(64位)和scipy 0.9.0。目前,我的代碼如下:使用scipy應用Sobel濾鏡

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

我顯然會正確■ omewhere!有人可以告訴我在哪裏。謝謝。

回答

20

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

是的,我想越過0軸(DX)的衍生物。我實際上試圖實現Canny邊緣檢測器,並且在使用Sobel算子計算梯度時遇到了問題。非常感謝!我需要改變精度。 – Feanor

6

我無法評論cgohlke的答案,所以我重複了他的答案與修正。參數用於垂直衍生物和爲水平衍生物(第一圖像陣列的軸爲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) 
+1

爲了清楚起見,梯度垂直於邊緣,水平導數檢測*垂直*邊緣。 – dtk

0

,或者您可以使用:

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

+0

請在答案正文中包含對答案的解釋。有鏈接是好的,但只有*鏈接應該避免,因爲鏈接可能會隨着時間的推移而被打破。 – toonice