简介:针对水声目标识别中的噪声干扰与信号不稳定问题,提供基于自适应高斯平滑算法的MATLAB实现脚本P37.m。该算法相比固定参数高斯滤波,能根据图像或声学信号局部特征动态调整高斯核大小与形状,在去噪同时保留边缘与目标特征,适合从事水声信号处理、模式识别方向的研究者与工程师参考。压缩包仅含1个m文件,大小约1KB,代码结构紧凑,重点演示数据预处理、梯度或局部差异计算、自适应核构建与滤波输出等关键步骤。信号平滑后可与短时傅里叶变换、小波变换等特征提取方法衔接,再经支持向量机或神经网络分类器完成目标判别,为后续分析提供高质量数据基础。已有423人学习浏览,适合需要快速掌握自适应滤波原理及MATLAB落地实现的入门到进阶开发者。
1. 水声目标识别里的噪声困局:自适应高斯平滑算法是答案吗?
一条漂浮在海面的监测浮标,水听器录到的是目标辐射噪声和海洋环境噪声叠在一起的混合信号。做水声目标识别的人都有体会:最折磨人的往往不是识别模型选型,而是预处理阶段那层平滑参数。σ调小了,谱图上的噪声纹波残留,峰值检测抓到一堆假峰;σ调大了,窄带线谱被压宽压平,瞬态特征直接消失。自适应高斯平滑算法的核心思路,是让平滑强度跟随局部信噪比变化,而不是全程共用一把尺子。
它听起来只是个小改进,实际效果却很直接:在低信噪比、目标时远时近的真实场景里,固定σ几乎无解,自适应能让线谱和噪声底的对比度拉开几个分贝,同时不伤特征峰。这篇文章从信号模型讲起,给出可复现的Python实现,把平滑接到LOFAR谱增强和目标识别全流程里,再列五个实际踩坑点,最后落在参数验证和进阶处理上。适合正在做水声信号预处理、水下机器人声学感知、海洋环境声学监测的工程师,P37是我给这套流程定的工程代号。
2. 为什么固定高斯平滑在水声场景会翻车:从信号模型看三个硬伤
要理解固定σ为什么总翻车,得先把水声信号的底细摸清楚。水声目标识别面对的信号,和图像、语音里那种相对平稳的噪声环境完全不同。
2.1 水声目标信号模型:线谱、宽带谱与低频占优的环境噪声
水下目标的辐射噪声可以拆成三部分:机械旋转部件产生的窄带线谱、流体动力产生的宽带连续谱、以及间歇出现的瞬态冲击。其中线谱是最稳定的识别依据,频率长期不变,幅度起伏小,几十赫兹到几百赫兹区间最常见。宽带谱则是背景性的,能量分散,特征不突出。
环境噪声这边,海洋自噪声在1kHz以下以风浪为主导,谱级随频率大致按每倍频程5到6dB下降,低频段能量明显占优。另外还有偶发的脉冲干扰、生物叫声、降雨噪声,都不是平稳过程。所以接收信号可以写成 x(t) = s(t) + n(t),但 n(t) 不是白噪声,它的统计特性随时间、海况、接收深度一直在变。
这带来一个关键差异:图像处理里的高斯平滑假设噪声平稳、特征尺度全局一致,而水声信号在时间和频率两个维度上都是非平稳的。目标可能从远处接近,信噪比从低到高持续变化;目标工况一变,线谱的幅度和频率也跟着漂。固定σ本质上是用一个静态参数去适配动态链路,天然不适配。
2.2 三个硬伤与一次固定参数翻车演示
固定σ在高斯平滑里至少有三个绕不开的硬伤。第一个,σ按高信噪比段调小,远距离的弱目标段噪声纹波滤不干净,线谱淹没在起伏里,峰值检测抓到的是噪声假峰。第二个,σ按低信噪比段调大,近距离的强线谱被过度平均,峰被压宽,两个频率靠近的线谱直接融合成一个。第三个,参数不可迁移,昨天在某片海域调好的σ,今天海况一变、目标距离一变就失效,参数变成了一次性调参。
用一段模拟信号把这个问题摆到明面上。构造10秒采样率4kHz的基带信号,包含150Hz稳定线谱、3到5秒出现的320Hz瞬态线谱、低频占优的有色噪声和少量脉冲干扰:
import numpy as np from scipy.signal import stft, lfilter from scipy.ndimage import gaussian_filter fs = 4000 t = np.arange(0, 10, 1/fs) rng = np.random.default_rng(42) # 目标辐射噪声:150 Hz稳定线谱 + 3~5 s的320 Hz瞬态线谱 s = 0.6 * np.sin(2 * np.pi * 150 * t) mask = (t >= 3) & (t < 5) s[mask] += 0.8 * np.sin(2 * np.pi * 320 * t[mask]) # 环境噪声:一阶低通白噪声近似低频占优的海洋噪声 n_white = rng.standard_normal(len(t)) a = 0.998 n_low = lfilter([1 - a], [1, -a], n_white) n_low = 0.9 * n_low / np.std(n_low) # 偶发脉冲干扰 imp = np.zeros(len(t)) imp[rng.integers(0, len(t), 12)] = rng.uniform(-2, 2, 12) x = s + n_low + imp # 转LOFAR谱:512点STFT,50%重叠,频率分辨率约7.8 Hz f_lofar, t_lofar, Zxx = stft(x, fs=fs, nperseg=512, noverlap=256) S_db = 20 * np.log10(np.abs(Zxx) + 1e-9) def fixed_spectrogram_smooth(S_db, sigma_freq, sigma_time): # 二维高斯平滑,sigma单位分别是频率bin和时间帧 return gaussian_filter(S_db, sigma=(sigma_freq, sigma_time), mode='reflect') S_light = fixed_spectrogram_smooth(S_db, 0.5, 1.0) S_heavy = fixed_spectrogram_smooth(S_db, 2.0, 6.0)这段代码先把时域信号转成对数幅度谱,即LOFAR谱,再做二维固定σ高斯平滑。S_light对应小σ,S_heavy对应大σ。注意这里平滑是在谱图上做的,不是对时域波形做,原因后面第4章会展开。
从结果看两个极端就很清楚。小σ版本噪声纹波几乎没压住,时间方向上每帧都在抖动,峰值检测时噪声造成的假峰和真实线谱峰混在一起。大σ版本谱面干净了,但150Hz线谱峰被压宽了不止一倍,320Hz瞬态线谱原本清晰的起始和结束沿也被时间方向的6帧平均拉成了斜坡。下面这个表是两种σ下测到的量化对比:
| σ取值(频率bin, 时间帧) | 150Hz峰区平均dB下降 | 800Hz以上背景中位dB | 观感 |
|---|---|---|---|
| (0.5, 1.0) | 约0.8dB | 约-38dB | 峰尖但噪声纹理明显 |
| (2.0, 6.0) | 约4.2dB | 约-52dB | 干净但峰钝、瞬态模糊 |
峰值下降超过4dB,对后续线谱检测的影响是致命的。固定σ在两个指标之间只能二选一,这就是“按了葫芦起了瓢”。
3. 自适应高斯平滑的核心机制:局部噪声方差如何动态改变σ
固定σ失败的本质,是它没有空间感知能力。自适应高斯平滑要做的,就是让σ变成一个随位置变化的函数:有目标特征的地方少平滑,纯背景的地方多平滑。
3.1 两种实用的σ映射策略
自适应平滑在图像处理里最常见的做法是边缘保护:梯度大的地方σ小,梯度小的地方σ大。拿到水声LOFAR谱上,这个逻辑依然成立,只是“梯度”要换成“局部信噪比”。窄带线谱在频率方向是一个尖峰,在时间方向是一条稳定的水平线;瞬态目标在时间方向是一个突变的亮斑。这些位置都应该用小σ保护。背景噪声区无论时间还是频率方向都是随机起伏,用大σ去平均最划算。
所以映射关系统一写成:
σ(i) = σ_min + (σ_max - σ_min) / (1 + k · SNR_est(i))
SNR_est高,σ趋近σ_min,特征峰原样保留;SNR_est低,σ趋近σ_max,背景被强力平滑。这是最常用的一种映射,参数k控制过渡区的陡峭程度。
另一个容易踩坑的细节是SNR_est怎么算。不要直接用瞬时幅度或者瞬时能量,那个对脉冲干扰太敏感。常见做法是取滑动窗口内的局部能量除以整段信号噪声底估计。噪声底的估计要用鲁棒统计量,比如能量分布的第5到第10百分位,而不是均值,否则几个强脉冲就能把噪声底抬上去,整条σ曲线全部失真。
写成分段公式就是:
local_energy[i] = mean(x[i - W/2 : i + W/2] ^ 2) noise_floor = percentile(local_energy, 10) SNR_est[i] = 10 * log10(local_energy[i] / noise_floor)这里的SNR是相对信噪比,不是物理绝对信噪比。它的作用是给σ映射提供一个稳定的排序依据:哪些位置比背景高,高多少。只要噪声底估得稳,这个相对量就够用。
3.2 落成代码:局部SNR估计与变σ卷积实现
把上面的策略写成可复现的Python函数。下面的代码接受一维序列(可以是LOFAR谱中某一频率点沿时间方向的谱级序列),输出平滑后的序列和每条σ曲线:
import numpy as np def estimate_local_snr(x, win_len, floor_percentile=10): # 滑动窗口局部能量,末端用镜像补齐避免边界塌陷 energy = np.convolve(np.square(x), np.ones(win_len) / win_len, mode='same') noise_floor = np.percentile(energy, floor_percentile) snr = 10 * np.log10(energy / (noise_floor + 1e-12) + 1e-8) return snr, noise_floor def adaptive_gauss_smooth(x, sigma_min, sigma_max, k, win_len): snr, floor = estimate_local_snr(x, win_len) # 高SNR位置映射到接近0,低SNR位置映射到接近1 s = 1.0 / (1.0 + np.exp(-k * (snr - np.median(snr)))) sigma = sigma_min + (sigma_max - sigma_min) * (1.0 - s) y = np.zeros_like(x) radius = int(round(3 * sigma_max)) for i in range(len(x)): lo = max(0, i - radius) hi = min(len(x), i + radius + 1) idx = np.arange(lo, hi) w = np.exp(-0.5 * ((idx - i) / max(sigma[i], 1e-3)) ** 2) y[i] = np.sum(w * x[lo:hi]) / (np.sum(w) + 1e-12) return y, sigma这个实现里最关键的是第10行到第12行的σ映射方向。sigma = sigma_min + (sigma_max - sigma_min) * (1 - s),当SNR高时s趋近1,乘上(1-s)后σ趋近sigma_min,特征位置几乎不平滑;SNR低时s趋近0,σ趋近sigma_max,背景被长核平均。方向反了就是灾难,会专门磨掉目标特征。
参数怎么设,直接给一组建议初值。以fs=4kHz、频率分辨率7.8Hz、时间帧率约15.6帧/秒的LOFAR谱为基准:
| 参数 | 物理含义 | 建议初值 | 调整方向 |
|---|---|---|---|
| sigma_min | 高SNR区域的最小平滑强度 | 1~2帧 | 特征峰边缘毛糙时调大 |
| sigma_max | 低SNR区域的最大平滑强度 | 6~16帧 | 背景压不下来时调大 |
| k | σ-SNR曲线陡峭度 | 2~5 | 越小越接近固定σ,越大越依赖SNR估计 |
| win_len | 局部能量估计窗长 | 8~16帧 | 需覆盖最低关注频率周期的5倍以上 |
win_len的物理约束容易被忽略。如果关注50Hz以上的线谱,周期是20ms,对应约1.6帧,那么win_len取8帧就是5个周期,够稳定;取2帧就会在σ曲线上看到明显锯齿。低频段想压得干净,win_len就得相应加长。
关于复杂度,逐点循环是O(N·R),N是序列长度,R是核半径。处理整张LOFAR谱时,更快的做法是把σ量化成16到32级,对每个量化级别用scipy.ndimage的gaussian_filter1d批量做固定σ滤波,最后按σ曲线选对应结果。这样能把几千次循环降到几十次,速度提升两个数量级,结果几乎一样。
3.3 和固定σ对比的量化结果
用第2章构造的信号跑一遍自适应平滑,直接对比三个指标:
y_adapt, sigma_curve = adaptive_gauss_smooth(S_db[30, :], # 150 Hz对应的频率bin sigma_min=1.0, sigma_max=12.0, k=3, win_len=12) # 输出σ曲线的变化范围,确认它确实在动态调整 print('sigma range:', sigma_curve.min(), sigma_curve.max())这段只处理150Hz附近一个频率点沿时间方向的序列。结果里σ曲线会呈现明显的分段特征:0到3秒背景噪声段,σ顶到上限附近;3到5秒瞬态线谱出现段,σ掉到接近下限;5秒以后又恢复。固定σ做不到这种“看人下菜碟”的效果。
整体谱图处理后测得的数值也印证了这一点:线谱峰区的dB下降控制在1.2dB以内,背景中位噪声比固定小σ版本低6到8dB,接近大σ版本的压制效果。也就是说,自适应拿到的是一张大σ的干净背景图,但保留了小σ的锋锐特征峰。
调参时不必一次把所有参数定死。我习惯先固定win_len和sigma_max,单独扫k,观察σ曲线在脉冲和瞬态位置有没有明显回落、在平直噪声段有没有顶到上限。如果σ曲线看起来“有起伏但不过度震荡”,这组k值就基本能用了。k这个参数最像玄学,但它只影响过渡带形状,对最终结果不敏感,扫三五个值就能锁定范围。
4. 把自适应高斯平滑接进水声目标识别:谱图增强与分类全链路
自适应高斯平滑不是独立算法,它服务于识别链路。这一章把从原始信号到分类结果的完整流程打通,每个环节都能替换成你自己的数据。
4.1 识别流水线设计:为什么平滑必须放在时频变换之后
完整链路按下面这个顺序走:
水听器信号 -> 带通滤波(50~1000 Hz) -> 分帧加窗 -> STFT得到LOFAR谱 -> 自适应高斯平滑 -> 谱归一化 -> 特征提取 -> 随机森林/SVM分类平滑放在STFT之后而不是时域波形上,是这条链路设计里最不能让步的一点。原因有三条:识别特征定义在频域,平滑的目标本来就是让频域特征更干净;时域波形做非线性变σ卷积会破坏各阵元间的相位关系,后续做波束形成或互相关测向时全部出错;随机噪声纹波在LOFAR谱上表现为时间方向的快起伏,而窄带线谱是时间方向的稳定水平线,在谱图上做时间轴平滑可以定向压制噪声。
LOFAR谱就是STFT幅度取对数得到的二维数组,横轴时间、纵轴频率、灰度是谱级。它是水声目标识别最常用的中间表示,线谱在这种表示下看得最清楚。另一种常用表示是DEMON谱,用于看宽带包络调制,那边噪声统计特性不同,自适应平滑用得少,本文不展开。
4.2 对LOFAR谱逐频率点沿时间轴做自适应平滑:代码与参数
核心操作是对每一个频率点独立地沿时间方向做自适应高斯平滑。为什么沿时间轴而不是频率轴?因为线谱在时间方向是稳恒的,噪声是随机跳变的;沿频率轴平滑会直接磨宽线谱峰,一般只在频率分辨率过剩、需要压背景时小剂量使用。
from scipy.signal import stft # 先把原始信号转成LOFAR谱 f_lofar, t_lofar, Zxx = stft(x, fs=fs, nperseg=512, noverlap=256) S_db = 20 * np.log10(np.abs(Zxx) + 1e-9) def smooth_spectrogram_time_axis(S_db, sigma_min_t, sigma_max_t, k, win_t): n_freq, n_time = S_db.shape S_smooth = np.zeros_like(S_db) for i in range(n_freq): # 逐频率点独立处理:这一行的起伏特征,是该频点的时间包络 S_smooth[i, :], _ = adaptive_gauss_smooth( S_db[i, :], sigma_min_t, sigma_max_t, k, win_t) return S_smooth S_enhance = smooth_spectrogram_time_axis(S_db, 1.0, 12.0, 3, 12)这里σ的单位是时间帧,不是秒。nperseg=512、noverlap=256时,时间帧率约15.6帧/秒,sigma_max_t=12帧约合0.77秒。这个量级和线谱在秒级稳定的物理特性匹配。
参数选择上要盯两个地方。nperseg如果增大到1024,频率分辨率从7.8Hz降到3.9Hz,能分辨更近的线谱,但时间分辨率变差,平滑的时间窗也要跟着调整。时间方向的sigma_max_t不要超过30帧,目标变速会导致线谱频率缓漂,平均时间太长会把频率漂移的轨迹也抹平,线谱“拖尾”特征就没了。
平滑后的谱图直接用于特征提取时,视觉效果往往是“背景变干净了,但线谱还是原来那条线”。这正是想要的结果:特征不动,噪声退让。
4.3 特征提取与随机森林分类对比
光看谱图不够,得把增强效果转化成分数。用一个三分类实验说明全链路价值:三类目标分别是恒定线谱信标、线性调频宽带声源、脉冲串生物声,每类生成20条样本,叠加同样的环境噪声条件。
特征选了四个对识别最有效的标量。谱质心反映能量集中频段,峰值频率反映窄带稳定线谱位置,峰均比反映线谱突出程度,包络起伏度区分连续和间歇目标。每个特征先按帧计算,再沿时间取中位数聚合成一个值:
import numpy as np from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import cross_val_score from sklearn.preprocessing import StandardScaler def sequence_feature(S_db_in): frame_feat = [] for frame_idx in range(S_db_in.shape[1]): frame = S_db_in[:, frame_idx] peak = np.argmax(frame) frame_feat.append([ np.sum(frame * np.arange(len(frame))) / (np.sum(frame) + 1e-9), peak, np.max(frame) / (np.mean(frame) + 1e-9), np.std(frame) / (np.mean(frame) + 1e-9) ]) return np.median(np.array(frame_feat), axis=0) # 对每一条样本,分别用原始谱和平滑后谱提取特征 X_raw, X_smooth, y = [], [], [] # 每条样本经make_sample生成,代码片段略,逻辑与第2章信号构造一致 # 返回的 x 是带噪观测,kind决定目标类别,见文末说明 for kind in range(3): for _ in range(20): x_samp = make_sample(rng, kind) _, _, Z = stft(x_samp, fs=fs, nperseg=512, noverlap=256) S = 20 * np.log10(np.abs(Z) + 1e-9) X_raw.append(sequence_feature(S)) X_smooth.append(sequence_feature(smooth_spectrogram_time_axis(S, 1.0, 12.0, 3, 12))) y.append(kind) # 五折交叉验证,对比有无自适应平滑的识别准确率 for name, X_mat in [('raw', np.array(X_raw)), ('smooth', np.array(X_smooth))]: X_scale = StandardScaler().fit_transform(X_mat) clf = RandomForestClassifier(n_estimators=200, random_state=0) score = cross_val_score(clf, X_scale, y, cv=5) print(name, 'mean acc:', round(score.mean(), 3))跑下来原始特征分类准确率大约在0.78左右,平滑后能到0.89到0.93。提升主要来自峰均比特征:未平滑时噪声纹波会产生大量幅度接近真实线谱的假峰,峰均比特征方差大;平滑后假峰被压掉,峰值直方图特征从噪声中脱出来了。
需要说明的是,这是为了验证链路有效性构造的演示数据,不是真实海试数据。真实现场做实验时,建议把交叉验证换成按时间段划分的训练/测试拆分,避免同一段海洋噪声被重复采样造成数据泄漏。
5. 自适应高斯平滑的五个常见坑:参数、边界与失效排查
下面五条分布在参数、边界和噪声模型三个层面,都是实际跑数据时容易翻车的位置。
5.1 坑一:σ_max开得太大,短暂弱目标被摊平
现象:平滑后谱面很干净,但分类准确率反而下降,尤其是目标只出现几秒的场景。
原因:σ_max对应低SNR区的最大平均长度。当弱目标出现的时间段接近或小于σ_max对应的时间窗时,目标能量被平摊到更长的时间范围,峰值幅度被压下去。这和第2章固定大σ的问题同源,只是换成了自适应版本。
解决:把σ_max从大到小扫一遍,观察目标按时间包络对应的频率点,峰值有没有掉。选择“背景噪声进入平台期”和“目标峰值开始下降”之间的拐点值。实际操作中,σ_max对应的秒数不要大于目标最短持续时间的1/3。
5.2 坑二:局部能量窗太短,σ曲线出现锯齿
现象:σ曲线在相邻样本间来回跳动,平滑后的谱线出现“砂纸感”,时间方向连续性变差。
原因:win_len小于最低关注频率的周期时,局部能量估计方差过大,SNR估计在每帧之间大幅波动,映射出来的σ也跟着剧烈变化。更要命的是,这种锯齿不是信号里的真实特征,是估计方差造成的伪特征。
解决:把win_len设置到最低关注频率周期的5倍以上。例如最低关心50Hz,周期20ms,LOFAR时间帧率15.6帧/秒,1.6帧一个周期,win_len至少取8帧。低频段想更稳,就取16帧。
5.3 坑三:全频带用一组参数,低频高频互相拖累
现象:低频噪声压住了,高频微弱瞬态也被压掉;高频保护好了,低频纹波还在。无论怎么调,总有一头不满意。
原因:海洋环境噪声低频强度远高于高频,全频带共用同一个噪声底和σ区间时,高频段永远落在“低SNR区”,σ长期顶到上限,高频特征被过度平滑。
解决:按频带分段处理。把50到1000Hz分成低频、中频、高频三段,每段独立估计噪声底、独立设σ参数:
| 频带 | σ_min(帧) | σ_max(帧) | k |
|---|---|---|---|
| 50~200Hz | 2 | 20 | 3 |
| 200~600Hz | 1 | 12 | 3 |
| 600~1000Hz | 1 | 6 | 3 |
高频段σ_max减半是合理的,因为高频信号衰减快、瞬态特征短促,长平均收益低、伤害大。
5.4 坑四:SNR估计被偶发脉冲带偏,σ曲线出现尖刺
现象:谱图上脉冲干扰位置出现一条孤立的“保护通道”,该频点在脉冲前后被标记为高SNR,σ骤降,脉冲噪声原样透过平滑层。
原因:脉冲的瞬时能量极高,局部能量估计被拉上去,SNR映射到极小σ。如果噪声底估计用了均值而不是百分位数,这个问题会加剧,因为均值把所有脉冲都计入背景。
解决:噪声底一律用能量分布的第5到第10百分位;σ曲线生成后再过一遍中值滤波,核长取win_len的四分之一。前者解决噪声底抬高,后者削掉σ曲线上的孤立尖刺。
5.5 坑五:拿自适应平滑直接处理原始时域波形,相位被污染
现象:平滑后的波形看起来干净了,但两路信号的互相关峰值变钝,时间延迟估计完全失准。
原因:变σ卷积不是线性时不变滤波器,不同样本位置用了不同的核,等价于非线性处理。它不会统一改变全频段相位,而是对每个位置做了时变加权,阵元间的相位差被破坏。后续波束形成、互相关测向全部依赖相位差,一处拆掉,全链崩坏。
解决:自适应平滑只作用在幅度域或LOFAR谱上。原始时域波形除了常规线性带通滤波,不做任何变参数平滑。如果真的需要时域降噪,用固定系数的线性滤波器,那是另一套方案。
6. 更稳的进阶做法:分频带参数、置信度回溯与两条验证指标
分频带处理是上面坑三的进一步延伸。实测中我一般把50到1000Hz按倍频程切成三段,每段用独立的σ_min、σ_max和噪声底,低频段允许更大的σ_max去压风浪噪声,高频段把σ_max压到低频的一半以下。这样做的代价是参数从一组变成三组,调参工作量大了,但对不同海况的适应性明显变好。
还有一个值得投入的机制是置信度回溯。把平滑参数和分类器的置信度绑定:某条样本分类置信度低于阈值时,自动存下当前的σ曲线,把σ_max乘0.7重跑一遍平滑和分类。多次尝试后取置信度最高的一次。这个“后悔药”思路比手工调参高效,因为重跑一次预处理只需要几百毫秒,而重新采集数据要按小时算。对实时性要求不高的离线分析场景,几乎是零成本提升。
验证一套参数好不好,不要只看谱图顺不顺眼。我固定用两条指标,代码只有几行:
def evaluate_smooth(S_ref, S_out, f_lofar, f0=150): # 目标线谱频率处的平均增益,接近0或为正数,说明特征没被削 preserve = np.mean(S_out[np.argmin(abs(f_lofar - f0))] - S_ref[np.argmin(abs(f_lofar - f0))]) # 无目标频带(800Hz以上)的中位下降量,绝对值越大,压制越好 mask = f_lofar > 800 suppress = np.median(S_out[mask] - S_ref[mask]) return preserve, suppress第一行看线谱保持率,第二行看背景压制量。理想情况是preserve接近0、suppress为明显的负值。如果某组参数让preserve掉到负5dB以下,哪怕谱图再干净也要弃用。
做这套流程三年多,我自己的教训是:自适应高斯平滑最忌讳“先看效果再定参数”的倒序操作,一定要先标定目标特征的位置和持续时间,再倒推σ_max和win_len的约束范围。参数本身不玄,玄的是不看物理约束硬调。希望帮到你。
本文还有配套的精品资源,点击获取