
做数字信号处理这块的人十有八九都遇到过这种需求手里有一堆数据要么是从 Simulink 模型里示波器录出来的波形要么是别人给你扔过来的 .mat 文件里面存着一段莫名其妙的历史数据。你想去掉噪声、提取有用频段但不想再动模型、不想重新跑一遍仿真更不想从头手写一个巴特沃斯滤波器来回试阶数。这时候基于 MATLAB 的 FFT 滤波就是最顺手的一招——把时域信号搬到频域看一眼该留的留、该灭的灭再搬回来就完事了。这篇文章就围绕这个思路展开讲清楚从 Simulink 示波器导出数据、从外部 .mat 文件读数据、到用 FFT 做频域滤波的完整流程顺便把我这些年踩过的坑一并交代了。1. 先说清楚需求FFT滤波到底解决什么问题1.1 为什么是从外部拿数据再MATLAB里滤而不是直接在Simulink里挂滤波模块很多人第一反应是Simulink 里不是有现成的 Discrete Filter、Transfer Function 模块吗直接在模型里加一个低通滤波器不就行了为什么还要把数据导出来、绕过模型单独做滤波这个问题的答案我在实际项目里体会特别深。首先很多情况下你手上的数据根本就不是现在还能跑通的模型产出的。项目做到后期模型版本换来换去可能原模型早就不存在了只剩下一堆 .mat 存档或者示波器导出的波形文件。这时候你不可能为了滤个波把几年前的模型翻出来重新搭一遍。其次即便模型还在重新加滤波器模块也意味着要重新配置参数、重新仿真甚至要返工验证系统是否稳定——为了一个只做一次性分析的滤波操作这个代价太大了。更关键的一点是Simulink 里加滤波器属于在线处理滤波模块会实时地作用于信号链路这会影响控制系统的闭环行为、时序响应甚至稳定性。但你只是想离线分析一下数据、看看滤波后的特征在线滤波反而会改变系统的动态特性属于杀鸡用了牛刀还顺带误伤。所以做离线分析的正确姿势是把示波器数据或 .mat 文件导入 MATLAB 工作区基于 FFT 的频域处理快速完成滤波再返回去对比、出图、做指标计算。整个流程不碰模型不碰控制链路纯数据分析灵活性和安全性都是最好的。1.2 FFT滤波的两条路线频域掩膜 vs 普通数字滤波器我经常看到有人把 FFT 滤波和普通数字滤波器搞混其实它们的实现逻辑完全不同。普通数字滤波器比如 Butterworth、Chebyshev、IIR/FIR 滤波器是在时域上通过差分方程或者卷积的方式对信号逐步处理。它的特点是需要选阶数、定截止频率、还要忍受相位延迟除非用零相位滤波技术。FFT 滤波的本质则是把时域信号通过离散傅里叶变换搬到频域乘以一个频域窗函数掩膜再通过逆变换回来。这个掩膜你可以完全按照需求画出来——比如把高频部分直接清零、把某个窄带噪声掀掉、保留某个谐振峰的幅值。它最大的优势是频域操作够直观功率谱上哪个峰是噪声我就是要把那个频段的 FFT 系数置零所见即所得。当然FFT 滤波也有它的缺陷因为 FFT 隐含的是周期延拓所以滤波后的波形首尾可能出现振铃边缘效应另外如果直接在频域做硬截断矩形窗时域上会有明显的吉布斯振荡。这两条路线互相补充实际中我的习惯是需要快速看趋势就用 FFT 滤波需要严格保持时域特征就用 filtfilt 加 FIR/IIR 滤波器。后面的章节会把 FFT 滤波的细节、坑位和完整代码全部展开。2. 数据准备从示波器和.mat文件里拿到干净的原始数据2.1 Simulink示波器波形数据的三种导出姿势在聊 FFT 滤波之前一定要先把数据是怎么来的搞清楚。很多人在 Simulink 里看着示波器波形很漂亮真要把数据拿出去用的时候就开始手忙脚乱。常见的导出方式有三种我按推荐程度排个序。第一种最推荐也最干净的方式在模型里直接加 To Workspace 模块把需要分析的信号线引进去设置变量名比如写 SimOut和输出格式建议选 Structure with time 或者 Array。这样仿真一跑完数据自动出现在 MATLAB 工作区SimOut.Time 是时间轴SimOut.Signals.values 是信号值。这种方式能同时拿到时间和信号而且不需要手动点击导出特别适合批量跑仿真的时候用。第二种用 Scope 模块自带的导出功能。双击打开 Scope点菜单栏中的Settings或者上面的齿轮图标在Logging选项卡里勾选Log data to workspace填写变量名。这个操作会把示波器通道里的数据和属性一起打包进工作区。注意它生成的变量一般是结构体字段结构和 To Workspace 略有区别取值时要看清楚。第三种也是最容易被忽略的如果你的 Simulink 模型已经配置了信号记录signal logging仿真结束后可以直接用logsout这个变量从工作区取数再通过logsout.getElement(信号名)拿到具体的信号值。适合信号链路比较复杂的模型但一次性配置比较复杂新手不太建议直接用。这里必须强调一点无论是用哪种方式导出时最好把采样时刻也带上。FFT 分析必须知道采样频率这直接决定所有频域结果是否可靠。如果只有波形数据没有时间轴那你还得根据模型参数猜测采样率——这是个很容易出大错的隐患。2.2 .mat外部数据的加载与清洗外部 .mat 文件的情况更常见也更考验基本功。数据可能是别人给你的、实验台录的也可能是上一阶段处理完的半成品。加载数据就一句话load(filename.mat)。但真正的坑在于你根本不知道里面藏了什么结构。我拿到别人 .mat 文件的第一件事不是急着滤波而是先在命令行敲whos -file filename.mat看一下里面有哪些变量、各是什么类型、维数多大。很多时候你以为是一个一维数组进去了才发现是个结构体里面还嵌套了 cell还有的时候你以为是一个通道结果是个 N 行多列的矩阵每一列代表一个工况。这一步虽然是土办法但省掉的是后面无数个 Index exceeds array bounds 的报错。第二个坑来自数据本身的质量。外部 .mat 数据经常带有直流分量、异常跳变点、NaN 空值甚至起始时刻不是 0。FFT 滤波对异常点极度敏感一个 NaN 进去整个频谱都会出问题一个大跳变点会让频谱上长出一片墙上芦苇。所以我的习惯是加载后先画一眼时域波形做一次粗略的清洗——去均值、去掉 NaN、必要时对明显毛刺做局部插值或直接切除然后再进入频域滤波流程。这里还要提醒一点如果 .mat 文件里本身就存了采样率 Fs优先从文件里读别自己瞎设。数据来源不同采样率差异可能高达几十倍搞错了截止频率就是买椟还珠。2.3 采样率和时间轴是滤波的命根子关于采样率我再多说两句。FFT 滤波看起来是频域操作但它的一切都和采样率绑定频率分辨率是 采样频率 / 数据点数奈奎斯特频率是 采样频率 / 2截止频率在频域掩膜中的位置也是靠采样率换算成对应的 FFT 索引。一个 Fs 设错所有频域坐标全盘皆错滤波结果跟蒙眼织布没有区别。特别要提醒的是 Simulink 的变步长模式Variable-step solver。如果模型用的是变步长Scope 导出数据的时间间隔可能根本不是等间隔的。FFT 分析的前提是等间隔采样如果时间轴不均匀你就得先对信号做一次重采样resample 或 interp1 转到均匀时间轴否则频谱上全是混叠出来的假峰。这也是从示波器拿数据和从理想采集卡拿数据最不一样的地方——很多同学第一次用 FFT 滤 Simulink 的波形频谱乱七八糟找半天原因最后发现是变步长导致的非等间隔采样。3. FFT滤波的原理和实现细节3.1 FFT的基本流程和频率轴上代码之前先把原理里最关键的三句话说明白。第一句对一个长度为 N 的实信号做 FFT你会得到 N 个复数这 N 个复数代表从 0 到 Fs 的 N 个频率分量但真正独立有效的只有前 N/21 个点从 0 到 Fs/2 的奈奎斯特区间后一半是前一半的镜像。第二句频率分辨率 df Fs / N意思是数据越长频域越精细两个靠得近的频率峰越能分开。第三句如果你只想保留某一个频段就在频域把对应索引的 FFT 系数乘以 1把不要频段的系数乘以 0再 IFFT 回来就实现了滤波。拿一个具体例子来算一下你可能体会更深假设信号采样率 Fs 2000 Hz数据长度 N 2000 点那么频率分辨率 df 1 Hz。这意味着你能分辨出 50 Hz 和 51 Hz 这两个频率分量的差异但如果两个分量只差 0.5 Hz就处于同一个频域槽里掰不开了。同样的 2000 点数据如果采样率是 20000 Hzdf 就变成 10 Hz想分离开 50 Hz 和 51 Hz 就不可能了。所以 FFT 滤波前先算算你的 df 够不够用这比调任何参数都重要。MATLAB 里获取频率轴的标准姿势是N length(x); df Fs / N; f (0:N-1) * df; % 完整频率轴 f_positive f(1:floor(N/2)1); % 正频部分简单解释f这个向量的第一个元素是 0 Hz直流第 N 个元素接近 Fs。fftshift可以把频谱两边搬到中间视觉上更顺眼但对滤波来说我建议你先别急着用fftshift老老实实保持 FFT 的天然顺序这样在做频域掩膜的时候索引关系更透明不容易乱。3.2 频域掩膜滤波最简单也最容易踩坑的做法频域掩膜滤波的代码骨架非常短我直接把它全量贴出来然后逐行拆解。% 假设 x 是原始信号Fs 是采样率 N length(x); X fft(x); % 频率轴 f (0:N-1) * Fs / N; % 设计掩膜以低通为例截止频率 fc 以下保留 fc 100; % 截止频率根据需求修改 H ones(size(X)); % 找到超过截止频率的位置注意同时要处理对应的负频率半轴 idx (f fc) (f Fs - fc); H(idx) 0; % 频域滤波 Y X .* H; % 逆变换回时域 y ifft(Y); y real(y); % 实信号理论上 ifft 结果虚部应为0取 real 消除浮点误差这段代码有四个细节值得抠一抠。第一H(idx) 0这行同时把正频率和负频率的高频部分都置零了这是必须的——因为实信号的频谱是共轭对称的你只清零正频率会给 IFFT 返回一个复数信号虽然real能兜底但结果跟正确清零负频是有细微差别的。第二idx的判断用(f fc) (f Fs-fc)而不是(f fc)因为如果不把负频区间的对称点处理好IFFT 回来的信号会出现严重的相位畸变和附加振荡。第三real(y)是处理浮点误差的标准姿势fft 的对称性在数值计算里不会严格成立取实部没有副作用。第四如果 N 是偶数奈奎斯特频率点索引 N/21即 f 恰好等于 Fs/2要特别对待——它对应正负频率的共用点一般把它按需求归入保留或切除区间都行但千万别忘了它。这个硬截止版本实现最简单肉眼看着很直接但实际效果往往让人皱眉滤波后的波形会有明显的振铃尤其是信号本身含有接近截止频率的能量时。原因就是我在第一章预告过的吉布斯现象——频域矩形窗对应的时域旁瓣泄漏。想缓解它就得用下一节的过渡带设计。3.3 加窗和过渡带告别吉布斯振荡解决吉布斯现象的办法不是把频谱磨得更尖反而是把截止处抹圆。形象的比喻是一刀切下去损失惨重但用一把钝刀斜着切过去切口就平滑多了。具体做法是给掩膜加过渡带。最常见的过渡带形状是线性锥形linear taper或者余弦过渡cosine taper。代码实现其实很简单不要直接把频域系数从 1 跳成 0而是让它在过渡带内平滑地降下来。比如设计一个带过渡带的低通掩膜fc1 100; % 通带截止频率 fc2 150; % 阻带起始频率过渡带宽 fc2 - fc1 f (0:N-1) * Fs / N; H ones(size(X)); % 正频部分 idx_right f fc2; idx_trans (f fc1) (f fc2); % 过渡带的余弦锥形 H(idx_trans) 0.5 * (1 cos(pi * (f(idx_trans) - fc1) / (fc2 - fc1))); H(idx_right) 0; % 负频部分做同样的处理 idx_right_neg f (Fs - fc1) f (Fs - fc2); idx_trans_neg (f (Fs - fc2)) (f (Fs - fc1)); H(idx_trans_neg) 0.5 * (1 cos(pi * ((Fs - f(idx_trans_neg)) - fc1) / (fc2 - fc1))); H(f (Fs - fc1)) 0;这段代码的细节在于过渡带的公式把过渡带映射到 [0, pi] 区间用半个余弦周期让它从 1 平滑衰减到 0。这样做了之后滤波后信号的时域旁瓣衰减会明显改善尤其适合对脉冲型信号做平滑处理输出波形不再剧烈抖动。补充一点如果你处理的信号本身带有强烈的周期噪声比如 50 Hz 工频干扰那么更精准的做法是做一个陷波掩膜只把对应频段的一个窄带清零。具体就是把上面低通掩膜的设计逻辑反过来把 45~55 Hz 附近的频段设为 0其余部分保留。这个思路跟模拟域的陷波滤波器异曲同工但实现起来比设计模拟陷波器简单一百倍而且不会引入相位失真。3.4 完整可运行的FFT滤波脚本把前面几节的零件拼装起来我给出一份在绝大多数场景都能抄作业的完整脚本。这个脚本支持两种输入Simulink 波形数据处理后的变量或者外部 .mat 数据文件。脚本里带了完整的区间选择和绘图逻辑可以直接作为滤波分析的模板使用。% % FFT滤波脚本适用于Simulink示波器导出数据或外部.mat文件 % 输入.mat文件路径 或 工作区变量 % 输出滤波后的时域信号、频谱对比图、保存后的滤波数据 % clear; clc; close all; % ---- 第1步加载数据 --------------------------------------- dataFile sim_data.mat; S load(dataFile); % ---- 第2步识别数据字段和采样率 ---------------------------- % 先whos看一眼再按实际情况改字段名 if isfield(S, time) isfield(S, signal) t S.time; % 时间轴等效采样率可变或者等间隔都行 x S.signal; % 原始信号 elseif isfield(S, t) isfield(S, x) t S.t; x S.x; else fn fieldnames(S); x S.(fn{1}); t (0:length(x)-1)/1000; % 如果没提供采样率先假设Fs1000务必回头修改 end % 如果时间轴非等间隔先重采样 dt_all diff(t); if max(dt_all) - min(dt_all) 1e-6 * mean(dt_all) Fs_resamp 1 / mean(dt_all); [x, t] resample(x, Fs_resamp, 1/mean(dt_all)); else Fs 1 / (t(2) - t(1)); end % ---- 第3步去直流 ------------------------------------------ x x - mean(x); % ---- 第4步FFT 变换 --------------------------------------- N length(x); X fft(x); f (0:N-1) * Fs / N; X_shifted fftshift(X); f_shifted (-N/2:N/2-1) * Fs / N; % ---- 第5步频域滤波参数 ------------------------------------ lowFc 0.1; % 低频截止一般保留低频时设为0.1Hz以内 hiFc 50; % 高频截止根据需求设置 tranF 10; % 过渡带宽Hz % 设计带通掩膜默认保留 lowFc~hiFc可根据需要改低通/高通 H ones(size(X)); fpos f(1:floor(N/2)1); fneg Fs - fliplr(fpos); mask_pos (fpos lowFc) (fpos hiFc); mask_neg (fneg lowFc) (fneg hiFc); H(1:floor(N/2)1) mask_pos; H(floor(N/2)2:end) flip(mask_neg(2:end)); % 注意共轭对称 % 如果带通外仍有过渡需求可以叠加锥形这里保留硬掩膜版本 Y X .* H; y real(ifft(Y)); % ---- 第6步绘图对比 ---------------------------------------- figure; subplot(3,1,1); plot(t, x); title(原始信号(时域)); xlabel(时间(s)); subplot(3,1,2); plot(f_shifted, abs(X_shifted)/N); title(原始信号(频谱)); xlim([0 200]); subplot(3,1,3); plot(t, y); title(FFT滤波后(时域)); xlabel(时间(s)); % ---- 第7步保存滤波结果 ------------------------------------- save(filtered_signal.mat, t, y, Fs); disp(滤波完成结果已保存到 filtered_signal.mat);这份脚本作为一个通用模板我特别强调第 3 步去直流的那一行别看它简单很多外部数据带一个不小的偏置不去掉直流频谱 0 Hz 位置会出现巨大的山峰把你真正关心的低频分量全部淹没。第 6 步绘图时我把频谱横轴限制在 0~200 Hz这是根据很多工程信号的常见能量集中区间的习惯设置使用时按实际场景改一下 xlim 就好。4. 实操把Simulink示波器波形完整滤一遍4.1 步骤一从Scope导出数据到工作区前面原理讲了一堆现在进入完整的实操流程。假设你现在手上有一个 Simulink 模型里面已经连好了示波器模块波形画出来是毛茸茸的带着噪声场景是要把其中的有效低频信号提取出来。第一步就是把 Scope 里的数据导到工作区。我推荐用前面提到的最利索的方式在信号线旁边放一个 To Workspace 模块双击设置如下Variable name 填sig_dataSave format 选Structure with time然后重新跑一遍仿真。跑完后工作区里面出现一个结构体sig_data它的字段结构是sig_data.time时间列和sig_data.signals.values信号数据列多通道时values会是一个 N x 通道数 的矩阵。如果你的模型跑一次很费劲不想为了取个数据重跑整个仿真那就用 Way 2在 Scope 窗口里右键选择 Log data to workspace同样可以导出来。但实测下来这个方式的坑在于Scope 本身如果设置了Limited data points限于演示模型默认可能会截断你会突然发现导出来的数据长度不是完整的仿真时间缺口会让你在 FFT 的时候发现频谱分辨率完全对不上。所以导出之后一定要先看一眼时域波形全貌再进入下一步。4.2 步骤二确认采样率和数据质量拿到sig_data之后不要急着fft先做三个检查。第一时间轴是否等间隔看diff(sig_data.time)的数值是否稳定如果不稳定要么回到模型把 solver 改成定步长固定步长要么在脚本里做 resample。我发现很多现场数据其实都是伪等间隔——solver 报告它每个步长都测试了好几次实际落盘的时刻之间有微小的抖动这种抖动在进行频谱分析时基本可以忽略但如果数据是从外部采集卡读出来的那就必须严格检查。第二信号里有没有 NaN 或异常值直接用sum(isnan(x))查一遍有就处理。这里给个土办法如果 NaN 占比很小可以直接用前后有效值线性插值补掉x fillmissing(x, linear)这种一次性离线分析插值带来的误差远小于 NaN 导致的频谱全毁。第三记录一下采样率 Fs。很多新手会犯一个滑稽的错误在 Simulink 里看到 Scope 横轴是 1000 个点就默认 Fs 1000但模型里仿真步长设定可能是 0.001 秒FS1000也可能是 0.01 秒FS100一个量的差异会让截止频率偏差 10 倍。务必从sig_data.time里用1/(t(2)-t(1))实算采样率别用猜的。4.3 步骤三滤波脚本执行过程把导出的数据填进上一节的通用脚本里一般就能直接跑出滤波结果。这时候我会做两个额外的精细操作很多人不重视但极其有用。一个是频段的试凑法。先别急着把截止频率拍脑袋定下来用脚本段的频谱图画出来看一眼能量主要聚集在哪一段、噪声的底噪大概有多高。比如你看到有用信号的峰值集中在 20 Hz 附近而噪声是一个从 100 Hz 往上逐渐抬高的斜坡那截止频率就选 50~60 Hz 附近比 20 Hz 大一点点、又能躲开主要噪声区。这个看频谱定截止的过程比盲猜靠谱得多。另一个是关于N如果数据长度特别长比如几十万点直接整体 FFT 会算得非常慢而且频率分辨率太高之后掩膜的边缘效应会被放大。这时候可以把数据分段处理每段 8192 或 16384 点分别滤波后再拼接。这种分段 FFT 滤波在医学信号、振动数据里是常态操作因为记录时长动辄十几分钟不可能一口气 FFT 全段。拼接时要注意把段和段之间留一点点重叠比如每段末尾的 100 点丢弃从下一段补回来否则接缝处会看到台阶。4.4 步骤四结果验证频域与时域双重检查滤波做完最后验证这步千万别省。我的验证套路是双轨制的先看时域波形再看频谱。时域上滤波后的波形应该平滑了噪声明显变小但不能出现两种异常一种是整体波形相对于原始波形有了整体位移或畸变这通常说明频域操作破坏了相位信息另一种是首尾出现大振幅的振荡这通常是边缘效应说明数据分段或延拓处理不到位。如果只是边缘十几二十个点有问题那基本可以接受把边角裁掉即可如果振荡延伸到波形中部就要回过头加宽过渡带或者对信号先延拓再滤波。频域上把滤波后的信号再做一次 FFT和原始频谱叠在一张图上对比。要求是通带内的谱线形状和原始信号基本一致阻带内的谱线降到底噪水平。这篇文章里我还会顺手写两个评估量滤波前后方差下降多少、信噪比提升了多少。比如snr_out 10*log10(signal_power / noise_power)算完填在报告里说服力比看图觉得干净了强得多。5. 常见问题与排查技巧实录5.1 波形首尾有突变边缘效应怎么解决这个坑我遇到太多次了。原因在前面提过FFT 滤波本质上做的是循环卷积它假设信号首尾相接是一个周期的。但真实信号的首尾值大概率不相等循环卷积的这个跳变就会被当做一个高频脉冲处理滤波结果自然在首尾长了毛刺。处理办法的最土也最有效的版本是滤波前先对信号做边缘预处理把首尾各延长一段让边界的跳变发生在真正的原始信号之外滤波后再把延长的部分裁掉。具体实现可以这样做取原始信号的前后各一段长度 M比如 M 200 点把前 200 点反向延拓到开头把后 200 点反向延拓到末尾然后对拼接后的序列做 FFT 滤波最后把两头的延拓段去掉。这个处理成本极低效果立竿见影。如果嫌麻烦也可以直接用wextendWavelet Toolbox 里的边缘扩展函数支持多种扩展模式比如sym对称扩展和per周期扩展配合滤波脚本使用非常顺手。5.2 频谱图上的“墙”和泄漏滤波效果不好的第二个常见原因是频谱图上出现了不该出现的高墙。这往往不是滤波本身的问题而是原始信号里含有强直流分量和强线谱。典型的例子是信号本身叠了个 5V 的直流偏置FFT 之后 0 Hz 处的谱线高得离谱你的纵轴范围全被它占了其余频段被压缩成地面上的小草看起来就像一堵墙。解决办法就是我反复强调的滤波前去均值。去均值不会改变交流成分的相对关系但对后续的查看和掩膜设计帮助巨大。还有一类墙是工频干扰。现场采集的数据几乎都带 50 Hz 及其谐波成分在频谱图上表现为一排等间距的尖峰。如果目标是提取低频信号直接低通滤波到 40 Hz 以下就顺手把工频干掉了但如果目标带宽本身就覆盖 50 Hz那就必须用前面提过的窄带陷波掩膜只干掉那几根尖峰别让低通的一刀切毁了有用信号。5.3 跑出来的相位不对是怎么回事有人会发现滤波后的波形比原始信号早出发了或慢半拍。这个问题的答案既简单又重要FFT 频域滤波是线性相位滤波它本身就具备零相位延迟特性——只要你和我的代码一样保证了频谱的共轭对称处理IFFT 回来之后信号相位和原始信号完全对齐不会像 IIR 滤波器那样出现明显的群延迟。那为什么你还是会觉得相位不对十有八九是时域信号里的基准时刻不对。比如采集卡从某一点才开始记录信号本身含有一个较大的初相位而你在对比时拿滤波后的信号和滤波前的信号直接叠加看到整体平移了——这其实不是滤波延迟而是取数据和去均值时没有对齐时间零点。解决办法很简单绘图时横轴都用t - t(1)以第一个采样点为 0 时刻两个波形自然就对齐了。5.4 常见问题速查表问题现象主要原因快速排查与解决方法频谱0Hz处巨大尖峰其余信号看不见信号带直流偏置x x - mean(x)去直流滤波后波形首尾剧烈振荡循环卷积的边缘效应边缘预处理/延拓滤波后裁边或用 wextend频段处理后信号出现明显虚部失真掩膜破坏共轭对称性检查负频率区间掩膜保证 H(k)conj(H(N-k))频谱分辨率太低分不开两个邻近峰数据长度 N 不足增加数据长度或降低采样率计算 df 是否够用频谱上出现一排等间距尖峰电源工频干扰窄带陷波掩膜处理 50Hz 及各次谐波数据时间轴不等间隔导致频谱脏变步长求解器或采集时钟抖动重采样到等间隔或改用定步长仿真ifft 回来虚部很大浮点误差或掩膜不对称real(ifft(Y))取实部检查掩膜对称滤波后波形幅值变小掩膜过渡带过宽或阻带误伤通带收紧过渡带核对通带增益应为1数据量很大FFT 跑很久单次 FFT 点数过多分段滤波每段8k~16k点段间留重叠这张表基本覆盖了我做 FFT 滤波以来见到的高频问题收藏起来比翻几十篇文档有用得多。最后再分享一个小技巧在实际处理 Simulink 数据时我习惯在滤波之后顺手算一个滤波前后方差比比如原始信号方差和滤波后信号方差之比。如果这个比值在 2~5 倍之间说明减噪效果明显如果比到 10 倍以上反而要警惕是不是把有效信号削掉太多了。滤波不是越干净越好关键是保留你要的那部分信息。这个分寸感只能靠多看频谱、多对比时域波形慢慢养出来。希望对正在做同样事情的你有帮助。