波束形成本质是线性积分:从导向矢量到MATLAB仿真全梳理

很多人第一次学波束形成,接触到的都是“给每个阵元加一个延迟,再叠加起来”这种讲法。这个讲法没有错,但它会让人忽略一个更本质的视角:波束形成的输出,本质上是对整个接收孔径上信号场的一次线性积分。搞清楚这一点,栅瓣为什么出现、窗函数为什么有用、导向矢量为什么长成那个样子,全都是顺理成章的事。这篇文章就用“线性积分”这条主线,把窄带常规波束形成的原理和 MATLAB 实现从头顺一遍,最后再聊聊实际仿真里一定会踩的几个坑。适合刚开始接触阵列信号处理、想把原理和代码对应起来的读者。

1. 为什么要把波束形成理解成一次“线性积分”

1.1 连续孔径上的输出方程

先忘掉离散阵元,假设我们有一根长度为 L 的连续接收孔径,比如一条无限细的水听器线阵。入射信号在孔径位置 x 处的复声压是 p(x, t)。一个线性波束形成器的输出,可以写成孔径上的加权积分:

[ y(t) = \int_{-L/2}^{L/2} w(x) , p(x, t) , dx ]

这里的 w(x) 是孔径加权函数,也就是常说的窗函数或锥削函数。输出 y(t) 是输入场 p(x,t) 的线性泛函,而连续孔径上的组合方式就是积分。所以“线性积分”并不是一个高深说法,它就是字面意思:把孔径上每个位置接收到的信号,乘上一个权重,然后沿整个孔径加起来。

为什么要关心这个连续形式?因为很多结论在连续模型下特别干净。远场平面波假设下,从 θ 方向来的信号到达孔径位置 x 时,相对参考点有一个传播时延 x sinθ / c。窄带情况下,这个时延在复包络上表现为一个相移 e^{-j k x sinθ},其中 k = 2π/λ。于是输出可以写成:

[ Y(\theta) = S(\omega) \int_{-L/2}^{L/2} w(x) e^{-j k x \sin\theta} dx ]

注意看这个积分:它是对空间坐标 x 做积分,而积分核是 e^{-j k x sinθ}。这和傅里叶变换的核长得一模一样,只不过变量从时间频率换成了空间角度。换句话说,波束方向图就是孔径加权函数 w(x) 在空间频率 u = sinθ 处的傅里叶变换值。

这个结论值得单独拎出来记:波束形成的本质是空间傅里叶分析,而不是某种“近似的延迟叠加技巧”。

1.2 离散阵元让积分退化成加权求和

实际阵列不可能连续采样,只有 M 个离散阵元。数学上,相当于把连续孔径上的采样用一个梳状函数表达,积分退化成求和:

[ y(t) = \sum_{m=0}^{M-1} w_m , p(x_m, t) ]

如果阵元等间距 d,且以阵列中心为原点,x_m = (m - (M-1)/2)d。这时权重向量 w = [w_0, ..., w_{M-1}]^T,阵列接收数据也是向量,输出就是一个简单的内积。离散化带来了一个连续模型里不存在的限制:空间采样定理。阵元间距 d 必须不大于 λ/2,否则方向图在 u 域会出现周期重复,也就是栅瓣。这一点后面展开讲。

刚到这一步,很多初学者会困惑:为什么有的地方写 y = w^H x,有的地方写 y = w^T x?因为不同教材对导向矢量的相位定义不一样。这篇文章统一采用如下约定:导向矢量 a(θ) = e^{-j k x_m sinθ},波束输出时用补偿权重 v(θ₀) = conj(a(θ₀)),输出写成 v^T x 而不是 v^H x。这个约定会在 MATLAB 代码部分再次强调,因为符号搞反是最常见的低级错误。

1.3 这个视角带来的三个工程推论

从“线性积分”看波束形成,至少有三个工程上经常用到的推论:

第一,波束形成和傅里叶分析是同构的。所以时域信号处理里关于窗函数、旁瓣、主瓣宽度的所有经验,几乎可以原封不动搬到空间域。时域加窗降低频谱旁瓣,空间加窗降低方向图旁瓣;时域窗越宽主瓣越窄,空间阵列孔径越大主瓣越窄。

