2010-09-16 5 views

risposta

4

Sembra che scipy.signal.convolve2d sia quello che stai cercando.

+1

Quando si utilizza la modalità 'same', non penso che siano effettivamente uguali. SciPy si differenzia in modo diverso da Matlab. Matlab dice "Se c'è un numero dispari di righe o colonne, il" centro "ne lascia un altro all'inizio e alla fine." SciPy sembra fare l'opposto. – endolith

+0

https://gist.github.com/4303970 – endolith

1
scipy.ndimage.convolve 

lo fa in n dimensioni.

+0

così come 'scipy.signal.convolve'? – endolith

1

È necessario fornire un offset per ciascuna dimensione non singleton per riprodurre i risultati del conv2 di Matlab. Una semplice implementazione sostenere l'opzione 'stesso', solo, potrebbe essere fatto simili

import numpy as np 
from scipy.ndimage.filters import convolve 

def conv2(x,y,mode='same'): 
    """ 
    Emulate the function conv2 from Mathworks. 

    Usage: 

    z = conv2(x,y,mode='same') 

    TODO: 
    - Support other modes than 'same' (see conv2.m) 
    """ 

    if not(mode == 'same'): 
     raise Exception("Mode not supported") 

    # Add singleton dimensions 
    if (len(x.shape) < len(y.shape)): 
     dim = x.shape 
     for i in range(len(x.shape),len(y.shape)): 
      dim = (1,) + dim 
     x = x.reshape(dim) 
    elif (len(y.shape) < len(x.shape)): 
     dim = y.shape 
     for i in range(len(y.shape),len(x.shape)): 
      dim = (1,) + dim 
     y = y.reshape(dim) 

    origin =() 

    # Apparently, the origin must be set in a special way to reproduce 
    # the results of scipy.signal.convolve and Matlab 
    for i in range(len(x.shape)): 
     if ((x.shape[i] - y.shape[i]) % 2 == 0 and 
      x.shape[i] > 1 and 
      y.shape[i] > 1): 
      origin = origin + (-1,) 
     else: 
      origin = origin + (0,) 

    z = convolve(x,y, mode='constant', origin=origin) 

    return z 
2

Mentre le altre risposte già menzionano scipy.signal.convolve2d come equivalente, ho trovato che i risultati differiscono quando si utilizza mode='same'.

Mentre Matlab conv2 produce artefatti nella parte inferiore e destra di un'immagine, scipy.signal.convolve2d ha gli stessi artefatti in alto ea sinistra di un'immagine.

vedere questi collegamenti per i grafici che mostrano il comportamento (non abbastanza reputazione di inviare le immagini direttamente):

Upper left corner of convoluted Barbara

Lower right corner of convoluted Barbara

Il seguente involucro potrebbe non essere molto efficiente, ma ha risolto il problema nel mio caso ruotando entrambi gli array di input e l'array di output, ciascuno di 180 gradi:

import numpy as np 
from scipy.signal import convolve2d 

def conv2(x, y, mode='same') 
    return np.rot90(convolve2d(np.rot90(x, 2), np.rot90(y, 2), mode=mode), 2)