Esiste un equivalente della funzione Python CONV2 di MATLAB?
-
03-10-2019 - |
Domanda
non Python o uno qualsiasi dei suoi moduli hanno un equivalente di MATLAB di CONV2 funzione? Più in particolare, sono interessato a qualcosa che fa lo stesso calcolo come conv2(A, B, 'same')
in MATLAB.
Soluzione
scipy.signal.convolve2d è quello che stai cercando.
Altri suggerimenti
Mentre le altre risposte già menzionano scipy.signal.convolve2d
come equivalente, ho trovato che i risultati differiscono quando si utilizza mode='same'
.
Mentre i risultati conv2
di Matlab in artefatti sul fondo e destro di un'immagine, scipy.signal.convolve2d
ha le stesse artefatti sulla parte superiore e sinistra di un'immagine.
Vedere questi collegamenti per trame che mostrano il comportamento (non abbastanza reputazione di inviare direttamente le immagini):
In alto a sinistra all'angolo di contorto Barbara
angolobasso a destra del contorto Barbara
Il seguente involucro potrebbe non essere molto efficace, ma risolto il problema nel mio caso ruotando entrambe le matrici di ingresso e la matrice di uscita, 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)
scipy.ndimage.convolve
fa in n dimensioni.
È necessario fornire un offset per ogni dimensione non Singleton di riprodurre i risultati di CONV2 di Matlab. Una semplice implementazione sostenere l'opzione 'stesso', solo, potrebbe essere fatto così
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