第二章 雷达信号处理基础:脉冲压缩、多普勒处理、CFAR检测、点迹与航迹形成

各位同学,欢迎来到雷达目标识别的核心基础课。说实话,很多搞机器学习的同行一听到「雷达信号处理」就头大,觉得全是傅里叶变换和滤波器。但我得说,如果你不懂这些底层处理,你后面做的目标识别模型,很可能就是个「空中楼阁」。

我个人习惯把雷达信号处理比作「从噪声里捞针」。你想想看,目标回波那么弱,干扰那么多,怎么把它干净地捞出来?这就是我们今天要聊的四个关键步骤。

2.1 脉冲压缩:既要远,又要精

雷达有个天生的矛盾:想看得远,就得发大能量,那就得用长脉冲。但长脉冲会让距离分辨率变差。怎么办?

脉冲压缩就是来解决这个矛盾的。它用宽脉冲发射,保证能量够大;接收时再用匹配滤波,把脉冲「压」窄,恢复出高分辨率。

核心思想:发射大时宽带宽积信号(如线性调频信号),接收时通过匹配滤波,将宽脉冲压缩为窄脉冲。

我在项目中遇到过一件事:某次外场试验,目标距离很近,但雷达就是分不清是两个目标还是一个。后来一查,脉冲压缩没做好,旁瓣把目标淹没了。嗯,这里要注意,脉冲压缩后会有旁瓣,得加窗函数抑制。

常用的窗函数有:

  • 汉明窗:旁瓣抑制好,但主瓣会变宽一点
  • 布莱克曼窗:旁瓣更低,但主瓣更宽
  • 凯泽窗:可调参数,灵活

说白了,这就是个取舍问题。你要旁瓣低,就得牺牲一点分辨率。

% 脉冲压缩示例(MATLAB风格)
% 发射线性调频信号
T = 10e-6;          % 脉冲宽度 10us
B = 10e6;           % 带宽 10MHz
fs = 2*B;           % 采样率
t = -T/2:1/fs:T/2;
s = exp(1j*pi*B/T*t.^2);  % LFM信号

% 匹配滤波
h = conj(fliplr(s));       % 匹配滤波器
y = conv(s, h);            % 脉冲压缩输出

我的小技巧:实际工程中,脉冲压缩通常在频域做,用FFT实现,效率高得多。但要注意,频域卷积会有循环卷积效应,记得补零。

2.2 多普勒处理:动目标检测的命根子

雷达不光要知道目标在哪,还得知道它动没动、怎么动。多普勒效应就是干这个的。

为什么会这样?因为目标运动会让回波频率发生偏移。偏移量正比于径向速度。我们通过一组脉冲的相位变化,就能把速度算出来。

我记得刚入行时,师傅跟我说:「多普勒处理,说白了就是沿着慢时间维做FFT。」当时觉得太简单了,后来才发现,这里面坑不少。

多普勒处理的关键参数:

参数 含义 我的经验
PRF(脉冲重复频率) 每秒发射的脉冲数 PRF决定了不模糊速度范围,选高了距离模糊,选低了速度模糊
相参积累时间 处理用的脉冲个数 × PRI 积累时间越长,速度分辨率越高,但目标可能跨距离单元走动
多普勒滤波器组 通常用FFT实现 点数不够可以补零,但补零不提高分辨率,只是插值

避坑指南:我曾经在某个项目中,目标速度很快,但PRF设得太低,结果多普勒模糊了,把高速目标误判成了低速目标。后来加了多普勒解模糊算法才搞定。记住:PRF的选择一定要考虑目标的最大可能速度。

2.3 CFAR检测:自适应门限的艺术

信号处理完了,怎么判断有没有目标?简单粗暴的做法是设个固定门限。但现实中的噪声和杂波是变化的——海面杂波、地杂波、气象杂波,强度忽高忽低。

CFAR(恒虚警率检测)就是解决这个问题的。它根据背景噪声自适应地调整门限,保证虚警率恒定。

