use*_*318 16 python matlab signal-processing image convolution
我一直在尝试使用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 ]
Run Code Online (Sandbox Code Playgroud)
我想把它卷入其中 [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
Run Code Online (Sandbox Code Playgroud)
有些函数用Python来计算这个输出吗?我将感激回应.
Joe*_*ton 31
有许多不同的方法可以实现scipy
,但2D卷积不直接包含在内numpy
.(如果你需要避免scipy依赖,那么只使用numpy也很容易实现fft.)
scipy.signal.convolve2d
,scipy.signal.convolve
,scipy.signal.fftconvolve
,并且scipy.ndimage.convolve
将所有处理二维卷积(最后三个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).
scipy.signal.convolve
如果你正在使用2d数组,请避免使用.它适用于Nd情况,但它对于2d数组来说是次优的,并且scipy.signal.convolve2d
存在更高效地执行完全相同的操作.卷积函数可scipy.signal
让您使用mode
kwarg 控制输出形状.(默认情况下,它们的行为与matlab类似conv2
.)这对于一般的数学卷积非常有用,但对图像处理不太有用.但是,scipy.signal.convolve2d
通常比慢scipy.ndimage.convolve
.
有许多不同的选项部分是由于不同子模块中的重复scipy
,部分是因为有不同的方法来实现具有不同性能权衡的卷积.
如果您可以提供有关用例的更多详细信息,我们可以推荐更好的解决方案.如果您正在卷积两个大小相同的阵列,并且它们已经是浮动的,那么这fftconvolve
是一个很好的选择.否则,scipy.ndimage.convolve
可能打败它.
scipy的convolved1d()做你想要的,只是区别对待边缘:
sp.ndimage.filters.convolve1d(A,[0.707,0.707],axis=1,mode='constant')
Run Code Online (Sandbox Code Playgroud)
会给你:
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]])
Run Code Online (Sandbox Code Playgroud)
如果你想要完全相同的结果,只需在A中添加一列零,如下所示:
sp.ndimage.filters.convolve1d(np.c_[np.zeros((4,1)),A],[0.707,0.707],axis=1,mode='constant')
Run Code Online (Sandbox Code Playgroud)
你会得到:
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]])
Run Code Online (Sandbox Code Playgroud)
根据我的经验,你可以用scipy/numpy做很多你在Matlab中做的很容易(甚至更多).
Dan*_*rin -4
为什么不自己实现呢?请注意,conv2 使用空间形式的二维卷积方程的简单形式实现。如果a和b是两个离散变量n1和n2的函数,则a和b的二维卷积公式为:
但实际上, conv2 计算有限间隔的卷积。