第二,栅瓣就是空间域的混叠。时域采样率不够会产生频谱混叠,空间采样间隔大于 λ/2 会产生栅瓣。这两个是同一个数学现象的两张脸。

第三,窄带假设是线性积分成立的边界。如果信号带宽较大,x_m 处的“相位差”不再能用单一频率的 e^{-j k x sinθ} 描述,而必须保留真实的延迟。这时单导向矢量模型崩坏,需要换成频域子带处理或真实时延波束形成。很多人把宽带信号硬套窄带模型,方向图从中间塌掉,原因就在这里。

2. 窄带常规波束形成:导向矢量与方向图的来龙去脉

2.1 从几何时延到导向矢量

假设 M 元均匀线阵,间距 d,目标信号是频率为 f₀ 的窄带信号,从法线方向右侧 θ 角入射。以阵列中心为参考点,第 m 个阵元相对参考点的传播时延是:

[ \tau_m = \frac{x_m \sin\theta}{c} ]

中心频率 f₀ 对应的波数为 k = 2π/λ,窄带复包络下,阵元接收信号可以写成:

[ x_m(t) = s(t) e^{-j k x_m \sin\theta} ]

把所有阵元排成列向量,就得到导向矢量:

[ \mathbf{a}(\theta) = \left[ e^{-j k x_0 \sin\theta}, \ e^{-j k x_1 \sin\theta}, \ \dots, \ e^{-j k x_{M-1} \sin\theta} \right]^T ]

这里每个阵元相对参考点都有一个相位差。记住一个判断方法:入射角为正时,阵列右侧阵元先收到信号,所以它们的相位相对参考点是超前的;但上面公式用负指数表示滞后。两种约定都能自洽,关键是权重补偿方向必须和它配套。

为了让波束指向 θ₀,我们需要给第 m 个阵元乘上一个正好抵消该相位差的权重:

[ v_m = e^{+j k x_m \sin\theta_0} ]

也就是 v = conj(a(θ₀))。这样当真实信号从 θ₀ 来时,每个阵元补偿后的复数信号都对齐到同一个方向,相加之后信号幅度增强 M 倍。输出写法和常见教材有点差别,我用普通转置:

[ y(t) = \mathbf{v}^T \mathbf{x}(t) ]

提示:如果看到别的资料写 w^H x,不要直接照抄公式,先确认它的导向矢量是 e^{j k x sinθ} 还是 e^{-j k x sinθ}。导向矢量定义方向不同,权重到底是共轭还是非共轭,结论完全不同。这块符号约定问题坑了很多初学者,MATLAB 报错或者方向图反向,多半就是这里出了问题。

2.2 方向图就是空间傅里叶变换

把波束输出幅度写成入射角的函数,就是方向图。把权重 v(θ₀) 和每个可能入射方向的导向矢量 a(θ) 做内积:

[ F(\theta) = \frac{1}{M} \sum_{m=0}^{M-1} e^{j k x_m (\sin\theta_0 - \sin\theta)} ]

令 u = sinθ,u₀ = sinθ₀,方向图变成:

[ F(u) = \frac{1}{M} \sum_{m=0}^{M-1} e^{j \frac{2\pi}{\lambda} x_m (u_0 - u)} ]

这正是离散孔径的空间傅里叶变换。为什么矩形窗下方向图像一个 sinc 函数的离散版本?因为均匀加权的有限长序列做傅里叶变换,本来就得到 Dirichlet 核。所以用 FFT 快速扫描方向图是完全合理的做法:把阵元坐标和角度变量都离散化,一次矩阵乘法就能算出全角度响应。

这里有一个工程细节值得注意:因为方向图只和 sinθ 有关,所以角度响应的形状在 u 空间是平移不变的。主瓣宽度、旁瓣位置参考 u 空间来设计,会比直接看角度更规整。

2.3 主瓣、旁瓣与增益的定量关系

对 16 元半波长间距均匀线阵,矩形窗下的关键参数如下:

  • 主瓣第一零点宽度在 u 空间约为 2λ/(Md)。转成角度时会因 cosθ₀ 有拉伸,偏离法线越远波束越宽。
  • 半功率波束宽度近似为 0.886λ/(M d cosθ₀)(弧度)。法线方向、d=λ/2 时,M=16 大约对应 6.4°。
  • 第一旁瓣电平约为 -13.3 dB,这是矩形窗众所周知的性质。
  • 白噪声输入下,常规波束形成的输出 SNR 提升 10log₁₀(M) dB。原因是信号相干相加幅度增益 M,功率增益 M²;而阵元噪声是非相干的,功率相加,所以只增加 M 倍,净增益 M 倍。

这些数字是判断仿真代码是否写对的“手感指标”。比如你跑完一个 16 元阵列方向图,主瓣半功率宽度不是 6 度上下,第一旁瓣不是 -13 dB 附近,那大概率代码有符号或归一化问题,而不是物理问题。

3. MATLAB 实现:从单频目标信号到可复现的仿真

3.1 仿真场景与参数选择

我用一个非常经典的水声场景来写示例:均匀线阵,16 个阵元,中心频率 15 kHz,声速 1500 m/s,波长 0.1 m,阵元间距取半个波长 0.05 m。目标从 20° 方向入射,采样率 100 kHz,快拍数 4096。单阵元输入信噪比设为 0 dB。

这样选择参数的原因:

  • d = λ/2 是空间采样定理的临界值,既能保证无栅瓣,又能让阵列孔径尽可能大,主瓣更窄。
  • 窄带信号直接用复指数表示,仿真里不需要走完调制解调流程,原理验证最干净。
  • 16 阵元给后面加窗、误差分析留了足够自由度,方向图也足够平滑。

3.2 完整仿真代码

clear; close all; clc; %% 基本参数 c = 1500; % 声速 m/s f0 = 15e3; % 中心频率 Hz lambda = c / f0; d = 0.5 * lambda; % 阵元间距,取半波长避免栅瓣 M = 16; % 阵元数 theta0 = 20; % 目标方向 deg fs = 100e3; % 采样率 Hz Ns = 4096; % 快拍数 SNR_in = 0; % 单阵元输入信噪比 dB %% 阵列坐标,以阵列中心为参考点 x_m = ((0:M-1) - (M-1)/2) * d; %% 导向矢量 k = 2*pi / lambda; a_target = exp(-1i * k * x_m(:) * sind(theta0)); % M x 1 %% 生成窄带目标信号 + 独立阵列噪声 t = (0:Ns-1).' / fs; s_t = exp(1i * 2*pi*f0 * t).'; % 1 x Ns 复包络 noise_power = 10^(-SNR_in/10); noise = sqrt(noise_power/2) * (randn(M, Ns) + 1i*randn(M, Ns)); X = a_target * s_t + noise; % M x Ns 阵列接收数据 %% 常规波束形成权重 % 注意:此处权重是共轭导向矢量,输出用普通转置而不是共轭转置 w_bf = conj(a_target) / M; % M x 1 %% 波束输出 y = w_bf.' * X; % 1 x Ns %% 分别计算信号和噪声分量,看 SNR 提升 y_signal = w_bf.' * (a_target * s_t); y_noise = w_bf.' * noise; SNR_in_est = 10*log10(mean(abs(s_t).^2) / mean(mean(abs(noise).^2))); SNR_out_est = 10*log10(mean(abs(y_signal).^2) / mean(abs(y_noise).^2)); fprintf('输入SNR: %.2f dB\n', SNR_in_est); fprintf('波束形成后SNR: %.2f dB\n', SNR_out_est); fprintf('理论增益: %.2f dB\n', 10*log10(M)); %% 方向图扫描 theta_scan = -90:0.1:90; A_scan = exp(-1i * k * x_m(:) * sind(theta_scan)); % M x Ntheta F = w_bf.' * A_scan; % 1 x Ntheta F_dB = 20*log10(abs(F) / max(abs(F))); figure; plot(theta_scan, F_dB, 'LineWidth', 1.5); grid on; xlabel('角度 (deg)'); ylabel('归一化幅度 (dB)'); ylim([-40 0]); title('常规波束形成方向图');

3.3 跑完代码后怎么解读结果

正常运行后,方向图最大值出现在 20° 附近,幅度是 0 dB,这就是波束指向。第一旁瓣大约在 -13 dB 附近,和前面理论值吻合。SNR 输出一般会比输入高 12 dB 左右,因为 10log₁₀(16) ≈ 12.04 dB。如果这两条都对不上,先检查导向矢量符号和转置有没有搞错。

我这里用w_bf.' * X而不是w_bf' * X,关键就在 MATLAB 里单引号是共轭转置。由于权重本身已经存成了共轭导向矢量,再做共轭转置会多出一个共轭,波束输出相位乱掉,方向图最大值位置会跑到负角度去。这个错误非常隐蔽,因为幅度方向图看起来仍然有个峰,很多人直到方向图“镜像”了才意识到。

另外可以顺手验证一件事:把d = 0.5 * lambda改成d = 1.0 * lambda,再跑一次方向图,会看到除了 20° 主峰外,-41° 附近出现一个等高的假峰。这就是栅瓣,后面专门说它。

4. 方向图之外:栅瓣、窗函数和指向误差的实战考验

4.1 栅瓣:空间采样定理被违反时会发生什么

栅瓣是阵列信号处理里最容易验证、也最容易理解的一个现象。方向图在 u = sinθ 空间里是周期函数,周期是 λ/d。只要 d ≤ λ/2,这个周期大于等于 2,而 u 的取值范围恰好是 [-1, 1],所以可见范围内只有一个主瓣。一旦 d > λ/2,周期小于可见范围,u 空间里相邻周期的重复峰就会漏进 [-1,1],形成栅瓣。

以下表是 d=0.5λ、λ、1.5λ 三种取值下,目标从 20° 入射时出现的栅瓣角度:

阵元间距栅瓣位置(u空间平移量)可见栅瓣角度
0.5λ±2,超出范围无
λ1 的整数倍平移-41.1°
1.5λ每 0.667 平移-18.9°,-82.4°

第三个例子里,-82.4° 的低掠射角栅瓣甚至比主瓣更接近端射区域,实际工程中会被当成真实目标。宽带系统尤其要注意:阵元间距设计通常按最高工作频率对应的半波长来定,如果频率范围太宽,高频端满足条件,低频端波长变大,半波长间距反而变大?其实反了,高频端波长小,按低频端设计会给高频造成栅瓣。所以正确做法是“最高频定间距”,低频端只是主瓣变宽,不会出现栅瓣。

如果已经用了稀疏阵列无法改间距,最常见的补救是布阵时引入非均匀间距,破坏空间采样周期性。好处是不再有明确栅瓣,代价是平均旁瓣抬高、方向图可控性变差。这个交易要心里有数。

4.2 空间窗函数:旁瓣与主瓣宽度的交易

矩形窗方向图第一旁瓣 -13.3 dB,在很多干扰场景下不够用。比如 30° 处有个强干扰,它透过旁瓣进来的能量可能直接淹没目标。空间加窗和时域加窗思路完全一样:对幅度锥削,让阵列边缘的阵元贡献小、中间贡献大。代价是有效孔径变短,主瓣变宽,输出 SNR 增益也会略小于 M。

常用窗的情况:

窗类型第一旁瓣电平主瓣展宽系数(相对矩形窗)
矩形窗-13.3 dB1.00
汉宁窗-31.5 dB1.62
汉明窗-42.7 dB1.52
布莱克曼窗-57.6 dB1.74

MATLAB 里加窗很简单,比如在生成权重时乘一个汉明窗:

win = hamming(M, 'periodic').'; % 1 x M w_bf = win .* conj(a_target).'; w_bf = w_bf / sum(win); % 保持主瓣增益为 0 dB

注意 MATLAB 里hamming默认返回列向量,为了维度对齐,我把它转成行向量再和conj(a_target).'做逐元素乘。sum(win)归一化是为了让主瓣峰值仍然为 0 dB。如果不做归一化,SNR 的理论增益会进一步偏离 M。

