阵列信号处理前三章Matlab代码实战:波束形成与方向图综合

简介:本资源是《优化阵列信号处理》前三章关键案例的Matlab实现代码,面向学习阵列信号处理、波束形成与DOA估计的高年级本科生、研究生及科研人员,帮助读者把书中理论落到可运行、可调试的仿真程序上。压缩包共27个文件,以26个.m脚本为主,另含1个txt说明文件,整体约36KB,涵盖波束形成、方向图绘制、三维可视化与优化求解等典型环节,脚本命名与书中案例对应,便于按章节定位。已有8839人学习下载,说明其在相关课程与科研入门中认可度较高。读者可借助这些代码复现最大似然、最小均方误差等波束形成算法,观察功率谱密度与方向图的三维呈现,并体会梯度下降、牛顿法等优化手段在权值求解与DOA估计中的作用,从而加深对阵列增益、旁瓣抑制与定位精度的理解,提升动手实践与算法验证能力。

1. 从翻烂PDF到跑通代码:这套阵列信号处理前三章案例到底值不值得下

阵列信号处理这个方向,理论推导和能跑的代码之间隔着一道很深的沟。很多同行啃《优化阵列信号处理》的时候,前几章的波束形成、方向图综合、协方差矩阵估计这些内容,公式能看懂,但一打开 Matlab 就不知道从哪下手。这份资源就是冲着这个痛点来的——它把该书前三章的关键案例做成了可直接运行的 Matlab 实现代码,覆盖均匀线阵建模、常规波束形成、MVDR 自适应波束形成、方向图综合等核心环节。适合正在做阵列信号处理课程设计、论文复现或者工程预研的人,尤其是那些手里有书但缺可运行参考实现的从业者。代码本身不复杂,但胜在结构清晰、参数可调,拿来当自己项目的起点比从零写要省很多时间。

2. 先搞清楚代码在算什么:阵列模型与波束形成的数学骨架

2.1 均匀线阵的信号模型怎么在代码里落地

