使用Python进行反向过滤

时间:2016-07-01 13:40:59

标签: python numpy scipy signal-processing sympy

给定脉冲响应h和输出y(两个一维数组),我试图找到一种方法来计算逆滤波器x,以便{ {1}},其中h * x = y表示卷积积。

例如,假设脉冲响应*h,输出为步进函数(即由所有[1,0.5]组成)。可以看出第一个系数应该是1,这会产生[1, 0.5, 0.75]的输出。最后一个术语包含错误,但这不是一个真正的问题,因为我只关注输出到某个最大时间。

我想自动化和扩大规模。这种逆滤波可以实现更长,更复杂的脉冲响应函数。到目前为止,我已经想出得到系数的唯一方法是使用sympy生成Z变换的级数展开。 (注意,阶跃函数的Z变换是1 /(1-z))。

然而,我已经注意到,在计算系数时,同情心很慢:即使是一个简单的简短示例,也需要0.8秒,如下面的脚本所示:

[1, 1, 1, 0.375]

这会产生输出:

import numpy as np
from scipy import signal
from sympy import Symbol, series
import time

h = np.array([1,0.5])           # Impulse response function
y = np.array([1,1,1,1,1])       # Ideal output is a step function

my_x = np.array([1,0.5,0.75])   # Inverse filter response (calculated manually)

my_y = signal.convolve(h,my_x)  # Actual output (should be close to ideal output)

print(my_y)

start = time.time()
z = Symbol('z')
print(series(1/((1-z)*(1+z/2)),z))
end = time.time()
print("The power series expansion took "+str(end - start)+" seconds to complete.")

简而言之,功率扩展的系数与所需的滤波器响应相匹配,但使用sympy来做这件事似乎很麻烦。有没有更好的方法在Python中计算逆滤波器系数?

1 个答案:

答案 0 :(得分:6)

这称为解卷积:scipy.signal.deconvolve将为您执行此操作。您知道原始输入信号x的示例:

import numpy as np
import scipy.signal as signal

# We want to try and recover x from y, where y is made like this:
x = np.array([0.5, 2.2, -1.8, -0.1])
h = np.array([1.0, 0.5])
y = signal.convolve(x, h)

# This is called deconvolution:
xRecovered, xRemainder = signal.deconvolve(y, h)
# >>> xRecovered
# array([ 0.5,  2.2, -1.8, -0.1])
# >>> xRemainder
# array([  0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
#          0.00000000e+00,  -1.38777878e-17])

# Check the answer
assert(np.allclose(xRecovered, x))
assert(np.allclose(xRemainder, 0))

听起来你不知道原始信号,所以你的xRemainder为机器精度为0 - 它将代表记录信号中的噪音{{1} }。