2010-09-16 3 views

Antwort

4

Sieht aus wie scipy.signal.convolve2d ist was du suchst.

+1

Wenn Sie den gleichen Modus verwenden, glaube ich nicht, dass sie tatsächlich gleich sind. SciPy zentriert sich anders als Matlab. Matlab sagt: "Wenn es eine ungerade Anzahl von Zeilen oder Spalten gibt, lässt das" Zentrum "am Anfang mehr als das Ende." SciPy scheint das Gegenteil zu tun. – endolith

+0

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

1
scipy.ndimage.convolve 

tut es in n Dimensionen.

+0

also tut 'scipy.signal.convolve'? – endolith

1

Sie müssen für jede Nicht-Singleton-Dimension einen Offset angeben, um die Ergebnisse von Matlabs conv2 zu reproduzieren. Eine einfache Implementierung der ‚gleichen‘ Option unterstützt, konnte nur, wie diese Während

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

gemacht werden, die bereits die anderen Antworten scipy.signal.convolve2d als Äquivalent erwähnen, fand ich, dass die Ergebnisse unterscheiden sich, wenn mode='same' verwenden.

Während Matlabs conv2 zu Artefakten auf der unteren und rechten Seite eines Bildes führt, hat scipy.signal.convolve2d die gleichen Artefakte oben und links von einem Bild.

Sehen Sie diese Links für Diagramme zeigen das Verhalten (nicht genug Ruf die Bilder direkt schreiben):

Upper left corner of convoluted Barbara

Lower right corner of convoluted Barbara

Die folgenden Wrapper möglicherweise nicht sehr effizient sein, aber das Problem gelöst in meinem Fall durch Drehen sowohl der Eingangsarrays als auch des Ausgangsarrays um jeweils 180 Grad:

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)