簡體   English   中英

Python中的2D卷積類似於Matlab的conv2

[英]2D Convolution in Python similar to Matlab's conv2

我一直在嘗試使用SciPy進行2D矩陣的卷積,而Numpy卻失敗了。 對於SciPy我試過,sepfir2d和scipy.signal.convolve和Convolve2D for Numpy。 在Matlab for Python中是否有像conv2這樣的簡單函數?

這是一個例子:

 A= [ 5     4     5     4;
      3     2     3     2;
      5     4     5     4;
      3     2     3     2 ]

我想用[0.707 0.707]卷積它

而來自Matlab的conv2的結果是

3.5350    6.3630    6.3630    6.3630    2.8280
2.1210    3.5350    3.5350    3.5350    1.4140
3.5350    6.3630    6.3630    6.3630    2.8280
2.1210    3.5350    3.5350    3.5350    1.4140

有些函數用Python來計算這個輸出嗎? 我將感激回應。

使用scipy有很多不同的方法,但2D卷積不直接包含在numpy (如果你需要避免scipy依賴,那么只使用numpy也很容易實現fft。)

scipy.signal.convolve2dscipy.signal.convolvescipy.signal.fftconvolvescipy.ndimage.convolve將以不同的方式處理2D卷積(后三個是Nd)。

scipy.signal.fftconvolve在fft域中進行卷積(這是一個簡單的乘法)。 在許多情況下,這種速度要快得多,但是與邊緣情況相比,邊緣效應會產生非常小的差異,並且您的數據將通過此特定實現強制轉換為浮點數。 此外,在使用更大的陣列卷積小陣列時,會有不必要的內存使用。 總而言之,基於fft的方法可以大大加快,但是有一些常見的用例,其中scipy.signal.fftconvolve不是理想的解決方案。

scipy.signal.convolve2dscipy.signal.convolvescipy.ndimage.convolve都使用在C中實現的離散卷積,但是,它們以不同的方式實現它。

scipy.ndimage.convolve保持相同的數據類型,並允許您控制輸出的位置以最小化內存使用。 如果你正在卷積uint8 (例如圖像數據),它通常是最好的選擇。 輸出將始終與第一個輸入數組的形狀相同,這對圖像有意義,但可能不適用於更一般的卷積。 ndimage.convolve讓你可以通過mode kwarg(其功能與scipy.signalmode kwarg完全不同)對如何處理邊緣效果進行大量控制。

如果您正在使用2d數組,請避免使用scipy.signal.convolve 它適用於Nd情況,但它對於2d數組來說不是最理想的,並且存在scipy.signal.convolve2d可以更有效地完成相同的操作。 scipy.signal的卷積函數scipy.signal讓您使用mode kwarg控制輸出形狀。 (默認情況下,它們的行為與matlab的conv2 。)這對於一般的數學卷積很有用,但對圖像處理不太有用。 但是, scipy.signal.convolve2d通常比scipy.ndimage.convolve慢。

有很多不同的選擇,部分原因是由於scipy的不同子模塊中的scipy ,部分原因是有不同的方法來實現具有不同性能權衡的卷積。

如果您可以提供有關用例的更多詳細信息,我們可以推薦更好的解決方案。 如果您正在卷積兩個大小相同的陣列,而且它們已經浮動, fftconvolve是一個很好的選擇。 否則, scipy.ndimage.convolve可能會擊敗它。

scipy的convolved1d()做你想要的,只是區別對待邊緣:

sp.ndimage.filters.convolve1d(A,[0.707,0.707],axis=1,mode='constant')

會給你:

array([[ 6.363,  6.363,  6.363,  2.828],
       [ 3.535,  3.535,  3.535,  1.414],
       [ 6.363,  6.363,  6.363,  2.828],
       [ 3.535,  3.535,  3.535,  1.414]])

如果你想要完全相同的結果,只需在A中添加一列零,如下所示:

sp.ndimage.filters.convolve1d(np.c_[np.zeros((4,1)),A],[0.707,0.707],axis=1,mode='constant')

你會得到:

array([[ 3.535,  6.363,  6.363,  6.363,  2.828],
       [ 2.121,  3.535,  3.535,  3.535,  1.414],
       [ 3.535,  6.363,  6.363,  6.363,  2.828],
       [ 2.121,  3.535,  3.535,  3.535,  1.414]])

根據我的經驗,你可以用scipy / numpy做很多你在Matlab中做的很容易(甚至更多)。

為什么不自己實現呢?請注意,conv2使用空間形式的二維卷積方程的直接形式實現。 如果a和b是兩個離散變量n1和n2的函數,那么a和b的二維卷積的公式是: 在此輸入圖像描述

然而,在實踐中,conv2計算有限區間的卷積。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM