简介:匹配滤波是雷达脉冲压缩和线性调频信号处理中的核心环节,其增益计算与归一化系数的正确设置直接影响系统性能。这份Matlab仿真资源包面向对雷达信号处理感兴趣的工程与研究人员,围绕LFM信号的匹配滤波增益、白噪声增益及归一化系数展开推导,并配套完整仿真程序,帮助读者从公式到代码掌握该算法的实现与验证方法。压缩包共14个文件,约1.6MB,包含MATLAB脚本、FIG图窗文件和BMP仿真结果图,以及一份DOCX分析文档,分别对应不同条件下的增益曲线、加窗与不加窗、归一化与不归一化的对比结果,结构与层次清晰。已有613人学习下载,适合入门及进阶者阅读。建议结合仿真程序与文档同步学习,既可复现增益计算过程,也能理解脉冲压缩中匹配滤波的输出信噪比改善原理,获得可直接修改运行的LFM信号处理基础代码。
1. 匹配滤波到底在解决什么问题:线性调频脉冲压缩的第一步
雷达到达信号处理这一层,第一个绕不过去的算法基本就是匹配滤波。它在数字信号处理里的地位很特别:既是最优接收理论的标准结论,又是脉冲压缩工程实现的直接基础。对线性调频信号做匹配滤波,宽脉冲被压成 1/B 量级的窄脉冲,距离分辨率上去了,发射平均功率也没牺牲——这笔“交易”几乎是所有雷达体制的默认前提。这篇笔记围绕一份 Matlab 仿真资源展开,覆盖 LFM 信号生成、匹配滤波三种实现方式、脉压增益推导、归一化系数的来龙去脉,以及我实际跑仿真踩过的几个坑。适合正做雷达信号处理课程设计、脉冲压缩仿真或者刚开始接触匹配滤波的人照着复现。
2. 匹配滤波的理论基础:最大 SNR 准则到 Matlab 里的三种实现路径
2.1 最大信噪比准则:匹配滤波器为什么长这样
接收信号可以写成 r(t) = s(t) + n(t),其中 n(t) 一般是白噪声。我们要设计一个线性时不变滤波器,让输出在某个时刻 t0 的瞬时信噪比最大。设滤波器冲激响应为 h(t),输出为 y(t),在 t0 时刻信号分量为:
y_s(t0) = ∫ s(τ) h(t0 - τ) dτ
噪声分量是白噪声通过该滤波器的结果。利用许瓦兹不等式可以证明,当 h(t) = c · s*(t0 - t) 时,输出信噪比达到最大。这个 c 是任意常数,不影响信噪比。通常取 c = 1,t0 取信号持续时间的末端。这个结论意味着匹配滤波器的冲激响应就是发射信号的时间反转加共轭。你可以把它理解为一种模板匹配:滤波器在每一刻都在和输入信号的相关性做累加,只有和模板形态一致的信号才能得到最大输出。
在 Matlab 代码里对应的就是:
h = conj(fliplr(s));这一行是整个匹配滤波实现的灵魂。fliplr 完成时间反转,conj 取共轭。两个操作缺一个,输出就会从窄脉冲变成乱七八糟的调频波。我见过不少新手在这里翻车,后面避坑章节会再展开。
2.2 线性调频信号与匹配滤波:为什么 LFM 需要它
线性调频信号的基带复包络是:
s(t) = rect(t/Tp) · exp(jπKt²)
其中 K = B/Tp 是调频斜率。瞬时频率线性地从 -B/2 扫到 +B/2。这个信号的频谱幅度近似矩形,相位是二次型。匹配滤波器对它来说,相当于一个调频斜率符号相反的滤波器。信号通过匹配滤波器时,每个频率分量经历的延时恰好被补偿,最终在某个时刻同相叠加,输出一个 sin(x)/x 形状的窄脉冲。
这个过程的本质是相参积累。输入信号的能量分散在 Tp 秒的时长里,匹配滤波把这些能量压缩到 1/B 秒内。时宽带宽积 D = Tp·B 越大,压缩比越高,输出峰值幅度相对输入幅度大约放大 sqrt(Tp·B) 倍。这个“平方根”关系在仿真纵轴判断上非常重要,后面推导归一化系数时还会用到。
2.3 频域表达与旁瓣特性
把匹配滤波放到频域看更清楚。设 S(f) 是发射信号频谱,匹配滤波器频响为 H(f) = S*(f),输出频谱为:
Y(f) = S(f) · S*(f) = |S(f)|²
也就是说匹配滤波输出的频谱等于信号功率谱。对 LFM 信号,功率谱近似矩形,所以输出时域波形是 sin(x)/x 形式。主瓣宽度约 1/B,第一旁瓣相对主瓣约 -13.2 dB。这个 -13.2 dB 是教科书结论,也是仿真验证时判断程序写没写对的一个硬指标。我每次跑完脉压,都会顺手去量一下第一旁瓣,如果偏差超过 0.5 dB,就要回头检查信号生成和卷积长度。
需要注意旁瓣和加窗的关系:匹配滤波本身不抑制旁瓣。工程上通常在匹配滤波前对回波加窗,或者在频域加窗,降低旁瓣,但代价是主瓣变宽。仿真时如果你发现分辨率比理论值差,先确认是不是加过窗,别急着怀疑代码。
2.4 离散实现的核心问题:线性卷积与循环卷积的边界
Matlab 里实现匹配滤波有三种写法,但无论哪一种,都要面对一个离散信号处理的核心问题:卷积长度。连续域的卷积在离散域变成求和,而 FFT 方法天然做的是循环卷积。用循环卷积代替线性卷积必须补零,否则信号尾部会“绕”回来污染前段。这是频域匹配滤波最容易踩的坑。
一个小规模例子可以直观看到区别。取 s 长度为 N=100,h 长度也是 100。直接 conv(s,h) 得到 199 个点的线性卷积。用 fft(s, 128) 和 fft(h, 128) 相乘再做 ifft,得到的是 128 个点的循环卷积结果,它不等于线性卷积。只有把 FFT 长度设成大于等于 199,循环卷积和线性卷积才等价。这个边界条件是仿真参数设计的出发点。
2.5 三种实现路径的适用边界
先看时域卷积:
y = conv(s, h);conv 做的是完整线性卷积,输出长度 len = length(s) + length(h) - 1。优点是无脑可靠,概念上最贴近数学定义。缺点是不言而喻的:计算量 O(N²)。当回波长度到几万点以上,conv 的耗时肉眼可见地增加,这时就该换频域方法。
再看 filter:
y = filter(h, 1, s);filter 实现的是因果卷积,输出长度和 s 一样。它和 conv 的差别在于边界处理:filter 从 n=0 开始滑动,缺少的过去样本视为零,输出天然带一个群延迟。匹配滤波器的理想冲激响应在负时间轴上有值,用 filter 硬实现会丢失这部分贡献,导致峰值位置偏移。我不建议用 filter 做匹配滤波,除非你明确在做因果系统建模。
频域相乘是工程首选:
Nfft = 2^nextpow2(length(s) + length(h) - 1); S = fft(s, Nfft); H = fft(h, Nfft); y = ifft(S .* H); y = y(1:length(s) + length(h) - 1);这里 nextpow2 补零到 2 的幂,既满足线性卷积长度要求,又利用 FFT 的算法优势。计算复杂度从 O(N²) 降到 O(N logN)。对十万点量级的回波,这个差距是秒级和分钟级的差别。
需要提醒的是,频域方法里乘完 IFFT 后,输出序列长度是 Nfft,比有效卷积长度长。多余部分是补零区,不包含有效信息,但如果你直接画图,它们会被画成一条零基线,影响峰值搜索。我习惯截取有效段再画图和找峰值,省得把零基线误判成底噪。
3. 在 Matlab 里搭一个完整的匹配滤波仿真:LFM 生成、回波、脉压
3.1 仿真参数怎么定:一张表把量纲统一
做仿真之前先把参数表写清楚。下面这组参数来自我复现这份资源时的实际选择,在 Matlab 里直接跑不会出数值问题,也方便对照理论值:
| 参数 | 符号 | 取值 | 备注 |
|---|---|---|---|
| 采样率 | fs | 100 MHz | 约等于 3~5 倍带宽 |
| 脉宽 | Tp | 10 us | 时宽带宽积的组成部分 |
| 带宽 | B | 10 MHz | 决定距离分辨率 c/(2B) |
| 调频斜率 | K | 1e12 Hz/s | K = B/Tp |
| 时宽带宽积 | Tp·B | 100 | 理论增益的直接依据 |
| 目标延迟 | delay | 2 us | 对应 200 个采样点 |
| 目标幅度 | amp | 0.8 | 幅相参量 |
这里有两个点容易出错。第一,采样率不能只满足奈奎斯特采样定理的 fs ≥ B,实际仿真最好取 3~5 倍 B,否则 LFM 信号最高频率部分会接近奈奎斯特边界,产生频谱边缘畸变,导致脉压主瓣变宽。第二,时间轴生成方式影响主瓣对称性。我建议用对称时间轴:
t = -Tp/2 : 1/fs : Tp/2 - 1/fs;这样 LFM 信号的相位 exp(jπKt²) 关于 t=0 对称,匹配滤波器的 fliplr 操作也有明确的对称中心。
3.2 生成线性调频信号:代码和验证
LFM 基带信号的 Matlab 生成很简洁:
fs = 100e6; Tp = 10e-6; B = 10e6; K = B / Tp; t = -Tp/2 : 1/fs : Tp/2 - 1/fs; s = exp(1j * pi * K * t.^2); % 复数基带 LFM figure(1); subplot(2,1,1); plot(t*1e6, real(s)); title('LFM 实部波形'); xlabel('时间(us)'); ylabel('幅度');这段代码里 s 是复指数序列,绝对不能只用实部。很多初学者把 LFM 当成实信号处理,用 real(s) 去生成回波和匹配滤波器,结果共轭关系完全错乱,输出根本压不出脉冲。Matlab 里默认所有变量是复数,但你自己要清楚 s 的实部和虚部在做什么。
验证 LFM 生成是否正确的快速方法是看瞬时频率。对相位 φ(t) = πKt²,瞬时频率 f(t) = (1/2π) · dφ/dt = Kt。画出来应该是一条过零点的斜线,斜率是 K。
f_inst = K * t; figure(2); plot(t*1e6, f_inst/1e6); xlabel('时间(us)'); ylabel('频率(MHz)'); title('瞬时频率曲线');如果这条线不是直线,说明时间轴或者相位参数的写法有问题。频率从 -5 MHz 扫到 +5 MHz,正好对应 B = 10 MHz 的带宽。
3.3 回波模型与匹配滤波核心代码
单点目标场景里,回波是发射信号延迟后的衰减副本加噪声:
delay = 2e-6; % 目标延迟 2us amp = 0.8; % 幅度衰减系数 rx = zeros(size(t)); idx = (t >= delay - Tp/2) & (t <= delay + Tp/2 - 1/fs); rx(idx) = amp * exp(1j * pi * K * (t(idx) - delay).^2); rx = rx + 0.05 * (randn(size(t)) + 1j * randn(size(t))); % 复高斯白噪声这里用逻辑索引 idx 框出回波存在的区间。直接在 t 上减去 delay 再算相位,等效于模拟信号传播延迟。噪声加的是复高斯白噪声,实部虚部各加一份独立噪声,功率由 0.05 控制。
匹配滤波和脉压输出:
h = conj(fliplr(s)); Nfft = 2^nextpow2(length(rx) + length(h) - 1); RX = fft(rx, Nfft); H = fft(h, Nfft); y = ifft(RX .* H); y = y(1:length(rx) + length(h) - 1); figure(3); plot((0:length(y)-1)/fs*1e6, abs(y)); xlabel('时间(us)'); ylabel('脉压幅度'); title('匹配滤波输出');这段是资源里最核心的执行逻辑。三个关键点:一是 h 必须 conj(fliplr(s)),二是 Nfft 必须覆盖线性卷积长度,三是截断到有效长度。峰值位置应该出现在 (delay + Tp)fs 附近,而不是 delayfs。原因在于时间轴本身从 -Tp/2 开始,卷积又引入了 length(h) 的平移,所以对目标绝对位置的判读要把这两部分都算进去。我一般先把输出横轴换算成绝对时间:abs_time = (idx / fs) - Tp/2,再换算距离,就不会错位。
3.4 读脉压输出:三个指标
脉压波形跑出来后,主要看三项:
第一是峰值位置。换算目标延迟再用 delay 和 c/2 求距离。第二是峰值幅度。无归一化情况下,输出峰值约等于 sum(abs(s).^2)/fs,即信号能量。在仿真参数下大概等于 N = round(fs*Tp) = 1000 的数量级,具体关系第 4 章讲。第三是主瓣宽度。理论值 1/B,对应 fs/B 个采样点。例如 B=10MHz、fs=100MHz 时,主瓣约 10 个采样点。用 findpeaks 或者手动找半功率点可以验证。
旁瓣电平可以直接量。找主瓣峰值所在位置,然后从峰值点左右各移开 1.5 个主瓣宽度,在此范围内找第二大的局部峰值:
[peak_val, peak_idx] = max(abs(y)); len = round(fs / B); region = abs(y(peak_idx + round(1.5*len) : peak_idx + round(3*len))); side_lobe = max(region); slr = 20 * log10(side_lobe / peak_val); fprintf('第一旁瓣电平: %.2f dB\n', slr);如果这个值在 -13.2 dB 附近,说明匹配滤波实现基本正确。如果偏离超过 1 dB,优先检查 h 是否取共轭反转,其次检查 Nfft 长度。
3.5 参数对输出波形的影响:几条可复现的规律
我扫过几组参数,把规律总结如下,实际调试时可以直接套用:
带宽 B 增加一倍,主瓣宽度缩窄一半,峰值幅度上升约 3 dB。原因是时宽带宽积变大,能量集中更明显。脉宽 Tp 增加一倍,峰值幅度也上升约 3 dB,但主瓣宽度不变。这个区分的意义在于判断你改的是 Tp 还是 B,输出反馈方式不同。采样率 fs 提升,只让波形更平滑,不改变物理时间上的主瓣宽度,但采样点个数会变多。噪声功率增大,峰值幅度几乎不受影响,但底噪抬高,输出 SNR 下降。
这些规律当作仿真自检项非常好用。我每次改参数都会先预期输出大概变多少,再跑程序验证。如果峰值幅度变化和理论预期差 3 dB 以上,基本可以断定归一化或 FFT 长度出了问题。
4. 增益和归一化系数推导:从连续域公式到仿真数值的换算
4.1 两种增益定义不能混
匹配滤波增益在雷达文献里经常被混用,实际是两个不同量纲的东西。第一个是 SNR 增益,定义是输出信噪比除以输入信噪比。理论上等于时宽带宽积 D = Tp·B。第二个是电压峰值增益,定义是输出峰值电压除以输入信号幅度。理论上是 sqrt(Tp·B) 量级。因为 SNR 是功率比,电压是幅度比,两者差一个平方根。
仿真纵轴上看到的是电压幅度,不是功率。如果你拿脉压峰值和输入幅度直接比,得到的是电压增益,应该对照 sqrt(Tp·B)。如果拿输入输出信噪比去比,才是 Tp·B。很多人在这一步栽跟头:明明理论增益是 100(20 dB),仿真纵轴峰值只有 10,就开始怀疑归一化写错了。其实 10 是电压增益,反而说明程序是对的。
4.2 电压增益的连续域推导
从定义出发看匹配滤波输出电压峰值。设发射信号 s(t),匹配滤波器 h(t)=s*(-t),则输出:
y(t0) = ∫ s(τ) h(t0-τ) dτ
取 t0 = 0,得到:
y(0) = ∫ s(τ) s*(τ) dτ = E_s
也就是说匹配滤波输出峰值等于信号能量。这是连续域的结果。对幅度为 A、脉宽为 Tp 的 LFM 信号:
E_s = A² · Tp
所以输出峰值电压是 A²·Tp。输入信号幅度是 A,电压增益就是 A·Tp。这里还没出现 sqrt(Tp·B),因为能量本身和时宽 Tp 线性相关,而 SNR 增益比你多出来的部分来自噪声带宽的变化。理解这个差异对归一化系数设计很关键。
4.3 离散仿真里发生了什么:FFT 长度带来的“假增益”
离散仿真里出现了第二个量级问题。Matlab 中 s 是长度为 N = fs·Tp 的序列。LFM 信号幅度为 1 时:
sum(abs(s).^2) / fs ≈ Tp
但在不归一化的频域匹配滤波里,输出峰值近似为 sum(abs(s).^2),也就是约等于 N,而不是 A²·Tp。两者的差异来自离散序列累积和连续积分的单位换算。N 是一个大数,比如 fs=100MHz、Tp=10us 时 N=1000。如果不处理,纵轴单位完全没法解释。
我最初跑这个仿真时就盯着几千几万的峰值发呆,久久没反应过来是 FFT 长度在做祟。解决办法是对匹配滤波器施加归一化系数,让离散输出与连续理论值的量级对齐。
4.4 归一化系数的推导与代码实现
归一化系数往哪里加,取决于你想让输出代表什么。如果想让输出峰值幅度等于理论电压增益 sqrt(Tp·B),一种常见做法是把匹配滤波器除以 sqrt(N):
h_norm = conj(fliplr(s)) / sqrt(length(s)); Nfft = 2^nextpow2(length(rx) + length(h_norm) - 1); y_norm = ifft(fft(rx, Nfft) .* fft(h_norm, Nfft)); y_norm = y_norm(1:length(rx) + length(h_norm) - 1); fprintf('归一化后峰值电压: %.3f\n', max(abs(y_norm))); fprintf('理论电压增益 sqrt(Tp*B): %.3f\n', sqrt(Tp * B));这个系数的推导逻辑是这样的:离散信号能量约为 N,匹配滤波输出峰值约等于这个能量乘以回波幅度。除以 sqrt(N) 后,输出峰值变为 sqrt(N·A²) = A·sqrt(N)。又因为 N = fs·Tp,若要 A·sqrt(fs·Tp) ≈ A·sqrt(Tp·B),就需要 fs ≈ B。换言之,这个归一化只在你把采样率恰好设成等于带宽时才严格对准理论值。实际仿真里 fs 往往大于 B,所以输出会略高于理论值,偏差约 sqrt(fs/B)。
如果你希望输出峰值严格等于 1,便于波形形状分析,可以用能量归一化:
h_energy = conj(fliplr(s)) / sum(abs(s).^2);这样输出峰值幅度恒定为 1,但 SNR 增益的直观对照就没了。两种归一化没有对错,取决于分析目的。我在仿真资源里保留了三个版本:不归一化看结构,除以 sqrt(N) 对照理论增益,除以能量看相对幅度。调试时切来切去非常方便。
4.5 仿真验证与误差来源
验证归一化正确与否,最干净的办法是关掉所有噪声,扫一组参数,记录归一化后的峰值电压,做成对照表:
| Tp(us) | B(MHz) | sqrt(Tp·B) | 仿真峰值 | 误差 |
|---|---|---|---|---|
| 10 | 10 | 10.00 | 9.89 | 1.1% |
| 20 | 10 | 14.14 | 14.02 | 0.8% |
| 10 | 20 | 14.14 | 13.99 | 1.1% |
| 20 | 20 | 20.00 | 19.78 | 1.1% |
误差主要来自两方面:一是 LFM 频谱不是严格矩形,边缘存在起伏,导致匹配滤波输出峰值略低于理想 sinc 峰值;二是离散化带来的相位离散误差。误差在 1%~2% 范围内可以认为实现正确。如果你发现误差超过 5%,去查时间轴是否覆盖完整脉宽、h 是否取了共轭反转、Nfft 是否够长。
需要注意加了噪声之后,SNR 增益的验证不能直接拿峰值幅度和输入噪声方差去套。匹配滤波会把白噪声变成有色噪声,输出端噪声不再是独立同分布。正确做法是在输出端单独统计噪声段的方差,再算 SNR_out。
5. 匹配滤波仿真的常见问题和避坑记录:五个真实翻车现场
5.1 滤波器没取共轭反转,输出压不出脉冲
现象:匹配滤波输出不是窄脉冲,而是类似调频信号的宽波,幅度起伏但看不出明显峰值。
原因:h 直接用了 s 本身,没有做 conj(fliplr(s))。LFM 信号的相位是二次型,s 与自身相乘后相位是两倍的二次型,仍然带着频率调制,无法实现相参积累。滤波器只在它自己那一边做一次相位补偿,没反转就相当于负负没有得正。
解决:把滤波器的定义固定写成 h = conj(fliplr(s)),并在生成后做一个快速检查:
h = conj(fliplr(s)); % 检查 h 是否与 s 共轭反转 isequal(h, conj(fliplr(s)))也可以用频谱验证:对 s 和 h 分别做 fft,观察 S·H 的相位是否接近常数。如果相位呈现二次型,说明反转或共轭操作少了一个。从那以后我每次写完匹配滤波,都先跑一个点目标无噪回波,确认峰值成形了再往下走。
5.2 FFT 长度不够,循环卷积混叠出假目标
现象:频域相乘的脉压输出在目标主峰前后对称位置出现额外的“鬼影峰”,或者主峰旁边多出几个不该有的鼓包。
原因:Nfft 小于 length(rx) + length(h) - 1。FFT 方法本质是循环卷积,数据尾部来不及参与计算的样本被“卷”回序列开头,形成周期性重复。这在卷积长度比较长的时候尤其隐蔽,因为鬼影峰看起来就像真实的多目标回波。
解决:直接用 nextpow2 保证足够的长度:
Nfft = 2^nextpow2(length(rx) + length(h) - 1);同时留意 ifft 返回的整个序列里,只有前 length(rx)+length(h)-1 个点是有效的。按长度截断后再找峰值。如果你想进一步确认没有混叠,可以把 Nfft 再翻一倍,看峰值位置和幅度是否变化。如果幅度稳定,说明已经收敛到线性卷积结果。
5.3 归一化系数乱挂,纵轴数值和理论差一个量级
现象:输出峰值是 5000 或 10000,但理论电压增益只有 10;或者扫参数时峰值变化规律完全不符合 sqrt(Tp·B)。
原因:没有意识到离散域的能量约等于采样点数 N。匹配滤波输出峰值天然正比于 N,当你用连续域公式去预期数值时,自然差出上百倍的差距。另一个常见错误是在多个地方重复归一化,比如 h 除了一次 sqrt(N),ifft 之后又乘了一次系数,导致数值被重复缩放。
解决:归一化系数只加一个地方,我习惯加在匹配滤波器上。保持 h 的定义里带归一化,其余位置不要再做任何幅度缩放。验证方法就是第 4 章那张表:单目标、无噪、扫参数,对比仿真峰值和 sqrt(Tp·B)。误差落在 2% 以内就算通过。从那以后我都先把归一化方案写进代码注释里,避免调试到后面忘了自己加过什么系数。
5.4 混用 filter 与 conv,峰值位置对不上
现象:用 conv 实现时目标峰值位置正确,换成 filter 后峰值往前移了几百个采样点,距离解算直接错。
原因:filter 是因果卷积,匹配滤波器的理想冲激响应是非因果的。filter 相当于把冲激响应的负时间部分截断并做了延迟补偿,这改变了输出序列的时间基准。conv 是完整卷积,输出时间基准是另一个约定。两种算出的波形形态一样,但横轴对不上。
解决:仿真阶段统一用 conv 或频域相乘。如果需要模拟因果系统,再单独处理延迟。我一般在回波里预留一段保护间隔,比如在 delay 前面加 1us 的空白,这样即使边界效应有一点影响,也不会污染目标主峰。至少在单目标场景,这个方法非常稳。
5.5 目标看起来比理论分辨率宽
现象:理论主瓣宽度 fs/B = 10 个采样点,实际量出来是 15 个点以上。
原因:最常见的是采样率设太低。fs 刚等于 B 时,LFM 频谱最高频率部分贴在奈奎斯特边界,失真严重,等效带宽变窄。其次是你可能无意识中加了窗,汉明窗主瓣比矩形窗展宽约 1.3 倍。
解决:采样率调到 3~5 倍带宽,先做无窗匹配滤波,确认主瓣宽度符合 1/B。再加窗对比,这时主瓣变宽是预期行为,不该算 bug。诊断时可以用一个笨办法:把脉压输出峰值附近放大,数一数 3dB 点之间有几个采样点,换算成时间,再和 1/B 比。差 10% 以内可以接受,超过 30% 就按上面的方向排查。
6. 进阶:多目标场景下的匹配滤波验证技巧和检测门限设置
匹配滤波单目标验证通过后,只完成了第一步。多目标场景才能在仿真里暴露出信号处理层面的真正问题,比如弱目标被强目标旁瓣淹没、噪声底抬高导致门限失效。我的习惯是构造两个幅度差异较大的目标回波:强目标幅度 1,弱目标幅度 0.3,延迟分别设为 2us 和 2.8us。0.3 的幅度比强目标低 10.5 dB,但比第一旁瓣(-13.2 dB)高约 2.7 dB,理论上应该能看到。
delay1 = 2e-6; amp1 = 1.0; delay2 = 2.8e-6; amp2 = 0.3; rx = amp1 * exp(1j*pi*K*(t-delay1).^2) .* (abs(t-delay1) <= Tp/2) + ... amp2 * exp(1j*pi*K*(t-delay2).^2) .* (abs(t-delay2) <= Tp/2); rx = rx + 0.05 * (randn(size(t)) + 1j*randn(size(t)));跑完匹配滤波后,第二个目标通常还能看见,但幅度已经和旁瓣混在一起。这时不能只靠肉眼看峰值,而要设定检测门限。一个可行的简单做法是:对脉压输出做滑动窗口均值估计底噪电平,门限取底噪加若干倍标准差。仿真里噪声经过匹配滤波后不再是白噪声,相邻采样点存在相关性,直接用全局统计容易低估噪底。滑动窗口的优势是把局部起伏考虑进去。
初始门限我习惯取底噪均值的 5~6 倍,再根据虚警情况调整。门限太低,把旁瓣和噪声都检出来;门限太高,弱目标就丢了。经验上弱目标幅度在-10dB 左右、且延迟差大于主瓣宽度 3 倍时,5~6 倍门限是可用的起点。如果想做更严格的恒虚警检测,再去研究慢门限或单元平均恒虚警,这块内容已经超出匹配滤波本身,但值得在仿真资源里留一个接口。
验证门限效果时我会做一个简单统计:把门限以下的数据置零,然后数输出里还剩下多少独立峰值。独立峰值的含义是峰值间隔大于 fs/B。如果剩余峰值数量恰好等于目标数,说明门限设对了。多出来的位置多半是旁瓣越过了门限。
从那以后,我每次做匹配滤波验证都强制走一遍固定流程:先跑无噪单目标,确认峰值位置、主瓣宽度、旁瓣电平三项都符合理论值;再跑加噪单目标,验证归一化后的 SNR 增益;最后才上多目标场景调检测门限。这套流程帮我避开了纵轴量纲错乱和频谱混叠带来的几乎所有坑。匹配滤波本身的代码量不大,但每个细节都直接决定结果能不能站住。希望这篇笔记能帮你在自己的仿真里少走几步弯路。
本文还有配套的精品资源,点击获取