
简介均匀直线阵常规波束形成CBF是阵列信号处理中的基础技术常用于无线通信、雷达与声纳系统通过控制各阵元相位差实现信号定向增强与干扰抑制。该资源面向学习天线阵列与波束形成的初学者或工程师提供可直接运行的MATLAB脚本用于演示方位谱图分析、权矢量计算及波束扫描等核心流程。压缩包共2个文件均为.m格式包含时域CBF与主程序两个模块整体仅2KB轻量易读适合快速上手和修改实验。已有1695人学习下载实用性得到初步验证。通过运行代码读者可直观理解均匀直线阵的相位控制原理观察不同指向下的波束形成效果并以此为基础拓展到更复杂的自适应波束形成算法。1. 均匀直线阵的常规波束形成为什么“对准”一个方向其他方向的声音就变小了把几个麦克风排成一条直线不做任何 fancy 处理只把每路信号加个延迟再求和——这就是常规波束形成Conventional Beamforming, CBF。听起来像个“加法和延迟”的小把戏但它是阵列信号处理里最底层的基石一个 8 元均匀直线阵ULA阵元间距半波长就能把某个方向的来波增益抬高到 8 倍同时把正交方向的增益压到接近零。这个现象反直觉的地方在于系统里没有任何一个滤波器在“削”信号你只是把同一份声音的多个副本对齐相加干涉本身就完成了空间滤波。CBF 值得搞懂不仅因为它是 MVDR、自适应波束形成、ESPRIT 这类高级算法的起点更因为它的“缺陷”非常说明问题主瓣宽度由阵列孔径决定、栅瓣由阵元间距决定、旁瓣电平由窗函数决定。这三个结论没有一个是靠“调参”能绕过去的它们刻在阵列的物理几何里。这篇文章从“为什么延迟求和能定向”讲起一直拆到 CBF 的数学结构、仿真实现、以及那些让你在工程里翻车的细节。2. 从“延迟求和”到空间滤波CBF 的核心机制2.1 远场模型为什么一个来波可以看成一束平行线均匀直线阵的经典假设是远场声源距离阵列足够远波前到达阵列时近似为平面波。这意味着从某个方向来的信号到达每个阵元的路径差只取决于方向角和阵元间距与声源距离无关。设阵元间距为 (d)来波方向与阵列法线的夹角为 (\theta)那么相邻阵元的波程差是 (d \sin\theta)。这个几何关系是整篇分析的出发点。用复数基带表示第 (m) 个阵元收到的信号可以写成[ x_m(t) s(t) e^{j 2\pi f (m d \sin\theta / c)} ]其中 (c) 是声速(f) 是频率。把全部 (M) 个阵元的接收信号堆成向量就得到了阵列流形向量steering vector[ \mathbf{a}(\theta) \left[ 1,\ e^{j 2\pi f d \sin\theta / c},\ e^{j 2\pi f \cdot 2d \sin\theta / c},\ \dots,\ e^{j 2\pi f (M-1)d \sin\theta / c} \right]^T ]这个向量编码了“从 (\theta) 方向来的单位幅度信号在阵列上会呈现什么相位分布”。注意它只与方向、频率和阵列几何有关与信号内容无关。这是波束形成里最核心的量所谓“对准某个方向”本质就是构造一个与 (\mathbf{a}(\theta)) 共轭匹配的加权向量。我一般会这么理解阵列流形向量就是阵列的“空间指纹”。不同方向的来波在阵列上留下不同的相位指纹波束形成器做的事情就是拿一组加权系数去“识别”这个指纹。识别对了信号同相叠加识别错了信号相互抵消——定向能力就来自这个干涉。2.2 常规波束形成的数学结构加权、求和、输出CBF 的输出是对阵元信号做复加权再求和[ y(t) \mathbf{w}^H \mathbf{x}(t) ]其中 (\mathbf{w}) 是 (M \times 1) 的复权重向量。常规波束形成的权重取为[ \mathbf{w}_{\text{CBF}} \frac{1}{M} \mathbf{a}(\theta_0) ]也就是直接用目标方向的阵列流形向量作为权重。当来波方向与 (\theta_0) 一致时[ y(t) \frac{1}{M} \sum_{m0}^{M-1} s(t) e^{j 2\pi f m d \sin\theta_0 / c} e^{-j 2\pi f m d \sin\theta_0 / c} s(t) ]每个阵元的相位延迟被权重里的共轭相位完全补偿M 路信号同相相加幅度变成 M 倍功率变成 M² 倍除以 M 做归一化后输出就等于原始信号。这就是“对准”的数学含义不是放大信号而是让各路副本相干叠加。当来波方向偏离 (\theta_0) 时相位补偿不完整各路信号存在残余相位差求和时发生部分抵消输出幅度下降。这个“输出幅度随来波方向变化”的函数就是波束图beam pattern[ B(\theta) \left| \mathbf{w}^H \mathbf{a}(\theta) \right| \frac{1}{M} \left| \sum_{m0}^{M-1} e^{-j 2\pi f m d (\sin\theta - \sin\theta_0)/c} \right| ]这是一个 Dirichlet 核的形式主瓣方向和零点位置全部由指数项的相位差决定。你可以从两个角度理解时域里这是一个 FIR 滤波器只不过抽头延迟换成了空间延迟频域里波束图就是空间频率响应的模——空间采样定理换了个马甲。2.3 栅瓣出现的条件空间采样定理的直观重述波束图里最值得警惕的是栅瓣grating lobe在某些非目标方向输出幅度与主瓣一样大。原因很简单相位差以 (2\pi) 为周期当其他方向的波程差恰好也凑成整数倍波长时各路信号再次同相叠加。数学上看栅瓣出现在满足以下条件的方向[ \frac{2\pi f d (\sin\theta - \sin\theta_0)}{c} 2\pi k,\quad k \pm 1, \pm 2, \dots ]想让整个可视区域内没有栅瓣需要[ d \leq \frac{c}{2f} \frac{\lambda}{2} ]即阵元间距不超过半波长。这个条件在教材里通常被直接给出但它本质上是空间采样定理阵元是对连续孔径的空间采样采样间隔大于半波长波数域就会混叠。注意这里说的是“波数域混叠”不是频谱混叠——你在时域做 ADC 时如果采样率不够高频分量会折叠回低频在空间域如果阵元间距太大某些方向的来波会伪装成其他方向的来波。一个常见的直觉错误是“加大阵列尺寸就能提高分辨率”。阵列孔径确实决定主瓣宽度但如果你通过拉大阵元间距来增加孔径栅瓣也会随之出现。主瓣变窄和栅瓣出现是同一个几何公式的两个侧面。仿真里把间距设成 (d \lambda) 跑一下 CBF你会看到波束图里冒出两个一样高的峰——这不是 bug是空间混叠。2.4 主瓣宽度与旁瓣电平窗函数为什么在这里也适用CBF 的波束图可以改写成[ B(\theta) \left| \frac{1}{M} \sum_{m0}^{M-1} w_m e^{-j 2\pi f m d (\sin\theta - \sin\theta_0)/c} \right| ]如果 (w_m) 不全取 1而是取一个窗序列Hamming、Blackman 等波束图的主瓣会变宽、旁瓣会降低。这和时域 FIR 滤波器的窗函数设计完全同构均匀加权对应矩形窗第一旁瓣约 -13.3 dB加 Hamming 窗后第一旁瓣降到约 -43 dB但主瓣宽度从 (0.886\lambda/(Md)) 展宽到约 (1.3\lambda/(Md))。这就是分辨率与干扰抑制的经典权衡。主瓣越窄你区分两个相近方向的能力越强但旁瓣越高来自非目标方向的强干扰越容易泄漏进输出。CBF 里没有“既窄又低旁瓣”的自由参数——窗函数只能在这两个指标之间滑动这是傅里叶变换的测不准原理在空间域的投影。我用一个身边的例子来记这个结论矩形窗的波束图在 (\sin\theta) 轴上的形状是 (\text{sinc}) 函数主瓣两侧各有一个明显的负瓣。若你在阵列正前方放一个强干扰源它的能量会透过这个旁瓣进入输出而你丝毫不觉——波束图是功率响应负瓣的相位信息在取模后完全消失你看到的只是“不该有的能量”。3. 从权重到实现CBF 的复基带仿真与参数细节3.1 为什么仿真里必须用复基带而不是实信号很多初学者第一次写 CBF 仿真直接把实正弦信号加延迟求和跑出来的波束图却与理论不符。问题出在“延迟”的实现方式上对实信号做延迟需要在时域做插值滤波或者用 FFT 搬移相位而在复基带表示里延迟就是乘一个复指数干净利落。复基带的约定是把窄带信号表示为 (s(t)e^{j2\pi f_c t})其中 (s(t)) 是复包络。阵列流形向量里的相位项 (e^{j2\pi f m d \sin\theta / c}) 只与载波频率有关与基带信号的内容无关。仿真时你可以直接用 Python 生成这些复指数矩阵运算一次完成。以下是一个最简实现import numpy as np # 参数设置 M 8 # 阵元数 d 0.5 # 阵元间距单位波长 theta0 30 # 期望方向单位度 theta np.linspace(-90, 90, 1801) # 扫描角度 # 构造阵列流形矩阵 def array_manifold(M, d, theta): # theta: 角度数组度 # 返回形状 (theta_len, M) 的复数矩阵 theta_rad np.deg2rad(theta) kd 2 * np.pi * d # 波数乘间距假设频率为载波频率 m np.arange(M) # 每一行对应一个方向 manifold np.exp(1j * kd * np.outer(np.sin(theta_rad), m)) return manifold A array_manifold(M, d, theta) # 构造 CBF 权重 theta0_rad np.deg2rad(theta0) w np.exp(1j * 2 * np.pi * d * np.sin(theta0_rad) * np.arange(M)) / M # 计算波束图 beam np.abs(A w) # 复数内积的模 beam_db 20 * np.log10(beam 1e-12) # 打印主瓣附近的零点位置 peak_idx np.argmax(beam_db) print(f主瓣峰值角度: {theta[peak_idx]:.1f} 度)代码的核心只有两行A w计算所有扫描方向的阵列响应np.abs取模得到幅度波束图。np.outer(np.sin(theta_rad), m)生成的是 (M) 个阵元的相位累加项每条扫描方向对应一行。注意kd 2 * np.pi * d这里频率不是显式参数因为整个分析在“以波长为单位”的约定下进行阵元间距 (d) 直接写成波长的倍数载波频率被归一化掉了。如果你想仿真不同频率的行为需要把 (kd) 改成 (2\pi f d / c)让频率显式参与。3.2 参数变化时看什么主瓣零点、栅瓣、还有那些“看不见”的量跑完上面的代码后你手上有一张波束图。不要只看“主瓣在 30 度”就完事。我一般会按顺序检查四个量主瓣宽度。从峰值往两侧找到第一个零点两点之间的角度就是主瓣零点宽度。理论上它是 (2 \arcsin(\lambda/(M d))) 的近似。把 (M) 从 8 改成 16零点宽度缩一半——这是阵列孔径带来的分辨率提升。栅瓣位置。把d 0.5改成d 1.5波束图上会出现两个等高的峰。一个在 30 度另一个大约在 (\arcsin(\sin 30^\circ - 1/1.5) \approx -14.5) 度。此时你会直观看到“空间混叠”来自 -14.5 度的信号会被系统当成 30 度的信号完全接收。旁瓣电平。均匀加权时第一旁瓣固定在约 -13.3 dB这是矩形窗的 Fourier 变换性质。加 Hamming 窗后旁瓣降低但主瓣变宽。在代码里给权重乘一个窗序列两行就能完成。但有一个量是波束图上看不见的输出信噪比。CBF 对不相关噪声有 (M) 倍的功率增益输出 SNR 提升 (10\log_{10} M) dB但波束图只描述了对方向性信号的响应。当阵元噪声彼此独立时CBF 的阵列增益是固定的与波束形状无关。曾被这个问题坑过——仿真里只看波束图以为旁瓣高 SNR 就差实际上对白噪声而言旁瓣高度不影响阵列增益。3.3 “指向”到底在调什么CBF 权重与转向向量的相位关系CBF 的权重向量看似简单但工程实现里有一个容易搞反的细节用 (\mathbf{a}(\theta_0)) 还是 (\mathbf{a}^*(\theta_0)) 作为权重。不同的阵列流形定义方式信号模型用 (e^{j\phi}) 还是 (e^{-j\phi})会导致共轭位置不同符号错了波束图指向变成 (-\theta_0)。一个稳妥的做法是在代码里用同一个函数生成“发射”和“接收”两个阵列流形向量然后让权重的相位与目标方向流形向量的相位共轭匹配。例如上面的实现w np.conj(A_target) / M # A_target 是目标方向的流形向量这里的conj不是装饰而是 CBF 的本质操作乘以共轭相位来抵消传播延迟把不同阵元上的信号“搬回”到同一相位基准。如果漏掉这一步输出的相位关系就是错的波束图会完全镜像翻转。另一个常见问题是把 CBF 理解成“给每个阵元一个固定增益”。实际上 CBF 权重是频率的函数相位随频率线性变化宽带信号下必须做频域处理或真延迟线否则波束方向会随频率漂移即波束色散。仿真里如果直接对宽带信号用复权重输出会出现明显失真——这不是 CBF 的缺陷而是窄带假设被突破后的自然结果。4. 避坑指南CBF 仿真里的五个经典翻车现场4.1 现象波束图主瓣不在期望方向原因阵列流形向量的符号约定不一致。某个函数里用np.exp(-1j * kd * sin(theta) * m)权重里用np.exp(1j * ...)两者混用结果主瓣出现在镜像方向。解决统一约定。在项目开头定义一个函数生成 steering vector全代码只调用它。并在测试里加一条断言beam_argmax theta0。如果断不过优先检查符号而不是去调角度。4.2 现象d 0.5 时波束图在端点处冒出一个等高的“假峰”原因这通常不是栅瓣而是端射方向(\theta \pm 90^\circ)的视在响应。半波长间距在端射方向上的等效相位差不是零但端射方向本身的投影面积小波束图计算没有考虑阵元指向性。解决如果你要仿真全向阵元确认波束图公式里没有混入阵元方向图因子如果你用的是实际麦克风有心形指向需要把阵元方向图乘进去。单独的 CBF 标准模型假设阵元全向端射响应偏高是模型特性不是错误。4.3 现象把阵元间距从 0.5 改成 0.49波束图“变差”了原因你没看错间距略小于半波长不会导致栅瓣但主瓣会更宽。这不是 bug而是孔径缩小的必然结果。问题的本质是你在试图“用更短的阵列达到同样的分辨率”这不可能。解决把期望的分辨率转成最小孔径需求再倒推阵元数和间距。公式是主瓣零点宽度 (\Delta\theta \approx 2\arcsin(\lambda/(M d)))先用它算孔径 (L M d)再在无栅瓣约束(d \le \lambda/2)下选 (M)。4.4 现象仿真信号用了实正弦结果波束图“抖动”原因实信号包含正负频率成分CBF 的复权重只对正频率分量正确负频率分量的相位是共轭的导致周期性畸变。典型表现是波束图在某些角度出现与理论不符的波纹。解决改用复解析信号。工程里常见的做法是用scipy.signal.hilbert把实信号转成解析信号再处理或者直接在频域做单边带处理。窄带仿真从源头就用复指数省掉这一层麻烦。4.5 现象加窗之后主瓣“变胖”但旁瓣没有明显降低原因你可能把窗乘在时间快拍上而不是乘在阵元维度上。CBF 里的窗作用于空间域阵元序号方向不是时间域。两个维度都叫“窗”但作用对象完全不同。解决确认窗序列的长度是M且在权重向量上有w w * window。检查波束图的第一旁瓣是否接近 -43 dBHamming如果不是检查窗是不是乘反了维度。另一个隐蔽错误是窗函数作用在 steering vector 上而不是权重上——数学上等效但代码结构上容易让人误判。5. 窄带 CBF 到宽带波束形成为什么“延迟”两个字没那么简单5.1 窄带假说什么时候失效前面所有分析都假设窄带信号带宽远小于载波频率阵列流形向量在每个频率上近似相同。但真实声学信号语音、机械噪声往往是宽带带宽可以占中心频率的 30% 以上。此时如果还用单一频率的权重各个频率分量经过阵列时的延迟相位不同波束方向在每个频率上都不一样输出信号会出现幅度和相位畸变。一个直观的验证方法把一段宽带信号送入窄带 CBF观察输出频谱。你会发现高频分量和低频分量的增益不同波束图变成一个随频率变化的曲面而不是一条曲线。这就是波束色散。解决思路有两个方向频域分带处理或者时域真延迟线。5.2 时域真延迟与频域子带分解的权衡时域方案把每个阵元的复权重换成一组 FIR 滤波器每个滤波器设计为“带通 真延迟”。优点是一步到位适用于实时处理缺点是 FIR 阶数随带宽和阵列规模增大计算量大。频域方案把信号分帧做 FFT在每一个频点上独立计算 CBF 权重然后 IFFT 合成。优点是每个频点都能精确控制相位实现简单缺点是频域分辨率受帧长限制低频频点上的波束主瓣宽度会被帧长拖累。工程上两者都常用。雷达和声呐倾向于频域因为窄带本身就多麦克风阵列实时语音处理倾向于时域 FIR因为延迟小、逐样本输出。选择时有一个关键指标你要的波束主瓣宽度对应多少个波长如果低频分量波长太长阵列电尺寸不够主瓣会很宽——这不是算法能救的和第二章的孔径结论是同一件事。5.3 频域 CBF 的一个参数级细节子带权重别忘掉归一化频域实现时每个频点 (f_k) 的权重为[ \mathbf{w}(f_k) \frac{1}{M} \mathbf{a}(f_k, \theta_0) ]注意这里的归一化系数 (1/M) 与频率无关但如果你在不同频点分别做归一化输出的宽带信号幅度在不同频率上会不一致导致频谱倾斜。正确做法是把参考频点如中心频率的归一化系数固定下来其他频点只做相位补偿幅度归一化统一在参考频点做。我曾在这个细节上栽过频域 CBF 的输出频谱从低频到高频逐渐抬高一开始以为是窗函数的问题排查半天才发现是每个频点都乘了 (1/M)宽带能量被频率加权了。把归一化挪到参考频点后频谱恢复正常。这类问题波束图上看不见只能在输出信号的频域检查里发现。6. 回到设计取舍CBF 的“最优”与“次优”以及窗函数教给我们的哲学CBF 在数学上有一个明确的最优性当噪声是空间白噪声各阵元独立同分布时CBF 是最大输出信噪比波束形成器。这个结论常被忽略因为大家更关心干扰抑制但它是理解自适应波束形成的一把钥匙。MVDR 之所以在 CBF 之上是因为它针对的是“非白”噪声场——存在方向性干扰时CBF 的旁瓣会漏进干扰能量而 MVDR 可以自适应地在干扰方向放置零点。两者的关系不是“先进替代落后”而是“白噪声环境下 CBF 已经最优不需要更复杂的东西”。但问题的另一面是MVDR 的干扰抑制能力来自对协方差矩阵的估计而这个估计需要数据支撑。快拍数不足矩阵求逆就会放大噪声波束图变成一团糟。CBF 虽然没有自适应能力但它对协方差矩阵的估计误差完全不敏感——权重里没有数据依赖只有几何关系。这是 CBF 至今没有退出工程舞台的根本原因鲁棒性是一种设计取舍而不是缺陷。窗函数的选择也体现了同样的哲学。均匀权重给你最窄的主瓣但换来 -13.3 dB 的旁瓣Hamming 窗把旁瓣压到 -43 dB主瓣却宽了接近一半。在空间谱估计比如 DOA 扫描里主瓣越窄越好在干扰抑制里旁瓣越低越好。没有哪个窗是“最好”的你选的其实是“你对哪种失败更容忍”。从那以后我每设计一个新阵列的第一件事就是跑一遍 CBF 基线白噪声环境下CBF 的 SNR 增益是否达到 (10\log_{10} M) dB加窗后旁瓣是否与窗函数的理论值一致改变扫描方式后主瓣指向是否依然精确对着目标方向。基线过了才敢上 MVDR才敢谈自适应。这个习惯救了我很多次——阵列信号处理里90% 的“高级算法翻车”都源自基线没打牢。希望这篇文章能帮你在自己的项目里少走一段弯路先用 CBF 把几何、采样、干涉这三件事吃透再往深水区走。这份资源里的代码和说明恰好覆盖了我上面提到的所有关键点从阵列流形向量的构造、CBF 权重的推导、波束图的可视化到栅瓣、加窗、宽带扩展的全部流程。值得作为你跑通第一个阵列仿真、理解空间采样定理的起点。本文还有配套的精品资源点击获取