快速实现0.667和3.833 Hz范围内的IIR滤波器

问题描述 投票:0回答:1

我需要切除0.667 - 3.833 Hz范围以外的频率(心率范围:40到230 bpm)。我查看了Apple文档,但我只看到了AVFoundation Butterworth过滤器。显然,“有效值范围是20 Hz到(SampleRate / 2)。”过滤器来自AVAudioUnitEQ所以它是可以理解的...我似乎找不到任何在我正在使用的频率范围内工作的滤波器。

我是否必须实施自己的巴特沃斯滤波器,或者我有什么遗漏?

编辑:所以我已经挖了更多的文档,我发现了一个IIR filterFIR filter,但它并不是我所期待的...... IIR滤波器是一个“级联双二阶IIR滤波器”,而不是Butterworth filter(这是什么我会比较喜欢)。我做了一个little reading,我不知道这个过滤器应该如何工作。如果我使用系数,我可以实现与巴特沃斯滤波器类似的功能吗?如果是这样,我该怎么做呢?我们的目标是拥有一个没有涟漪的平坦通带。

博客文章我松散地跟随:http://www.ignaciomellado.es/blog/Measuring-heart-rate-with-a-smartphone-camera

博客文章与一些双二阶过滤建议:http://www.ignaciomellado.es/blog/Measuring-heart-rate-with-a-smartphone-camera

swift signal-processing
1个回答
1
投票

IIR滤波器的实现在任何语言中都是相当直接和简单的。 IIR的设计是挑战和有趣的部分。有很多可以做出的权衡。 Biquad IIR滤波器是非常好的二阶滤波器(可以配置Butterworth系数),对于许多应用来说,一个就足够了,但是如果需要,你也可以级联它们以制作更高阶的滤波器。

首先要弄清楚你真正需要什么,这通常意味着你需要了解你想要滤除的噪声在频域中的样子,然后设计一个抑制噪声的滤波器。

周围有很多工具可以让您了解一组给定的IIR系数的频率响应。

这是来自快速谷歌搜索的许多one

一个关键参数是您对数据来源​​进行采样的频率(采样率)

一旦获得系数,实现就非常简单,它只是当前输入样本和许多先前输入和输出的函数。

你可以找到一些细节here,但这里有一个功能。

y[n] = b0* x[n] + b1 * x[n-1] + b2 * x[n-2] - a1 * y[n-1] - a2 * y[n-2]

其中x [n]是您当前的样本,x [n-1],是前一个样本等,y [n]是您当前的输出值,而y [n-1],y [n-2]是以前的产出。

如果你真的想深入了解过滤器设计的细节,我发现的最好的资源之一是使用SciPy,同样有很多关于如何做到这一点的教程。

我没有看过它,但这里有一个描述如何在Python中设计Butterworth滤波器的youtube video

正如我之前所说,一旦你有系数,任何语言的实现都非常简单。例如,这是一个非常简单的Biquad,我在c ++中用来过滤Arduino项目中的数据。这可以很容易地转换为swift或任何其他语言。

class BiQuad {

public:
  BiQuad(double b0, double b1, double b2, double a1, double a2)
      : b0_(b0), b1_(b1), b2_(b2), a1_(a1), a2_(a2) {}


  double processSample(double xn) {
    xn_ = xn;
    yn_ = b0_ * xn_ + b1_ * xnm1_ + b2_ * xnm2_ - a1_ * ynm1_ - a2_ * ynm2_;
    ynm2_ = ynm1_;
    ynm1_ = yn_;
    xnm2_ = xnm1_;
    xnm1_ = xn_;
    return yn_;
  }

  double getCurrentY() { return yn_; }

  void prime(double value) {
    xn_ = xnm1_ = xnm2_ = yn_ = ynm1_ = ynm2_ = value;
  }

private:
  double b0_;
  double b1_;
  double b2_;
  double a1_;
  double a2_;
  double xn_;
  double xnm1_ = 0.0;
  double xnm2_ = 0.0;
  double yn_ = 0.0;
  double ynm1_ = 0.0;
  double ynm2_ = 0.0;
};

希望这可以帮助。

© www.soinside.com 2019 - 2024. All rights reserved.