2010-09-16 9 views

Odpowiedz

4

Wygląda na to, że szukasz scipy.signal.convolve2d.

+1

Kiedy używam trybu "tego samego", nie sądzę, że są one takie same. SciPy centra inaczej niż Matlab. Matlab mówi: "Jeśli liczba wierszy lub kolumn jest nieparzysta," centrum "pozostawia jeszcze jeden na początku niż na końcu." Wydaje się, że SciPy robi coś przeciwnego. – endolith

+0

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

1
scipy.ndimage.convolve 

robi to w n wymiarach.

+0

, podobnie jak "scipy.signal.convolve"? – endolith

1

Należy podać przesunięcie dla każdego wymiaru nie pojedynczego, aby odtworzyć wyniki konw. Matlaba. Prosta implementacja wspiera „sam” opcję, tylko może być wykonany jak ten

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

Podczas gdy inne odpowiedzi już wspomnieć scipy.signal.convolve2d jako ekwiwalent, okazało się, że wyniki różnią się podczas korzystania mode='same'.

Podczas gdy Matlab's conv2 powoduje artefakty na dole i na prawo obrazu, scipy.signal.convolve2d ma te same artefakty na górze i na lewo od obrazu.

zobacz te linki na działkach pokazujących zachowanie (nie dość reputację zaksięgować bezpośrednio obrazów):

Upper left corner of convoluted Barbara

Lower right corner of convoluted Barbara

Poniższy wrapper może nie być bardzo skuteczny, ale rozwiązał problem w moim przypadku, obracając oba tablice wejściowe i macierz wyjściową, każdy o 180 stopni:

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)