
简介针对4D毫米波雷达在实际应用中静态杂波干扰动态目标检测的痛点这份算法资源面向雷达感知、自动驾驶、交通监控等方向的算法工程师与研究者聚焦静态目标与动态目标的区分、识别与滤除可用于改善多目标跟踪和检测精度。整包仅348KB共2个文件1个MATLAB脚本.m实现静态杂波滤波核心流程1个.mat数据文件存放用于验证算法的角度/回波测试数据可快速加载运行并观察处理前后效果。目前已有2019人学习下载属于轻量而典型的算法参考资料。读者既能从脚本中理解静态目标去除的完整信号处理链路与参数设置也能借助附带数据复现实验对比不同场景下的滤波结果在此基础上还可进一步尝试用CFAR、高斯混合模型或深度学习网络替换或融合原有方法开展算法改进与性能调优。 在实验室调77GHz毫米波雷达的时候我遇到的第一道坎就是静态目标去除。走廊里空无一人点云图上却是密密麻麻的一片——墙、消防栓、门框、天花板和金属支架全被雷达当成目标亮了出来。等真人走进来反而被这堆静态杂波淹得找不着北。这是所有做毫米波雷达信号处理的人迟早要面对的问题雷达天生不挑食凡是能反射电磁波的东西它都想报到点云里而静止物体占了绝大部分。这篇内容就围绕着毫米波雷达静态目标去除算法展开把原理、实现和工程里的坑一次性讲清楚。适合正在调雷达的算法工程师、做车载或安防感知的开发者以及刚入门信号处理方向的学生。1. 静态目标为什么是毫米波雷达的头号干扰1.1 回波模型所有反射物都在给雷达发消息FMCW体制的毫米波雷达发射chirp信号接收回波与发射信号混频后得到中频信号。每一个距离单元上的回波幅度和相位记录的是该距离上所有反射体的矢量和。静止目标墙、地、桌椅、金属立柱的回波在连续多个chirp之间几乎不变相位保持恒定运动目标的距离在变化回波相位会按多普勒频率持续旋转。所以把同一个距离bin上的慢时间序列拉出来看静止目标表现为一个基本不动的直流分量运动目标则是一个不断旋转的复数向量。静态目标去除要做的事就是这个常量从慢时间序列里滤掉同时尽量保留运动目标的旋转分量。听起来不复杂但雷达信号处理的所有麻烦都藏在尽量这两个字里。1.2 静态目标在距离-多普勒图上的样子距离FFT做完之后、多普勒FFT尚未进行时静止目标在每个chirp上的复数值几乎完全一样。跨chirp做多普勒FFT能量就集中在零速度bin多普勒索引0附近。多个不同距离上的静止目标叠加在一起会在距离-多普勒谱的零速度位置形成一条横贯整个距离维的亮线。如果多普勒FFT之前不做任何处理这条亮线会一直压在CFAR检测门限之上。就算目标检测算法勉强绕开了它窗函数旁瓣泄漏也会把零速度附近的底噪整体抬高让附近低速目标的信噪比直往下掉。1.3 不去除会引发什么连锁反应静态杂波不处理后面每一级都在给前面填坑。第一强静态杂波会抬高CFAR参考窗的均值检测门限被拉高弱目标直接被淹没。第二静态点云持续出现在同一位置跟踪器要反复处理这些固定虚假航迹计算量上升数据关联开始出错。第三测角阶段如果静态反射体和目标处于同一距离-多普勒单元相位不平衡会引入角度估计偏差。第四在多目标场景静止目标和运动目标回波耦合目标分离和聚类算法都会失效。所以静态目标去除不是锦上添花的前处理而是整个感知链条的地基。2. 三条去除路线MTI对消、多普勒置零与背景相消2.1 三条路线的工作原理处理静态目标工程上有三类主流思路。第一类是MTI动目标指示对消。在慢时间维对相邻chirp做差分两脉冲形式是 y[n] x[n] - x[n-1]。静止目标前后chirp相同直接减没了运动目标因为相位旋转差分后还有残留。从滤波角度看这相当于一个高通滤波器传递函数 H(z) 1 - z^{-1}在直流处有一个零点。第二类是多普勒置零法。先把2D-FFT做完在距离-多普勒谱上把零速度bin附近的若干行直接清零或压低权重。这个方法直观粗暴适合快速验证但问题不少后文会专门讲。第三类是背景相消法。维护一个随时间缓慢更新的背景模型当前帧减去背景帧得到前景。工程上常用指数加权平均B[n] α·B[n-1] (1-α)·X[n]再用X[n] - B[n]作为输出。α取0.9~0.99之间控制背景更新速度。2.2 三种方法的核心差异与选型方法运算量静态抑制效果低速目标影响典型场景MTI对消极低高有凹口低速明显衰减车载、运动目标速度较高的场景多普勒置零低中取决于清零bin范围快速原型验证背景相消中高瞬时运动目标几乎不受影响环境缓慢变化的场景选型时最容易犯的错误是拿着一种方法套所有场景。MTI对消对低速目标不友好背景相消对长时间静止目标吸收多普勒置零则受限于频谱泄漏。实际产品里往往不是只用一种而是组合用MTI先打掉固定强反射背景相消再处理缓慢漂移的杂波残留。2.3 我为什么优先推荐MTI如果只让我选一种实现我会选MTI。原因有三实时性好每个chirp只做一次复数减法和一次复数存储完全可以在DSP或MCU上实时跑参数少主要就是PRT和阶数效果可预期幅度响应曲线一画哪里衰减多少都算得出来。背景相消需要额外维护背景帧内存和定时逻辑都更复杂在安防场景里还经常出现人坐着不动被判无人的bug。多普勒置零虽然简单但速度分辨力不够时低速目标和静态目标会挤在同一个bin里一置零就把活目标也杀了。所以多数情况下MTI是那个不会错太多的答案。3. MTI对消器从原理到代码距离FFT后逐chirp相消3.1 两脉冲对消的幅度响应凹口到底有多宽两脉冲对消的传递函数 H(z) 1 - z^{-1}在单位圆上的幅度响应是 |H(f)| 2|sin(π·f·PRT)|其中f是多普勒频率PRT是chirp重复周期。f 0时幅度为0静止目标被彻底抑制f增大后增益上升直到 f·PRT 1/2 时达到最大值2。这个响应曲线意味着MTI会在零速度附近形成一个凹口凹口的宽度直接由PRT决定。我举个例子。77GHz雷达波长约3.9mmPRT 100us。一个速度0.25m/s目标的多普勒频率 fd 2v/λ ≈ 512.8vv0.25时约为128Hz。此时归一化频率 fd·PRT 0.0128两脉冲对消的增益 |H| 2|sin(π×0.0128)| ≈ 0.08也就是幅度只剩8%大约-22dB。一个0.25m/s的慢速目标在这种参数下基本被削没了。这说明MTI不能随便用在室内低速场景上参数前必须先把幅度响应曲线画出来确认你要关心的最小目标速度落在可接受的区间内。3.2 三脉冲对消边界更陡但噪声也放大更多为了加深静态抑制工程上常用三脉冲对消y[n] x[n] - 2x[n-1] x[n-2]传递函数 H(z) (1 - z^{-1})^2。在直流处变成了二阶零点零速附近的抑制比两脉冲更陡。对同一个0.25m/s目标三脉冲增益 |H| 4sin^2(π×0.0128) ≈ 0.0065约-44dB。所以三脉冲对极低速目标几乎是赶尽杀绝。代价也明显白噪声通过两脉冲对消后方差变为2倍通过三脉冲后变为6倍。阶数越高杂波压得越狠噪声也抬得越高。三脉冲适合强地杂波且目标速度较高的车载场景室内弱杂波场景反而两脉冲更稳妥。3.3 处理链位置与C代码实现MTI放在距离FFT之后、多普勒FFT之前。原因有两个。距离FFT之后每个bin对应一个距离单元跨chirp做差分针对的是某个距离上的静态反射物理意义清晰如果提前到ADC域做差分不同距离的回波混叠在一起根本减不干净。放到多普勒FFT之后再做那就成了频域置零失去了对幅度响应曲线的控制。下面是两脉冲MTI的C语言实现。数据在距离FFT之后是复数按chirp优先、距离bin次之的方式排布。// 两脉冲MTI对消 // data_in[chirp * num_range_bins range_bin] 为复数 // 输出写入 data_outchirp从0开始 for (int range_bin 0; range_bin num_range_bins; range_bin) { for (int chirp 1; chirp num_chirps; chirp) { int idx_cur chirp * num_range_bins range_bin; int idx_prev (chirp - 1) * num_range_bins range_bin; data_out[idx_cur].re data_in[idx_cur].re - data_in[idx_prev].re; data_out[idx_cur].im data_in[idx_cur].im - data_in[idx_prev].im; } // 第一个chirp没有prev直接置零 int idx_first range_bin; data_out[idx_first].re 0.0f; data_out[idx_first].im 0.0f; }三脉冲对消的代码几乎一样只是差分系数变成1、-2、1// 三脉冲MTI对消 for (int range_bin 0; range_bin num_range_bins; range_bin) { for (int chirp 2; chirp num_chirps; chirp) { int idx_cur chirp * num_range_bins range_bin; int idx_prev1 (chirp - 1) * num_range_bins range_bin; int idx_prev2 (chirp - 2) * num_range_bins range_bin; data_out[idx_cur].re data_in[idx_cur].re - 2.0f * data_in[idx_prev1].re data_in[idx_prev2].re; data_out[idx_cur].im data_in[idx_cur].im - 2.0f * data_in[idx_prev1].im data_in[idx_prev2].im; } // 前两个chirp没有足够的参考置零 data_out[range_bin].re 0.0f; data_out[range_bin].im 0.0f; data_out[num_range_bins range_bin].re 0.0f; data_out[num_range_bins range_bin].im 0.0f; }第一、二个chirp的输出置零会损失少量积累但chirp数达到128时损失不到1.6%对多普勒FFT输出几乎无影响。4. 实测躲不开的四个坑泄漏、误伤、吞人、折叠4.1 坑一多普勒置零为什么不彻底——频谱泄漏如果跳过MTI直接在2D-FFT后的距离-多普勒谱上把零速度bin清零会发现静态目标在邻近几个bin还有明显残留。这是窗函数旁瓣泄漏造成的。矩形窗第一旁瓣只有-13dB静态目标强度足够高时旁瓣照样压过检测门限。解决方法是加窗汉明窗或汉宁窗可以把旁瓣压到-40dB左右残留范围显著缩小。但加窗会降低多普勒分辨率本来能分开的两个低速目标可能就糊在一起。所以多普勒置零适合快速验证不太适合对低速分辨有要求的工程实现。4.2 坑二低速目标被凹口误伤——PRT像天平两端上文已经算过PRT100us、波长3.9mm时2.24m/s以下的目标在两脉冲MTI后增益都低于-3dB0.25m/s目标被压掉22dB。如果做室内人体活动检测这个结果会让检测率惨不忍睹。要保留更低速度的目标可以增大PRT但代价是最大无模糊速度 Vmax λ/(4·PRT) 下降。PRT1ms时凹口-3dB点降到约0.22m/s但Vmax只有0.975m/s目标再快一点就会出现多普勒模糊。所以选PRT是一场天平游戏一头是低速保留能力另一头是最大可测速度。产品需求里必须明确最小可检测速度再反推PRT和MTI阶数不能拍脑袋定。4.3 坑三背景相消把静止的人吞掉——存在性检测要另想办法这是我在人体存在雷达项目里踩得最深的坑。背景相消对瞬时运动目标几乎没有杀伤力效果很好但人一旦在工位上坐几分钟不动就会被指数加权背景模型逐步吸收从前景里消失。对判断房间有没有人这种需求静态目标去除的静态定义需要重新画墙和家具是真正要去的静态目标而坐姿或睡姿的人虽然宏观静止但呼吸带来的胸腔起伏会产生毫米级的微动回波相位以呼吸频率0.2~0.5Hz周期变化。处理的关键不是把零速度整个挖掉而是区分完全不变的分量和带微动的准静止分量。做法上可以对慢时间序列做带通滤波保留下呼吸频率附近的微弱调制而不是简单的高通差分。把人当墙滤掉正是智能存在检测误判无人的典型原因。4.4 坑四相位噪声与速度折叠静态目标回波在理想情况下恒定不变但实际雷达存在相位噪声近距离强反射体的相位噪声会把能量扩散到周围多普勒binMTI也只能压掉一部分零速度附近仍然有残余底噪。处理办法是优化锁相环配置降低相位噪声或者在MTI之后再做一次频域杂波图抑制。另一个容易被忽略的问题是速度折叠。高速目标的多普勒频率超过PRF/2时会折叠到低速区正好落进MTI凹口里被误杀。解决思路是先解速度模糊再做静态抑制或者在雷达参数设计阶段保证目标最大速度在无模糊范围之内。工程上见过不少系统用了MTI之后突然丢目标查到最后都是速度折叠搞的鬼。5. 去除静态目标之后的下游算法与效果验证5.1 CFAR与测距测速的变化MTI之后距离-多普勒谱的零速度带不再是一条亮线CFAR参考窗的均值恢复正常检测门限随之降下来弱目标更容易被发现。测速方面速度本身由多普勒峰的位置决定MTI对目标幅度的衰减不会改变峰位但由于信噪比下降峰值估计的抖动会变大。测距不依赖多普勒维基本不受影响。需要留意的是MTI对噪声统计特性的改变。两脉冲对消让白噪声功率翻倍三脉冲变成六倍。噪声底抬高了CFAR的恒虚警率设计要按处理后的噪声方差重新标定否则虚警率会比理论值高不少。5.2 点云、跟踪与深度学习检测的衔接4D毫米波雷达输出点云时很多方案会在点云级再做一次速度门限把速度绝对值接近零且位置长时间不变的点剔除作为信号级MTI的兜底。如果前面已经做了MTI这个门限可以设得很小只清理漏网的杂点。跟踪器侧静态点去除后航迹起始率会明显改善匈牙利数据关联的歧义也少了。给深度学习检测模型喂点云时静态点大量存在会让标注语义混乱同一点云在A帧是背景在B帧又出现在目标框里训练出来的特征会互相打架。所以模型输入的预处理链路里静态目标去除是必须前置的步骤。5.3 可复现的定量评估方法静态目标去除到底有没有生效我习惯用三组指标来验证。第一静态点数量占比。固定机位采集一段场景处理前90%以上的点云来自静止物体处理后应降到个位数。第二目标对比度。取目标所在的距离-多普勒bin算目标幅度与周围噪声底之比。两脉冲MTI处理前后这个对比度在目标速度远离凹口时通常能提升几dB到十几dB。第三虚警率。跑一段无人的固定场景统计CFAR输出点数量MTI之后应大幅下降。这三组数据建议固化到自动化测试里。每次改参数、换场景都跑一遍能快速暴露口碑问题比人工盯点云图像靠谱得多。我现在的习惯是在代码库里固定一个静态目标去除独立模块默认两脉冲MTI参数表里放PRT、最小目标速度、噪声底估计。每次换场景先画出幅度响应曲线确认低速目标增益在可接受范围再决定是继续用两脉冲、换成三脉冲还是改用均值相消加背景更新的组合方案。代码本身只有几十行真正花时间的永远是参数和场景的匹配。最后再提醒一句静态目标去除不是越强越好它能去掉墙也能去掉一个坐了十分钟的活人。先搞清楚你的应用到底要检测什么再决定对静止下多重的手。本文还有配套的精品资源点击获取