2010-09-16 143 views
5

Python或其任何模塊是否具有與MATLAB的conv2函數相同的功能?更具體地說,我對MATLAB中的conv2(A, B, 'same')執行相同的計算感興趣。是否有與MATLAB的conv2函數相當的Python?

+0

對不起,錯過n-d部分 – Anycorn 2010-09-16 21:59:28

+0

@aaa鯉魚 - 沒問題!無論如何感謝 – Ryan 2010-09-16 22:02:46

回答

4

看起來像scipy.signal.convolve2d是你在找什麼。

+1

當使用'same'模式時,我不認爲它們實際上是相同的。 SciPy與Matlab的中心不同。 Matlab說:「如果有奇數行或列,那麼」中心「在開始時比結束時多一個。」 SciPy似乎正好相反。 – endolith 2012-12-16 07:00:47

+0

https://gist.github.com/4303970 – endolith 2012-12-16 07:10:55

1
scipy.ndimage.convolve 

它在n維中。

+0

「scipy.signal.convolve」呢? – endolith 2012-12-16 07:01:35

1

您必須爲每個非單實例維度提供一個偏移來重現Matlab的conv2的結果。一個簡單的實現支持「相同」選項,只有,可以作出這樣的

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

雖然其他答案已經提到scipy.signal.convolve2d爲等效,我發現,這樣做的結果使用mode='same'時有所不同。

雖然Matlab的conv2會在圖像的底部和右側產生瑕疵,但scipy.signal.convolve2d在圖像的頂部和左側會產生相同的瑕疵。

見這些鏈接圖,顯示的行爲(沒有足夠的口碑後直接圖像):

Upper left corner of convoluted Barbara

Lower right corner of convoluted Barbara

以下包裝器可能不是非常有效的,但解決問題在我的情況下,通過旋轉兩個輸入陣列和輸出陣列,每個180度:

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)