常用的CFAR方法:

  • CA-CFAR(单元平均):取参考窗的平均值做门限。均匀背景效果好,但杂波边缘会出问题。
  • GO-CFAR(选大):取左右参考窗中较大的那个。适合保护杂波边缘。
  • SO-CFAR(选小):取较小的那个。适合多目标环境。
  • OS-CFAR(有序统计):排序后取第k个值。抗干扰能力强,但计算量大。

你想想看,如果目标旁边还有个强目标,CA-CFAR会把强目标也算进背景里,门限抬高了,弱目标就漏了。这时候OS-CFAR就好使。

关键参数:参考窗长度、保护单元数、虚警概率Pfa。Pfa设得太低,门限高,漏警多;设得太高,虚警多,后端处理压力大。我个人习惯Pfa取10^-6到10^-4之间,具体看场景。

# Python风格的CFAR伪代码
def ca_cfar(rd_map, guard_cells, ref_cells, pfa):
    # rd_map: 距离-多普勒图
    # guard_cells: 保护单元数
    # ref_cells: 参考单元数
    # pfa: 虚警概率
    
    alpha = ref_cells * (pfa**(-1/ref_cells) - 1)  # 门限因子
    threshold = np.zeros_like(rd_map)
    
    for i in range(ref_cells, rd_map.shape[0] - ref_cells):
        for j in range(ref_cells, rd_map.shape[1] - ref_cells):
            # 取参考窗(排除保护单元)
            window = rd_map[i-ref_cells:i+ref_cells+1, 
                           j-ref_cells:j+ref_cells+1]
            # 去掉保护单元
            # ... 省略具体实现
            noise_power = np.mean(window)
            threshold[i, j] = alpha * noise_power
    
    detections = rd_map > threshold
    return detections

我的经验:实际工程中,CFAR的参考窗大小很讲究。窗太小,估计不准;窗太大,计算量大,而且背景可能不均匀。我一般取参考单元数在16-32之间,保护单元取2-4个。

2.4 点迹与航迹形成:从散点到轨迹

CFAR检测完,我们得到了一堆「点迹」——每个点迹包含距离、多普勒、角度、幅度等信息。但这些点迹是散乱的,可能来自同一个目标,也可能是虚警。

点迹凝聚:把相邻的检测点合并成一个。为什么要做?因为一个目标可能跨多个距离单元和多普勒单元,不合并的话,一个目标会变成一堆点。

航迹形成:把不同时刻的点迹关联起来,形成目标的运动轨迹。这一步通常用卡尔曼滤波或粒子滤波。

我记得有个项目,目标在强杂波区,CFAR出来几千个点迹,但真正的目标只有两三个。航迹起始算法如果太激进,会生成大量虚假航迹;太保守,又会漏掉真实目标。

常用的航迹管理方法:

  • 最近邻关联:简单粗暴,找最近的。适合稀疏场景。
  • 概率数据关联(PDA):考虑所有可能关联的概率。适合中等密度。
  • 多假设跟踪(MHT):维护多个假设,延迟决策。适合高密度、复杂场景。

避坑指南:我曾经在航迹起始时,用了太小的速度门限,结果把静止杂波也起始成了航迹。后来加了「速度一致性检验」——连续几帧的速度方向和大小要一致,才把虚假航迹滤掉。记住:航迹起始要保守,航迹维持要灵活。

小结

好了,这一章的内容就这些。脉冲压缩让你看得清,多普勒处理让你看得懂动没动,CFAR让你在变化的环境中稳定检测,点迹航迹让你从散点变成连续轨迹。

这四个步骤,是雷达目标识别的「前菜」。后面的机器学习模型,都是在这四个步骤的输出上做文章。如果你连这些基础都不懂,那你做的模型再花哨,也是「无源之水」。

下一章,我们会聊怎么用机器学习来做目标分类。到时候你会发现,前面这些信号处理的质量,直接决定了分类的上限。嗯,今天就到这里,有问题随时问我。