3. 时域预处理:数据清洗、异常值剔除、缺失值插补、时间戳对齐
各位好,咱们接着聊IMU数据预处理。上一章讲了频域滤波,但说实话,很多噪声问题在时域就能解决大半。我做了这么多年惯导,发现一个规律:时域预处理做得好,后面滤波能省一半力气。今天咱们就聊聊数据清洗、异常值剔除、缺失值插补和时间戳对齐这四个核心环节。
3.1 数据清洗——先把脏数据筛出去
什么叫脏数据?说白了就是那些明显不对劲的采样值。比如加速度计突然跳了个100g,或者陀螺仪在静止时输出漂到了100°/s——这明显是传感器抽风了。
我个人习惯,拿到原始数据第一件事不是滤波,而是先做一次粗筛。怎么筛?很简单:
- 物理范围检查:加速度计输出不能超过±16g(看量程),陀螺仪不能超过±2000°/s。超出直接标记为无效。
- 变化率检查:相邻采样点变化不能太离谱。比如1ms内加速度变化超过10g,这基本是跳变噪声。
- 零值检查:连续出现多个0值?大概率是传感器掉线了。
重要经验:我在项目中遇到过,某次无人机试飞数据里,加速度计Z轴连续出现了3个0值。当时没在意,结果积分后速度直接飞了。后来加了零值检测,这类问题再没出现过。
3.2 异常值剔除——别让一个坏点毁了整段数据
异常值和脏数据不太一样。脏数据是明显超出物理范围的,异常值则是在合理范围内但统计上离群的点。比如静止状态下,加速度计输出应该在1g附近,突然冒出来个1.5g——这就是异常值。
我常用的方法有三种:
| 方法 | 原理 | 适用场景 |
|---|---|---|
| 3σ准则 | 超出均值±3倍标准差的值视为异常 | 数据近似正态分布时 |
| 中位数绝对偏差 | 基于中位数的稳健统计量 | 数据有较多离群点时 |
| 滑动窗口法 | 局部窗口内检测离群点 | 非平稳信号(如运动数据) |
嗯,这里要注意:千万别用全局统计量去检测运动数据中的异常值。你想想看,无人机在做剧烈机动时,加速度变化本来就大,用全局3σ会把正常机动信号当异常剔除掉。
我的建议:对于运动数据,用滑动窗口法。窗口大小取50-100个采样点,窗口内用中位数绝对偏差检测。这样既能剔除真正的异常点,又不会误伤正常信号。
代码实现其实很简单:
def detect_outliers_mad(data, window=50, threshold=3.0):
"""基于滑动窗口的中位数绝对偏差异常检测"""
outliers = np.zeros_like(data, dtype=bool)
for i in range(window, len(data) - window):
segment = data[i - window:i + window]
median = np.median(segment)
mad = np.median(np.abs(segment - median))
if mad == 0:
continue
if np.abs(data[i] - median) / mad > threshold:
outliers[i] = True
return outliers
3.3 缺失值插补——数据断了怎么办?
IMU数据缺失的原因很多:通信丢包、缓存溢出、传感器掉电。我见过最夸张的一次,某款低成本IMU在高温下会间歇性丢数据,丢得还挺规律——每100个点丢2个。
缺失值处理,我按优先级排序:
- 线性插值:最简单,适合短时间缺失(1-5个点)。精度够用。
- 样条插值:适合缺失段较长(5-20个点),能保持平滑性。
- 前向填充:用上一个有效值填充。适合静止或匀速运动场景。
- 模型预测:用ARIMA或卡尔曼预测。适合长段缺失,但计算量大。
避坑指南:我曾经在某个项目中,对缺失的陀螺仪数据用了线性插值。结果插值后的角速度在缺失段出现了明显的"平顶"现象,导致后续姿态解算出现了漂移。后来改用样条插值,问题解决了。
记住:陀螺仪数据对平滑性要求高,尽量用高阶插值。
3.4 时间戳对齐——多传感器融合的命门
这个坑我踩过不止一次。IMU、GPS、视觉传感器各自有独立的时钟,采样频率也不一样。如果不做时间戳对齐,融合出来的结果就是一团浆糊。
时间戳对齐的核心思路:
- 统一时间基准:所有传感器的时间戳都转换到同一个时钟域。我习惯用IMU的时间作为主时钟。
- 插值对齐:将低频传感器(如GPS,10Hz)的数据插值到IMU的时间轴上(如200Hz)。
- 延迟补偿:不同传感器有固定的处理延迟,需要测量并补偿。
举个例子,GPS和IMU融合时:
def align_timestamps(imu_time, gps_time, gps_data):
"""将GPS数据插值到IMU时间轴上"""
from scipy.interpolate import interp1d
f = interp1d(gps_time, gps_data, kind='linear',
bounds_error=False, fill_value='extrapolate')
return f(imu_time)
这里有个细节:插值方法的选择要看应用场景。如果是实时系统,用线性插值就够了,计算快。如果是后处理分析,可以用三次样条,精度更高。
我的经验:时间戳对齐最容易被忽视的是延迟补偿。我曾经在车载导航项目中,发现GPS和IMU融合后的位置总有个固定的滞后。后来一查,GPS模块内部有50ms的处理延迟,补偿后效果立竿见影。
3.5 本章知识体系
下面这张图总结了时域预处理的完整流程,大家可以对照着梳理自己的处理流程:
这张图把整个流程串起来了。从原始数据开始,先做数据清洗,把明显不对的点筛掉;然后做异常值剔除,把统计离群点处理掉;接着处理缺失值,把数据补全;最后做时间戳对齐,为后续的多传感器融合打好基础。
每一步都有对应的技术手段,大家在实际项目中可以根据数据质量灵活选择。比如数据质量好的时候,可以跳过清洗直接做异常检测;数据缺失严重的时候,插补方法要选保守一些的。
最后说一句:时域预处理没有标准答案,关键是要理解你的数据特点。我见过有人把预处理做得特别复杂,结果反而引入了新的误差。记住一个原则:够用就好,别过度处理。