2011-08-25 14 views
10

Estoy tratando de aplicar el filtro Sobel en una imagen para detectar bordes usando scipy. Estoy usando Python 3.2 (64 bit) y scipy 0.9.0 en Windows 7 Ultimate (64 bit). Actualmente mi código es el siguiente:Aplicación del filtro Sobel usando scipy

import scipy 
from scipy import ndimage 

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

No sé lo que estoy haciendo mal, pero la imagen procesada no se parece en nada a lo que debería. La imagen, 'bike.jpg' es una imagen en escala de grises (modo 'L' no 'RGB') por lo que cada píxel tiene solo un valor asociado.

Lamentablemente no puedo publicar las imágenes aquí todavía (no tienen suficiente reputación) pero he proporcionado enlaces siguientes:

imagen original (bike.jpg): http://s2.postimage.org/64q8w613j/bike.jpg

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

salida esperada: http://s1.postimage.org/5vexz7kdr/normal_sobel.jpg

obviamente estoy yendo s equivocadas ¡en algún lugar! ¿Puede alguien decirme dónde? Gracias.

Respuesta

20

1) Use una precisión más alta. 2) Usted solo está calculando la aproximación de la derivada a lo largo del eje cero. El operador 2D Sobel se explica en Wikipedia. Pruebe este código:

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

Sí, quería que el derivado a través del eje 0 (dx). En realidad estoy tratando de implementar el detector de bordes Canny y estaba teniendo problemas para calcular el gradiente utilizando los operadores de Sobel. ¡Muchas gracias! Necesitaba cambiar la precisión. – Feanor

6

No pude hacer ningún comentario sobre la respuesta de cgohlke, así que repetí su respuesta con una corrcción. Parámetro se utiliza para vertical de derivado y para horizontal derivado (primer eje de una matriz de imagen es la dirección Y/vertical - filas, y segundo eje es x/horizontal dirección - columnas). Solo quería advertir a otros usuarios, porque perdí 1 hora buscando errores en los lugares equivocados.

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

Para que quede claro, el gradiente es ortogonal al borde, la derivada horizontal detecta * bordes * verticales. – dtk

0

o puede utilizar:

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 

para más ver here

+0

Incluya una explicación de su respuesta en el texto de la respuesta. Tener el enlace está bien, pero tener * solo * el enlace debe evitarse ya que los enlaces pueden romperse con el tiempo. – toonice