阵列信号处理的一切从阵列流形开始。均匀线阵(ULA)是最基础的几何结构,N 个阵元等间距排列,假设远场窄带信号以平面波入射,相邻阵元之间的波程差引入的相位差由信号波长和入射角决定。代码里通常用一个steering_vector函数来生成导向矢量,核心就是那行exp(-1j*2*pi*d*(0:N-1)'*sind(theta)/lambda)。这个表达式看着简单,但有几个参数直接决定后面所有结果对不对。

阵元间距 d 一般取半波长,这是为了避免栅瓣。如果 d 大于半波长,方向图会出现虚假峰值,后面做波束形成的时候你会看到明明信号从一个方向来,结果好几个方向都有响应,这就是栅瓣在捣乱。波长 lambda 由载频决定,代码里通常用lambda = c/f0算出来,c 是光速,f0 是载频。入射角 theta 的范围一般取 -90 到 90 度,步进 0.1 或 0.5 度,步进太粗会漏掉主瓣细节,太细则计算量上去但视觉提升有限。

代码里还会定义快拍数 snapshots,这个参数影响协方差矩阵估计的精度。快拍数少的时候,协方差矩阵估计不准,MVDR 这类自适应波束形成器的性能会明显下降。我一般建议至少取 200 个快拍,条件允许就上 500 到 1000。信噪比 SNR 也是关键,代码里通常用awgn或者手动加复高斯噪声来实现,SNR 设 10dB 到 20dB 是比较常见的仿真条件。

% 均匀线阵参数初始化 N = 8; % 阵元数 d = 0.5; % 阵元间距,单位:波长 lambda = 1; % 归一化波长 theta = -90:0.1:90; % 扫描角度范围 snapshots = 500; % 快拍数 SNR = 15; % 信噪比 dB % 生成导向矢量矩阵 A = exp(-1j*2*pi*d*(0:N-1)'*sind(theta)/lambda);

这段代码的逻辑很直接:先定阵列几何和信号参数,然后生成所有扫描角度对应的导向矢量。注意(0:N-1)'是列向量,sind(theta)是行向量,乘出来是 N 乘 length(theta) 的矩阵,每一列对应一个角度的导向矢量。这个矩阵在后面算波束响应、协方差矩阵、MVDR 权重的时候都会反复用到。参数改的时候要联动:改了 N 就要改后面协方差矩阵的维度,改了 d 就要重新检查有没有栅瓣,改了 theta 范围就要确认信号来向在不在扫描区间内。

2.2 从常规波束形成到 MVDR:权重向量到底怎么算

常规波束形成(CBF)就是导向矢量本身做权重,w = a(theta0)/N,然后波束响应就是w' * A。这个方法的优点是稳健,不需要协方差矩阵,缺点是分辨率受限于阵列孔径,两个信号靠得近就分不开。代码里通常用pattern = abs(w' * A)来画方向图,取对数就是 dB 刻度。

MVDR 就完全不一样了。它的权重是w = R^-1 * a(theta0) / (a(theta0)' * R^-1 * a(theta0)),其中 R 是接收信号的协方差矩阵。这个公式的物理意义是在保证期望方向增益不变的前提下,让总输出功率最小,等价于把零陷对准干扰方向。代码实现的时候,R 通常用R = (1/snapshots) * X * X'来估计,X 是 N 乘 snapshots 的接收数据矩阵。

% 构造接收信号 theta_s = 20; % 期望信号来向 theta_i = -30; % 干扰来向 a_s = exp(-1j*2*pi*d*(0:N-1)'*sind(theta_s)/lambda); a_i = exp(-1j*2*pi*d*(0:N-1)'*sind(theta_i)/lambda); % 生成接收数据 s = (randn(1,snapshots) + 1j*randn(1,snapshots))/sqrt(2); i = (randn(1,snapshots) + 1j*randn(1,snapshots))/sqrt(2); n = (randn(N,snapshots) + 1j*randn(N,snapshots))/sqrt(2); X = a_s * s + a_i * i * 10^(SNR/20) + n * 10^(-SNR/20); % 估计协方差矩阵 R = (X * X') / snapshots; % MVDR 权重 a0 = exp(-1j*2*pi*d*(0:N-1)'*sind(theta_s)/lambda); w_mvdr = (R \ a0) / (a0' * (R \ a0)); % 波束响应 pattern_mvdr = abs(w_mvdr' * A); pattern_mvdr_db = 20*log10(pattern_mvdr / max(pattern_mvdr));

这里有几个实操细节值得说。第一,R \ a0比inv(R) * a0数值上更稳,尤其是 R 接近奇异的时候。第二,干扰功率和噪声功率的比例通过10^(SNR/20)来控制,这个写法假设信号和干扰的初始幅度都是 1,实际调的时候可以分开设。第三,画方向图之前一定要归一化,不然不同方法的绝对幅度没有可比性。MVDR 的方向图你会看到在 -30 度附近有一个很深的零陷,这就是它比 CBF 强的地方。

2.3 方向图综合:把期望形状“捏”出来

前三章里另一个重头戏是方向图综合,也就是给定一个期望的方向图形状,反推阵元加权系数。常见的有 Dolph-Chebyshev 综合和 Taylor 综合,前者用来控制主瓣宽度和旁瓣电平的折中,后者适合和差波束或者低旁瓣场景。代码里通常用chebwin或者自己写综合函数来实现。

Dolph-Chebyshev 的核心思想是用切比雪夫多项式来逼近方向图,使得在给定旁瓣电平下主瓣最窄。Matlab 里chebwin(N, sidelobe_level)直接给出窗函数,但注意这个窗是用于均匀线阵的,而且它给的是幅度加权,相位加权需要另外处理。如果你要做扫描,还得把加权系数和导向矢量结合起来。

% Dolph-Chebyshev 加权 sidelobe_dB = -30; % 旁瓣电平 w_cheb = chebwin(N, -sidelobe_dB).'; % 注意转置成行向量 w_cheb = w_cheb / sum(w_cheb); % 归一化 % 加权后的方向图 pattern_cheb = abs(w_cheb * A); pattern_cheb_db = 20*log10(pattern_cheb / max(pattern_cheb));

这里有个容易翻车的地方:chebwin的第二个参数是旁瓣衰减的正数值,比如你要 -30dB 旁瓣就传 30,不是 -30。传错了旁瓣电平会完全不对。另外加权之后主瓣会展宽,这是绕不开的代价,旁瓣压得越低主瓣越宽,实际用的时候要根据系统要求折中。代码里一般会把 CBF、MVDR、Chebyshev 三种方向图画在一起对比,这样一眼就能看出各自的取舍。

3. 把代码跑起来:环境配置、参数扫描与结果验证

3.1 Matlab 版本选择和工具箱依赖

这套代码对 Matlab 版本的要求不算苛刻,R2016b 之后的版本基本都能跑。但有几个函数需要注意:sind、cosd这些是基础函数,所有版本都有;chebwin在 Signal Processing Toolbox 里,如果你没装这个工具箱,就得自己写切比雪夫加权函数。自己写的版本也不复杂,核心就是切比雪夫多项式的递推和根求解,网上有现成的公式可以抄。

如果你用的是 Octave,大部分代码也能跑,但chebwin可能需要用chebwin的替代实现,Octave 的信号包里有类似函数。另外 Octave 对\运算符的支持和 Matlab 基本一致,MVDR 那部分不用改。我一般建议先在 Matlab 里跑通,再考虑移植到 Octave 或者 Python。

Python 用户也不用慌,numpy和scipy能复现绝大部分逻辑。scipy.signal.chebwin对应 Matlab 的chebwin,numpy.linalg.solve对应\。但要注意 Python 里索引从 0 开始,转置用.T,矩阵乘法用@,这些语法差异改起来不费劲但容易漏。

3.2 参数扫描:改哪些数、看哪些图

代码跑通之后,下一步就是调参看效果。我一般会按这个顺序扫:

第一步,固定 N=8、d=0.5、SNR=15dB,改快拍数从 50 到 1000,看 MVDR 方向图零陷深度的变化。快拍数少的时候零陷变浅甚至偏移,这是协方差矩阵估计误差导致的。第二步,固定快拍数 500,改 SNR 从 0dB 到 30dB,看 MVDR 和 CBF 的分辨率差异。低 SNR 下 MVDR 优势不明显,高 SNR 下零陷非常尖锐。第三步,改阵元数 N 从 4 到 16,看主瓣宽度的变化。N 越大主瓣越窄,但计算量和硬件成本也上去。

% 参数扫描示例:不同快拍数下的 MVDR 零陷深度 snapshots_list = [50, 100, 200, 500, 1000]; for k = 1:length(snapshots_list) snap = snapshots_list(k); % 重新生成数据、估计协方差、算 MVDR 权重 % ...(省略重复代码) % 记录零陷深度 null_depth(k) = pattern_mvdr_db(theta == theta_i); end

这段扫描代码的关键是每次改快拍数都要重新生成接收数据,不能复用同一个 X。因为快拍数变了,数据矩阵的列数就变了,协方差矩阵也跟着变。零陷深度用pattern_mvdr_db(theta == theta_i)来取,注意 theta 是向量,==返回逻辑索引,要求 theta_i 正好在扫描网格上,不然得用插值。

3.3 结果验证:怎么判断代码算对了

跑出方向图之后,怎么知道对不对?我一般看三个地方。第一,CBF 的主瓣峰值应该在期望方向 theta_s 上,旁瓣对称,第一旁瓣大约 -13dB。如果主瓣偏了或者旁瓣不对称,大概率是导向矢量符号错了或者角度定义反了。第二,MVDR 的零陷应该正好在干扰方向 theta_i 上,深度跟 SNR 和快拍数有关,但位置不能偏。第三,Chebyshev 加权后的旁瓣应该平坦,且电平接近设定的 sidelobe_dB。如果旁瓣起伏很大,可能是加权系数没归一化或者转置搞错了。

还有一个验证方法是跟理论值对比。比如 CBF 的主瓣宽度理论值大约是0.886 * lambda / (N * d)弧度,换算成角度大概是50.8 / (N * d / lambda)度。N=8、d=0.5 的时候主瓣宽度约 12.7 度,你从方向图上量一下 -3dB 宽度,对得上就说明阵列模型没问题。

4. 避坑与排查:那些让我熬夜的报错和异常

4.1 方向图出现栅瓣:阵元间距超了半波长

现象:方向图除了主瓣之外,在别的角度出现跟主瓣差不多高的峰值。原因:阵元间距 d 大于半波长,导致空间采样不足,出现栅瓣。解决:把 d 改回 0.5 或者更小。如果系统要求必须用大间距,那就得用非均匀阵列或者稀疏阵列来抑制栅瓣,但那就不是前三章的基础案例能覆盖的了。

4.2 MVDR 零陷位置偏移:协方差矩阵估计不准

现象:MVDR 方向图的零陷没有对准干扰方向,或者零陷很浅。原因:快拍数太少,协方差矩阵估计误差大;或者干扰和信号相关性太强,R 接近奇异。解决:增加快拍数到 500 以上;如果信号和干扰相干,需要做去相关处理,比如空间平滑。代码里可以先检查cond(R),条件数太大就说明 R 病态了。

4.3 chebwin 报错或旁瓣不对:工具箱缺失或参数符号错

现象:运行到chebwin报 undefined,或者旁瓣电平跟设定值差很远。原因:没装 Signal Processing Toolbox,或者第二个参数传了负数。解决:装工具箱,或者自己写切比雪夫加权函数;参数传正数,比如 -30dB 旁瓣传 30。

4.4 方向图归一化后全是负无穷:除零了

现象:20*log10(pattern / max(pattern))出现 -Inf。原因:max(pattern)是 0,或者 pattern 里有 0。解决:检查导向矢量是不是全零,或者信号来向超出了扫描范围导致波束响应为零。加一个小量eps到分母上可以临时规避,但根本原因还是要查参数。

4.5 扫描角度和信号来向对不上:角度定义反了

现象:期望信号在 20 度,但 CBF 主瓣在 -20 度。原因:导向矢量里sind(theta)的符号跟信号生成时的符号不一致。解决:统一符号约定,要么都用exp(-1j*...*sind(theta)),要么都用exp(1j*...*sind(theta)),别混着来。

5. 进阶技巧:从能跑到好用,几个我压箱底的习惯

代码能跑通只是第一步,真正做项目的时候还得考虑可复用性和可扩展性。我自己的习惯是把阵列参数、信号参数、算法参数分成三个结构体,这样换场景的时候只改结构体就行,不用满代码找数字。比如array.N、array.d、signal.theta_s、signal.SNR、algo.type,主脚本里根据algo.type分支调用不同的权重计算函数。

% 参数结构体化 array.N = 8; array.d = 0.5; array.lambda = 1; signal.theta_s = 20; signal.theta_i = -30; signal.snapshots = 500; signal.SNR = 15; algo.type = 'mvdr'; % 可选 'cbf' / 'mvdr' / 'cheb' % 主脚本根据 algo.type 分支 switch algo.type case 'cbf' w = a0 / array.N; case 'mvdr' R = (X * X') / signal.snapshots; w = (R \ a0) / (a0' * (R \ a0)); case 'cheb' w = chebwin(array.N, 30).'; w = w / sum(w); end

另一个习惯是每次改完参数都存一份方向图数据,用save('pattern_data.mat', 'theta', 'pattern_cbf', 'pattern_mvdr', 'pattern_cheb'),这样后面写报告或者对比不同参数的时候不用重新跑。还有,画图的时候把三种方法画在一个 figure 里,用legend标清楚,比分开画三张图直观得多。

验证方面,我一般会拿一个已知解析解的场景来对。比如单信号无干扰的时候,MVDR 退化成 CBF,方向图应该完全重合。如果对不上,说明 MVDR 实现有问题。再比如两个信号角度差很大的时候,CBF 应该能分出两个峰,MVDR 应该在一个峰上形成零陷对准另一个。这些边界条件测一遍,代码的可靠性就心里有数了。

从那以后我每次拿到新的阵列处理代码,都强制走一遍“单信号对 CBF、双信号对 MVDR、旁瓣对 Chebyshev”这三步验证,确认没问题再往项目里集成。这套前三章的案例代码本身不复杂,但把它的参数调透、边界摸清,后面做自适应波束形成或者 DOA 估计的时候会顺很多。希望帮到你。

本文还有配套的精品资源,点击获取

相关新闻

Assistants API实战:构建定制化AI Agent与知识库问答助手

Assistants API实战:构建定制化AI Agent与知识库问答助手

做AI Agent快两年,我最大的感受是:OpenAI Assistants API把“定制化AI Agent”这个事,从原来的DIY拼装变成了半成品套餐——你不用再自己维护会话历史、不用手写工具调用的循环、不用为多轮记忆写一堆状态管理代码,只要把“这个Ag…

2026/10/20 11:52:49 阅读更多 →
修正C/GMRES:嵌入式平台上实时NMPC的工程落地

修正C/GMRES:嵌入式平台上实时NMPC的工程落地

1. 潜航器控不住?实时NMPC是绕不开的路自动潜航器这东西,越往深水跑越不让人省心。水面下的水流、温度层、密度变化,加上潜航器本身的强非线性动力学,传统的线性控制器到了大机动工况下经常“使不上劲”。这几年做水下机器人控制的…

2026/10/20 11:52:49 阅读更多 →
net-snmp 实战指南:OID、community 权限与 snmpd 配置避坑

net-snmp 实战指南:OID、community 权限与 snmpd 配置避坑

简介:本资源是一份面向网络运维工程师、Linux系统管理员及初学者的Net-SNMP实战入门指南,聚焦SNMP协议在本地设备监控中的核心应用,解决SNMP代理部署、OID树结构理解与常用命令实操等关键问题。文档以清晰逻辑展开snmpd服务配置要点&#xff…

2026/10/20 11:52:49 阅读更多 →

最新新闻

提示词模板化:从基础到高级的Prompt Engineering实战指南

提示词模板化:从基础到高级的Prompt Engineering实战指南

1. 为什么要把提示词做成模板:从重复劳动到可复用资产先讲一个我自己的经历。早期用对话式AI干活的时候,每次都是临时想提示词,想到哪写到哪:“帮我总结一下这段文字”“写一个产品介绍,要专业一点”。这种随手写的做法…

2026/10/20 12:46:33 阅读更多 →
Kafka入门进阶:分区、副本、acks与消费者组核心机制详解

Kafka入门进阶:分区、副本、acks与消费者组核心机制详解

1. 从“能跑起来”到“跑得明白”:Kafka 基础入门的第二道坎很多人第一次接触 Kafka,都是照着官方 Quickstart 敲一遍命令行,看到生产者发消息、消费者收到消息,就觉得“我会了”。但真到了项目里,面对一堆server.prop…

2026/10/20 12:46:33 阅读更多 →
SpringBoot+Vue图书推荐系统源码解析:协同过滤与前后端分离实战

SpringBoot+Vue图书推荐系统源码解析:协同过滤与前后端分离实战

最近我在帮几位同学梳理毕业设计项目,被问得最多的就是“图书推荐系统”。这类题到现在依旧热门,原因也很简单:图书天然适合做推荐,用户行为数据容易理解,和电商推荐、短视频推荐比起来业务逻辑更干净,特别…

2026/10/20 12:46:33 阅读更多 →
技能不是标签而是动作:用刻意练习、反馈与复盘构建底层能力

技能不是标签而是动作:用刻意练习、反馈与复盘构建底层能力

很多人都把“技能”当成一个名词来理解,觉得自己会写代码、会做PPT、会剪辑视频,就算拥有一项技能。但真正带过人、自己从零啃过几门硬技能的人会知道,技能其实是动词——它是你每天都要做的一个动作,而不是简历上既能唬人又能自我…

2026/10/20 12:46:33 阅读更多 →
把涂鸦设备搬回局域网:Tuya-Local 本地控制与 Home Assistant 配置指南

把涂鸦设备搬回局域网:Tuya-Local 本地控制与 Home Assistant 配置指南

把涂鸦设备搬回局域网:Tuya-Local 本地控制与 Home Assistant 配置指南 【免费下载链接】tuya-local Local support for Tuya devices in Home Assistant 项目地址: https://gitcode.com/GitHub_Trending/tu/tuya-local Tuya-Local 是 Home Assistant 的一个…

2026/10/20 12:46:33 阅读更多 →
MCP协议驱动智能体底座架构设计:从插件思维到接口思维

MCP协议驱动智能体底座架构设计:从插件思维到接口思维

1. 从“插件思维”到“接口思维”的认知跃迁大多数人第一次接触MCP(Model Context Protocol,模型上下文协议)时,脑子里蹦出来的第一个词就是“插件系统”。这也不奇怪,毕竟它的外在表现确实像插件:你写一个…

2026/10/20 12:45:32 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

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

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

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

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

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

2026/10/20 1:01:30 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 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/20 10:02:08 阅读更多 →
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/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练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/20 9:50:45 阅读更多 →