使用 scipy.signal 在 Python 中进行卷积和反卷积

Posted

技术标签:

【中文标题】使用 scipy.signal 在 Python 中进行卷积和反卷积【英文标题】:Convolution and Deconvolution in Python using scipy.signal 【发布时间】:2013-06-08 11:07:40 【问题描述】:

我正在尝试对音频样本进行一些(反)卷积。 我有一个样本 s 和相同的样本,上面添加了一些过滤器 s_f。两个样本都表示为 numpy 数组。 我想对它们进行反卷积以获得一个表示隔离过滤器f的数组。一旦我这样做了,我应该能够使用 sf 的卷积来重现 s_f

代码如下:

f = signal.deconvolve(s, s_f)
convolved = signal.convolve(s, f)

但是,我在第二行收到以下错误:

ValueError: in1 and in2 should have the same rank

有人知道我在这里做错了什么吗?

非常感谢, 奥马尔

【问题讨论】:

更新:我使用了一组错误的样本。使用希望好的那些我现在得到一个不同的错误: ValueError: object too deep for desired array 【参考方案1】:

rank(x) 返回矩阵的秩。换句话说,它包含的维度数。在调用signal.convolve()之前,请检查sf的等级是否相同。否则,您将收到您引用的异常。

我不知道为什么反卷积可能会返回比给定输入更多维度的东西。这需要我没有时间进行更深入的调查。

【讨论】:

原来我的样本有问题。 尝试使用(希望)好的样本重复此操作,我现在在反卷积函数中收到以下错误:ValueError: object too deep for desired array 也许这可以帮助你:***.com/questions/15923081/…【参考方案2】:

deconvolve 返回两个 数组,即商和余数。所以试试:

f, r = signal.deconvolve(s, s_f)

很长一段时间,deconvolve 一直没有合适的 docstring,但它在 github 的 master 分支中有一个:https://github.com/scipy/scipy/blob/master/scipy/signal/signaltools.py#L731

文档字符串显示了使用deconvolve 的示例。这是另一个(sigscipy.signalnpnumpy):

要反卷积的信号是z,滤波系数在filter

In [9]: z
Out[9]: 
array([  0.5,   2.5,   6. ,   9.5,  11. ,  10. ,   9.5,  11.5,  10.5,
         5.5,   2.5,   1. ])

In [10]: filter = np.array([0.5, 1.0, 0.5])

申请deconvolve:

In [11]: q, r = sig.deconvolve(z, filter)

In [12]: q
Out[12]: array([ 1.,  3.,  5.,  6.,  5.,  4.,  6.,  7.,  1.,  2.])

将过滤器应用于q,以验证我们是否返回z

In [13]: sig.convolve(q, filter)
Out[13]: 
array([  0.5,   2.5,   6. ,   9.5,  11. ,  10. ,   9.5,  11.5,  10.5,
         5.5,   2.5,   1. ])

通过构造,这是一个非常干净的示例。余数为零:

In [14]: r
Out[14]: array([ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.])

当然,你不会总是得到这么好的结果。

【讨论】:

非常感谢。但我仍然无法让它工作。我认为这可能是因为我使用的 numpy 数组是 2D 而不是 1D,所以我得到: ValueError: object too deep for desired array。我尝试使用 numpy.reshape(s,s.size) 将它们转换为 1D,但实际上并没有将其转换为 1D。 使您的阵列一维有意义吗?每一行或每一列不是一个单独的信号吗?如果你真的想要制作一维,你可以做s = numpy.reshape(s, s.size)s = numpy.ravel(s)。 (reshape 函数不会就地修改数组。) 我不确定 scipy 库如何处理 wav 文件。也许第一列是立体声信号的左声道,第二列是右声道。所以也许这样做并不明智,但我仍然想运行它,看看我得到了什么。 我确实设法使用您的建议将其转换为一维数组,但现在我在反卷积函数上遇到了一个不同的错误:'ValueError: BUG: filter coefficient a[0] == 0 not supported还' 我还是不明白deconvolve 的工作原理。我问了一个新问题(***.com/questions/40615034/…)。所以如果有人有想法,请分享。

以上是关于使用 scipy.signal 在 Python 中进行卷积和反卷积的主要内容,如果未能解决你的问题,请参考以下文章

什么是维纳滤波,对于python里的函数scipy.signal.wiener(im,mysize

如何在 scipy.signal.filter_design.ellip 中使用 rp、rs 和 Wn 参数?

修改 scipy.signal.welch 方法以在平均之前拒绝某些光谱

了解 scipy.signal.spectrogram() 的输出

如何使用 Scipy.signal.butter 实现带通巴特沃斯滤波器

限制 scipy.signal.spectrogram 仅计算特定频率