假设我有一个以 220Hz 采样率采集的 2 秒数据集,我想过滤掉与 EEG 频谱相关的频带:
从信号中过滤频带
最简单的方法是什么?
我是 GNU Radio 的人。所以最简单的方法是这个 GNU Radio 同伴设计的流程图:
生成此流程图文件会生成一个 python 程序,该程序使用 GNU Radio 在尽可能多的 CPU 内核上进行信号处理。
然后你可以运行它
$ ./bandpass_filters.py -f {input file containing float32 samples, one after the other}
为了降低所有这些带通的复杂性,我首先使用低通将信号的采样率降低一半——这没关系,因为您只对低于输入采样率一半的频率感兴趣。
我用一个 200MB 的“虚拟”文件尝试了这个,创建了 8 个 100MB 的输出文件——这在一个临时目录中来回花费了整整 13 秒。我非常希望它足够快!我对此进行了一些基准测试,似乎该源每秒能够通过大约 2000 万个样本;缓慢的部分是写入 8 个文件。
请注意,这是一个快速简便的解决方案——一个适当的、速度优化的解决方案可能会使用
- 抽取,因为您的输出采样率仍然是 110 Hz,其中最多包含 9 Hz(这浪费了处理能力,因此浪费了速度)
- 对于低于该速率的四个滤波器,通过低通滤波到 27.5 Hz 的另一个预抽取 2
但是,实际上,在您的样本量适中(16GB = 40 亿个 32 位浮点数?),无论如何,如果您想喝杯咖啡,这并不是必需的。
那个流程图真的很好而且很容易设计。如果你想学习自己设计这样的信号处理流程图,我在这里,无耻地插入 GNU Radio 的指导教程;事实上,在实时流程图中使用 GNU Radio 更有趣,即在输入或输出(或两者)是物理设备(麦克风、心电传感器、声纳、无线电前端)的系统中。-r如果您将“文件源”替换为“音频源”(两者都带有 GNU Radio)并通过标志指定与声卡兼容的采样率,则完全相同的流程图可以与声卡一起使用。
现在,由于您可能比我更了解如何使用 Mathematica,因此我建议您实现以下内容:
- (第一次,一次)您使用 GNU Radio 伴侣生成一个 python 程序,为您进行信号处理。
- 您使用 Mathematica
BinaryWrite()将原始样本作为 32 位浮点数写入文件,例如BinaryWrite("/tmp/samples.dat.f32", your_sample_vector, "Real32"). - 您可以使用 Mathematica 的功能来调用您机器上的可执行文件来执行该 python 脚本。现在,我不是 Mathematica 专家,所以这都是基于谷歌的猜测:
RunProcess({"/path/of/python/executable", "/path/of/generated/python/program", "-f", "/tmp/samples.dat.f32"}) - 您在 Mathematica 中阅读 (
BinaryRead) 结果/tmp/samples.dat.f32_1_3.dat(等等)。…_4_7.dat
或者,您确实考虑在 Mathematica 中减少工作流程,并使用 GNU Radio 或其模块生态系统附带的大量信号处理东西。
采样频率似乎正确(220 Hz > 2*50 Hz),因此不会丢失信息。
您要做的是为每个频段设计一个带通滤波器,并将其应用于您的信号以提取每个频段。由于您似乎拥有“无限”的计算量,因此您可以轻松应用高阶滤波器并获取信号。
由于您使用的是mathematica,我建议使用此功能: https ://reference.wolfram.com/language/ref/BandpassFilter.html 它允许轻松指定频率和其他参数,而无需设计整个事物。
例如,假设您有一个信号在mathematica 中,它由数字数组 {12,21,...,36,...} 定义。你想提取波浪。您必须使用以下函数(n 是过滤器的内核长度)
BandPassFilter[S, {w1,w2},n]
w1 和 w2 被定义为:
如果您可以自由使用任何软件,我也建议您切换到 MatLab,它比 Mathematica(我的观点)更适合随心所欲地处理数据,并且在信号工程社区中广泛使用。
