[英]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.convolve2d
, scipy.signal.convolve
, scipy.signal.fftconvolve
和scipy.ndimage.convolve
將以不同的方式處理2D卷積(后三個是Nd)。
scipy.signal.fftconvolve
在fft域中進行卷積(這是一個簡單的乘法)。 在許多情況下,這種速度要快得多,但是與邊緣情況相比,邊緣效應會產生非常小的差異,並且您的數據將通過此特定實現強制轉換為浮點數。 此外,在使用更大的陣列卷積小陣列時,會有不必要的內存使用。 總而言之,基於fft的方法可以大大加快,但是有一些常見的用例,其中scipy.signal.fftconvolve
不是理想的解決方案。
scipy.signal.convolve2d
, scipy.signal.convolve
和scipy.ndimage.convolve
都使用在C中實現的離散卷積,但是,它們以不同的方式實現它。
scipy.ndimage.convolve
保持相同的數據類型,並允許您控制輸出的位置以最小化內存使用。 如果你正在卷積uint8
(例如圖像數據),它通常是最好的選擇。 輸出將始終與第一個輸入數組的形狀相同,這對圖像有意義,但可能不適用於更一般的卷積。 ndimage.convolve
讓你可以通過mode
kwarg(其功能與scipy.signal
的mode
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.