3、时域分析基础:均值、方差、标准差、自相关与互相关
各位同学,咱们今天聊聊时域分析。说白了,就是看信号随时间怎么变。我刚开始做嵌入式那会儿,总觉得时域分析太基础,不就是算个平均值嘛。后来踩过坑才明白,这些基础统计量,才是信号处理的真正基石。
3.1 均值——信号的直流分量
均值,大家都会算。但你知道它代表什么物理意义吗?
对于传感器信号,均值就是信号的直流分量。比如一个温度传感器,在恒温环境下采集100个点,均值就是那个温度值。但实际项目中,均值往往藏着陷阱。
均值的计算公式很简单:
μ = (1/N) * Σ x[i]
其中N是样本数,x[i]是第i个样本。嗯,就这么简单。
3.2 方差与标准差——信号的波动程度
方差衡量的是信号偏离均值的程度。标准差是方差的平方根,单位跟原始信号一致,更直观。
我个人的习惯是:先看均值,再看标准差。均值告诉你信号的中心在哪,标准差告诉你信号抖不抖。
实战经验: 在电机转速监测项目中,我通过标准差来判断电机是否平稳。正常运行时标准差很小,一旦轴承磨损,标准差会明显增大。这个指标比单纯看均值灵敏多了。
方差公式:
σ² = (1/N) * Σ (x[i] - μ)²
标准差公式:
σ = sqrt(σ²)
你想想看,如果两个传感器测同一个物理量,均值一样,但标准差不同,你会选哪个?当然是标准差小的那个,因为它更稳定。
3.3 自相关——信号与自己的相似度
自相关函数,说白了就是信号跟自己的延迟版本做对比。它告诉你信号在不同时间点上的相关性。
我记得有一次做语音信号处理,需要检测基频。用自相关函数一算,峰值位置就是基频周期,简单又有效。
自相关公式:
Rxx(τ) = Σ x[t] * x[t + τ]
其中τ是延迟时间。
实用技巧: 自相关函数在τ=0时取最大值,等于信号的能量。如果自相关函数衰减很快,说明信号是随机的;如果衰减很慢,说明信号有周期性成分。
在嵌入式系统中,自相关常用于:
- 检测信号的周期性
- 估计信号的基频
- 识别重复模式
3.4 互相关——两个信号的关系
互相关函数衡量两个信号之间的相似度。它比自相关多了一个维度——你可以比较两个不同的信号。
我做过一个项目,用两个麦克风定位声源。通过计算两个信号的互相关函数,找到峰值位置,就能算出时间差,进而定位声源方向。这个方法在嵌入式系统里很实用,计算量不大。
互相关公式:
Rxy(τ) = Σ x[t] * y[t + τ]
应用场景: 互相关在传感器融合中特别有用。比如用加速度计和陀螺仪做姿态估计,通过互相关可以分析两个传感器的时间延迟,然后做对齐处理。
3.5 实际项目中的选择策略
这么多统计量,什么时候用哪个?我给大家整理了一个表格:
| 统计量 | 用途 | 典型场景 |
|---|---|---|
| 均值 | 直流分量、基准值 | 温度测量、压力校准 |
| 标准差 | 噪声水平、稳定性 | 振动监测、故障检测 |
| 自相关 | 周期性检测 | 语音基频、心跳检测 |
| 互相关 | 信号对齐、时延估计 | 声源定位、多传感器融合 |
注意: 在嵌入式平台上,计算自相关和互相关时要注意内存和计算资源。我建议用定点数运算,避免浮点运算带来的性能开销。另外,数据长度不要超过1024点,否则实时性可能跟不上。
3.6 代码示例——嵌入式C实现
下面是我常用的一个轻量级实现,适合在MCU上跑:
// 均值计算
float calc_mean(float *data, int len) {
float sum = 0;
for (int i = 0; i < len; i++) {
sum += data[i];
}
return sum / len;
}
// 标准差计算
float calc_std(float *data, int len, float mean) {
float sum_sq = 0;
for (int i = 0; i < len; i++) {
float diff = data[i] - mean;
sum_sq += diff * diff;
}
return sqrt(sum_sq / len);
}
// 自相关(简化版)
void calc_autocorr(float *data, int len, float *result, int max_lag) {
for (int tau = 0; tau < max_lag; tau++) {
float sum = 0;
for (int i = 0; i < len - tau; i++) {
sum += data[i] * data[i + tau];
}
result[tau] = sum;
}
}
这段代码我用了好多年,简单可靠。你想想看,在资源受限的MCU上,这种实现方式最稳妥。
3.7 避坑指南
最后,分享几个我踩过的坑:
- 数据长度要足够: 样本太少,统计量没有意义。我一般要求至少100个点。
- 注意数据溢出: 在16位MCU上,累加和可能溢出。用32位变量或者分段计算。
- 去直流再算相关: 计算自相关和互相关前,先减去均值。否则结果会被直流分量主导。
- 归一化处理: 比较不同信号的相关性时,先做归一化,得到相关系数,范围在[-1, 1]之间。
嗯,时域分析基础就讲到这里。这些统计量看似简单,但用好了能解决很多实际问题。下一章咱们聊频域分析,到时候你会发现,时域和频域其实是同一枚硬币的两面。