2011-08-25 43 views
10

Tôi đang cố gắng áp dụng bộ lọc Sobel trên một hình ảnh để phát hiện các cạnh bằng cách sử dụng scipy. Tôi đang sử dụng Python 3.2 (64 bit) và scipy 0.9.0 trên Windows 7 Ultimate (64 bit). Mã hiện tại của tôi như sau:Áp dụng bộ lọc Sobel bằng cách sử dụng scipy

import scipy 
from scipy import ndimage 

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

Tôi không biết mình đang làm gì sai, nhưng hình ảnh đã xử lý trông không giống bất cứ thứ gì. Hình ảnh, 'bike.jpg' là hình ảnh màu xám (chế độ 'L' không phải 'RGB') nên mỗi pixel chỉ có một giá trị được liên kết với nó.

Đáng tiếc là tôi không thể gửi những hình ảnh ở đây chưa (không có đủ uy tín) nhưng tôi đã cung cấp các liên kết dưới đây:

Hình ảnh Gốc (bike.jpg): http://s2.postimage.org/64q8w613j/bike.jpg

scipy lọc (sobel.jpg): http://s2.postimage.org/64qajpdlb/sobel.jpg

Output dự kiến: http://s1.postimage.org/5vexz7kdr/normal_sobel.jpg

tôi rõ ràng là đi sai omewhere! Ai đó có thể cho tôi biết ở đâu. Cảm ơn.

Trả lời

20

1) Sử dụng độ chính xác cao hơn. 2) Bạn chỉ tính toán xấp xỉ đạo hàm dọc theo trục 0. Toán tử Sobel 2D được giải thích trên Wikipedia. Hãy thử mã này:

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

Vâng, tôi muốn đạo hàm trên 0 trục (dx). Tôi đang thực sự cố gắng để thực hiện các máy dò cạnh Canny và đã có vấn đề tính toán gradient bằng cách sử dụng các nhà khai thác Sobel. Cám ơn rất nhiều! Tôi cần thay đổi độ chính xác. – Feanor

6

Tôi không thể nhận xét về câu trả lời của cgohlke vì vậy tôi đã lặp lại câu trả lời của mình với một sự sửa đổi. Parameter được sử dụng cho dọc phái sinh và cho ngang phái sinh (trục đầu tiên của một mảng hình ảnh là y hướng/dọc - hàng, và trục thứ hai là x/ngang hướng - cột). Chỉ muốn cảnh báo những người dùng khác, bởi vì tôi đã mất 1 giờ để tìm kiếm nhầm lẫn ở những nơi không chính xác.

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

Chỉ cần rõ ràng, gradient là trực giao với cạnh, đạo hàm ngang phát hiện các cạnh * dọc. – dtk

0

hoặc bạn có thể sử dụng:

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 

để biết thêm thấy here

+0

Vui lòng bao gồm giải thích về Câu trả lời của bạn trong nội dung Câu trả lời. Có liên kết là không sao, nhưng có * chỉ * liên kết nên tránh vì các liên kết có thể bị hỏng theo thời gian. – toonice

Các vấn đề liên quan