scipy PPG数据的IIR滤波器嵌入式实现

okxuctiv  于 2023-04-21  发布在  其他
关注(0)|答案(1)|浏览(172)

我正在做一个项目,我需要过滤传感器采集的PPG数据。看几篇论文,这个用例的最佳评级过滤器是Chebyshev II过滤器,我也想使用它。
我的数据集由600个18bit ADC值组成。处理在收集电流样本后进行,并进行滤波。之后,我应用qppg算法进行峰值检测以计算心率方差。
在实现方面,我首先开始在Python中实现它,后来我需要将其重写为C。在Scipy库中,推荐的方法是使用cheby2()计算sos系数,并使用sosfiltfilt()函数将其应用于数据。这很好用。
然而,我计划做的是预先计算传递函数的a,B系数,将它们硬编码在C源文件中,并通过直接形式I或II使用for循环应用于信号数据(是的,我以为会这么简单)。仔细检查我发现的filtfilt()函数,它使用奇数扩展,然后是lfiter()_linear_filter())的底层C实现,我无法复制。
这个论坛上类似的帖子的问题是,为了得到正确的结果,lfilter()函数需要使用zi参数,该参数提供了滤波器延迟的初始条件,我不知道如何在计算中应用它们。
我的问题是:有没有可能使用最简单的操作(稍后重写到嵌入式C中)以更简单、更简洁的方式实现过滤结果?如果有,如何实现?
如果不是,我还能尝试什么其他方法?我有点想不出办法了,现在我正在考虑采用一种更简单的过滤算法(eidogg.巴特沃思)。

pgvzfuti

pgvzfuti1#

IIR滤波器的实现相当简单,我假设你说的z1参数是I型还是II型形式记忆?
从[gtkiostream中的这个IIR实现][1]中,您应该能够将此C++代码移植到C:

// Direct Form II algorithm
for (int i=0; i<x.rows(); i++){
  mem.row(0)=-x.row(i);
  mem.row(0)=-(A*mem.block(0, 0, A.rows(), A.cols())).colwise().sum();
  yTemp.row(i)=(B*mem.block(0, 0, B.rows(), B.cols())).colwise().sum();
  for (int j=mem.rows()-1; j>0; j--)
    mem.row(j)=mem.row(j-1);
}

在代码中,行是时间样本,列是不同的IIR滤波器。A和B分别是分母和分子系数。mem是内存,可能是你所说的z1,必须在输入信号的每次迭代之间存储以找到输出信号。https://github.com/flatmax/gtkiostream/blob/master/src/DSP/IIR.C#L83-L89

相关问题