Pregunta

Estoy buscando la implementación equivalente del Laplacian de la detección de bordes gaussianos.

en MATLAB Utilizamos la siguiente función

   [BW,threshold] = edge(I,'log',...)

En Python existe una función para calcular el Laplacian de Gaussian.No está devolviendo definitivamente los bordes.

  scipy.ndimage.filters.gaussian_laplace

Cualquier puntero a la implementación en línea o el código

gracias

¿Fue útil?

Solución

Qué Matlab Edge () debe ser

  1. Registro de cómputo
  2. Compute los cruces cero en el registro
  3. calcular un umbral para la diferencia de registro local
  4. borde píxeles= cruce cero && diferencia local> Umbral
  5. El filtro de registro de Scipy solo hace el paso 1 anterior. Implementé el siguiente fragmento para imitar el paso 2 ~ 4 arriba:

    import scipy as sp
    import numpy as np
    import scipy.ndimage as nd
    import matplotlib.pyplot as plt
    from skimage import data    
    
    # lena = sp.misc.lena() this function was deprecated in version 0.17
    img = data.camera()  # use a standard image from skimage instead
    LoG = nd.gaussian_laplace(img , 2)
    thres = np.absolute(LoG).mean() * 0.75
    output = sp.zeros(LoG.shape)
    w = output.shape[1]
    h = output.shape[0]
    
    for y in range(1, h - 1):
        for x in range(1, w - 1):
            patch = LoG[y-1:y+2, x-1:x+2]
            p = LoG[y, x]
            maxP = patch.max()
            minP = patch.min()
            if (p > 0):
                zeroCross = True if minP < 0 else False
            else:
                zeroCross = True if maxP > 0 else False
            if ((maxP - minP) > thres) and zeroCross:
                output[y, x] = 1
    
    plt.imshow(output)
    plt.show()
    

    Esto, por supuesto, es lento y probablemente no es idiomático, ya que también soy nuevo en Python, pero debería mostrar la idea.Cualquier sugerencia sobre cómo mejorarla también es bienvenida.

Otros consejos

Me jugué un poco con el código de Ycyeh (gracias por proporcionarlo).En mis aplicaciones, obtuve mejores resultados con el uso de valores de salida proporcional a la gama Min-MAX que solo 0s binarios y 1S.(Entonces, también necesitaba la trilla, pero se puede aplicar fácilmente un umbral de umbral en el resultado). También cambié los bucles a operaciones de matriz adorables para una ejecución más rápida.

import numpy as np
import scipy.misc
import cv2  # using opencv as I am not too familiar w/ scipy yet, sorry 


def laplace_of_gaussian(gray_img, sigma=1., kappa=0.75, pad=False):
    """
    Applies Laplacian of Gaussians to grayscale image.

    :param gray_img: image to apply LoG to
    :param sigma:    Gauss sigma of Gaussian applied to image, <= 0. for none
    :param kappa:    difference threshold as factor to mean of image values, <= 0 for none
    :param pad:      flag to pad output w/ zero border, keeping input image size
    """
    assert len(gray_img.shape) == 2
    img = cv2.GaussianBlur(gray_img, (0, 0), sigma) if 0. < sigma else gray_img
    img = cv2.Laplacian(img, cv2.CV_64F)
    rows, cols = img.shape[:2]
    # min/max of 3x3-neighbourhoods
    min_map = np.minimum.reduce(list(img[r:rows-2+r, c:cols-2+c]
                                     for r in range(3) for c in range(3)))
    max_map = np.maximum.reduce(list(img[r:rows-2+r, c:cols-2+c]
                                     for r in range(3) for c in range(3)))
    # bool matrix for image value positiv (w/out border pixels)
    pos_img = 0 < img[1:rows-1, 1:cols-1]
    # bool matrix for min < 0 and 0 < image pixel
    neg_min = min_map < 0
    neg_min[1 - pos_img] = 0
    # bool matrix for 0 < max and image pixel < 0
    pos_max = 0 < max_map
    pos_max[pos_img] = 0
    # sign change at pixel?
    zero_cross = neg_min + pos_max
    # values: max - min, scaled to 0--255; set to 0 for no sign change
    value_scale = 255. / max(1., img.max() - img.min())
    values = value_scale * (max_map - min_map)
    values[1 - zero_cross] = 0.
    # optional thresholding
    if 0. <= kappa:
        thresh = float(np.absolute(img).mean()) * kappa
        values[values < thresh] = 0.
    log_img = values.astype(np.uint8)
    if pad:
        log_img = np.pad(log_img, pad_width=1, mode='constant', constant_values=0)
    return log_img


def _main():
    """Test routine"""
    # load grayscale image
    img = scipy.misc.face()  # lena removed from newer scipy versions
    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # apply LoG
    log = laplace_of_gaussian(img)
    # display
    cv2.imshow('LoG', log)
    cv2.waitKey(0)


if __name__ == '__main__':
    _main()

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top