Domanda

Sto cercando l'attuazione equivalente del laplacian del rilevamento del bordo gaussiano.

in matlab Utilizziamo la seguente funzione

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

In Python esistono una funzione per calcolare il Laplacian of Gaussian.Non restituisce sicuramente i bordi.

  scipy.ndimage.filters.gaussian_laplace
.

Qualsiasi puntatore all'implementazione online o il codice

Grazie

È stato utile?

Soluzione

Quale margine MATLAB () dovrebbe essere

    .
  1. Compute Log
  2. Computa zero attraversamenti sul registro
  3. Computa una soglia per la differenza di registro locale
  4. Bordo pixel= zero attraversamento && differenza locale> soglia
  5. Il filtro del registro di Scipy fa solo il passaggio 1 sopra. Ho implementato il seguente snippet a mimico passaggio 2 ~ 4 sopra:

    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()
    
    .

    Questo ovviamente è lento e probabilmente non idiomatico come sono anche nuovo a Python, ma dovrebbe mostrare l'idea.Qualsiasi suggerimento su come migliorarlo è anche il benvenuto.

Altri suggerimenti

Ho giocato un po 'con il codice di Ycyeh (grazie per averlo fornito).Nelle mie applicazioni ho ottenuto risultati migliori con l'utilizzo dei valori di output proporzionale alla gamma Min-Max rispetto a solo binari 0s e 1s.(Allora non avevo più bisogno della trebbia, ma si può facilmente applicare una soglia sul risultato.) Inoltre ho cambiato i loop in operazioni di arroviazione prudente per un'esecuzione più rapida.

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()
.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top