实际项目里我见过不少“既要低旁瓣、又要窄主瓣、还要高 SNR”的需求,它们在物理上是互相拉扯的。加窗之前最好先量化一下:旁瓣要压到多少 dB?主瓣可以容忍变宽多少?干扰是近旁瓣还是远旁瓣?通常压旁瓣到 -30 dB 左右,对主瓣的损失还比较可控,再低就要用更复杂的优化方法而不是简单窗函数了。

4.3 指向误差和阵元误差:理想模型的边界

线性积分模型假设了理想均匀直线阵、平面波、窄带、阵元特性完全一致。现实中每一条都可能失配,其中最隐蔽的是指向误差和阵元幅相误差。

指向误差很好理解:波束指向 θ₀,目标实际从 θ₀ + δ 来,输出幅度会落在方向图主瓣斜坡上。比如上面的 16 元阵,20° 附近半功率波束宽度约 6.8°,如果指向偏差 2°,损失大概不到 1 dB;偏差 5°,损失接近 3 dB。这个损失在低信噪比场景下可能被噪声起伏掩盖,不容易发现,但会直接吃掉积累增益。

阵元误差更麻烦。阵元位置误差、幅度不一致、相位不一致都会让实际方向图偏离理论值。最典型的表现是旁瓣抬高、零陷变浅。低旁瓣设计对误差尤其敏感,你加了布莱克曼窗期望旁瓣 -50 dB,实际加工出的阵列可能只能到 -30 dB。所以阵列标校不是可有可无的事。

我自己做阵列仿真有个固定习惯:先跑理想模型确认算法正确,然后立刻加一组 Monte Carlo 误差仿真,检验算法对失配的敏感度。常用误差量级是:阵元位置随机偏差 0.02λ、幅度增益误差 5%、相位误差 5°。如果方向图在这些误差下还能保住期望的旁瓣或零陷水平,这个方案才敢往后走。差了几 dB 就调算法或者调布阵,总比装到平台上再发现问题便宜得多。

最后分享一个小技巧:不要只盯着方向图理论曲线看,把多次蒙特卡洛的波束输出 SNR 直方图画出来,你会很直观地看到误差对系统稳定性的影响。很多阵列算法的“理论优势”在误差面前缩水得很快,提前用仿真暴露出来,比到外场再被动解释要强得多。

相关新闻

C# Winform桌面翻译器实战:在线翻译接口封装与HTTP请求

C# Winform桌面翻译器实战:在线翻译接口封装与HTTP请求

简介:这是一款基于C#与Winform构建的Google在线翻译本地桌面工具,面向希望摆脱浏览器、提升翻译效率的开发者与日常办公用户。它通过HTTP请求调用Google在线翻译接口,在Windows窗体中完成原文输入、翻译触发与结果展示,省去打开网…

2026/10/22 9:52:15 阅读更多 →
监狱信息化单监模板:架构选型、安防集成与交付避坑指南

监狱信息化单监模板:架构选型、安防集成与交付避坑指南

简介:这份资源是面向监狱信息化项目设计人员、安防系统集成商及监管单位技术负责人的单监狱建设技术方案模板,以doc文档形式提供,可直接作为方案撰写与投标参考。压缩包内共1个doc文件,大小约2.82MB,内容围绕智能化监管…

2026/10/21 8:11:24 阅读更多 →
单个监狱信息化建设技术方案:架构、联动与验收指标

单个监狱信息化建设技术方案:架构、联动与验收指标

简介:这份2025年监狱信息化建设技术方案以单个监狱为模板,面向安防工程商、监狱信息化项目负责人及方案撰写人员,用于解决监管系统多子系统独立、难以统一联动的问题。资源包共1个doc文件,约2.82MB,内容按章节展开&…

2026/10/21 8:11:24 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/10/22 10:18:38 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/10/22 11:01:53 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/22 9:44:47 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/10/22 10:42:00 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/10/22 10:40:08 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/10/22 10:56:37 阅读更多 →

日新闻

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/22 1:47:45 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/21 21:32:28 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/22 5:12:39 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/21 21:50:56 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/21 21:51:55 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/21 16:24:48 阅读更多 →