资讯动态

YOLOv5锥桶识别实战:数据构建、训练调优与部署

发布时间:2026/10/27 21:00:58 来源:尧图企业网站定制
1. 项目整体设计与技术选型思路拆解1.1 锥桶识别到底在解决一个什么难题锥桶这东西学名交通锥工地上、临时占道施工的区域、大型活动停车场、物流园区的卸货区到处都能见到它。把它当成一个视觉检测任务的目标听起来特别简单——不就是个橙色圆锥嘛。但我实际做下来发现它属于那种看着简单、上手就翻车的典型目标。先梳理一下它的物理特性颜色高度饱和橙红为主顶部或腰部有一圈白色反光条几何形状是圆锥台投影到二维图像上会随着视角变化呈现三角形、梯形甚至一条竖线。尺寸跨度极大近处能占满画面的三分之一远处在 1080P 画面里只有十几个像素。更要命的是它经常成排、成组、密集堆叠出现NMS 稍微设不好就会把一整排锥桶只留下一个框。所以锥桶识别这个任务本质上要解决的是小目标检测、密集目标分离、强光照干扰下的颜色漂移这三件事的组合问题。它的典型落地场景包括施工区域的安全巡检判断围挡是否按规范摆放、工程车辆与作业机器人的环境感知别压到锥桶、别越过隔离线、道路场景理解的辅助标注、无人巡检设备的路径判断以及驾驶模拟器的场景资产构建。无论你是做视觉算法的新手想找一个练手项目还是工程侧需要一个能快速跑起来的检测模块这个题目都挺合适——数据好采、类别单一、效果直观但又能把检测任务里的大部分坑都踩一遍。1.2 为什么最终的骨干选了 YOLOv5选检测器这件事我最初的候选清单里有三四个方向。两阶段的方法精度确实好尤其对小目标但推理速度在边缘设备上很难看一个 640 分辨率的图跑出几百毫秒工地上要求实时回传就废了。早期的单阶段方法速度够快但对小目标的召回明显吃力锥桶这种远处只有十几像素的目标掉检率很难接受。还有一类是基于 Transformer 的检测方案精度漂亮但训练成本和显存开销对一个个人项目来说太重了。最后落到 YOLOv5主要是几个很实在的理由。第一是模型族完整n/s/m/l/x 五个规格参数从 1.9M 到 86.7M我可以先在 n 或 s 上快速验证数据质量和标注规范确认没问题再换大模型刷精度这个迭代节奏对个人项目太重要了。第二是工程成熟度仓库里训练、验证、推理、导出、超参搜索全都有现成脚本配置文件驱动改个 yaml 就能换数据集和结构不用自己写训练循环。第三是结构清晰Backbone 是 CSPDarknetNeck 用 PANet 做自顶向下加自底向上的双向融合Head 是三个尺度的检测头80×80、40×40、20×20对应输入 640 时这个结构理解起来门槛不高想改也很方便。我整理了一张对照表方便你根据自己的场景做判断方案推理速度小目标召回训练门槛部署生态适合场景两阶段检测器慢强中一般离线高精度分析早期单阶段检测器快弱低一般大目标、粗定位Transformer 类方案中强高较新算力充足的团队YOLOv5-n/s很快中等低极成熟边缘设备、实时巡检YOLOv5-m/l中较强低极成熟服务端、精度优先需要说清楚的是YOLOv5 是 anchor-based 的方法默认的 anchor 是在通用数据集上聚类出来的针对锥桶这种形状特殊的单一类别重新聚类 anchor 是有收益的后面会详细讲。另外它的损失函数用的是 CIoU对小目标的定位精度比早期的 IoU 损失要好一截这也是我倾向它的一个细节原因。1.3 整条链路的拆解与关键节点我把这个项目拆成六个环节每个环节的产出物都很明确方便逐段验证、逐段回退数据采集与清洗拿到带标注的原始图像池产出物是一个去重、去模糊、场景分布合理的图像集合。标注与规范统一产出物是 YOLO 格式的 txt 标注文件类别只有一个 cone。数据集划分与增强配置产出物是 images/labels 的 train/val/test 目录结构和 data.yaml。模型配置与训练产出物是 best.pt 和训练曲线。验证与 badcase 分析产出物是一份失效场景清单反哺数据。导出与推理部署产出物是 ONNX 或其它格式的模型文件和推理脚本。这条链路里最容易出问题、也最容易被新手忽略的是第 2 和第 3 步。我见过太多人把 90% 的精力花在调参上结果验证集 mAP 冲到 0.95一上真实视频就崩原因往往是验证集和训练集来自同一段连续视频帧间几乎一样模型等于在背答案。这个问题后面单独展开。2. 数据集从零构建的完整实操2.1 图像来源与采集的多样性设计锥桶图像不难搞难的是搞到分布合理的图像。我第一版数据集只有三百多张全是在同一个园区、同一个角度、同一个下午拍的训练出来 mAP 很好看但换个停车场就掉到六成以下。后来我把采集策略重做了一遍按下面的维度做了配额视角维度正前方平视、俯视监控或无人机、低角度仰视车载、斜侧 45 度。俯视角度的锥桶在图像上是同心圆或椭圆跟平视的三角形差别极大必须都要有。距离维度近景目标占画面 1/3 以上、中景、远景目标宽度小于 32 像素属于小目标。远景样本建议至少占总量三成否则模型对远处锥桶的召回会很难看。光照维度白天顺光、逆光剪影、黄昏、夜间有路灯、有车灯直射、阴雨天。夜间反光条会高亮成一条白线跟白天的观感完全不同。遮挡维度完整可见、被车辆遮挡一半、被其他锥桶叠压、只露出一角、倒伏状态。扰动维度被压扁的锥桶、脏污的、套了警示带的、与相似物共存的水马、隔离墩、锥形路障、红色消防栓、橙色的快递柜。采集手段上手机手持拍摄是最容易的注意不要只用一种焦距广角和长焦各拍一批模拟不同视场。行车记录仪视频可以逐帧抽但抽帧间隔要拉开建议按每 30 帧取一帧否则会得到大量高度相似的冗余样本。监控截图要注意分辨率和宽高比差异。公开的道路场景数据里通常带有一部分交通锥标注可以筛选合并但要检查它的标注框定义是否和你的标准一致比例尺差异大的数据混进来反而会污染分布。数据清洗这一步别省。我的做法是先跑一遍模糊度检测拉普拉斯方差低于阈值直接剔除再按感知哈希做近重复去重最后人工过一遍把画面里根本没有锥桶的、纯黑的、严重压缩失真的剔除掉。这一步大概会砍掉 15% 到 25% 的量但留下的每一张都有用。2.2 标注规范一致性比精细度更重要标注环节最核心的原则不是标得多准而是标得多一致。同一个目标A 同学框到反光条外沿B 同学只框橙色锥体部分模型学到的就是两套互相矛盾的标准最后谁的都不准。我定了一份简短的规则实操中挺管用类别只设一个cone。不要按大小、颜色、状态再分类除非你下游真的有这个需求。单类别能让损失函数收敛得更干脆也避免了类别不平衡。框的边界包含完整锥体加反光条但不要大面积把投影阴影框进去。阴影会在不同太阳高度角下长度变化巨大把它包进标签里等于给模型喂噪声。被遮挡的目标也要标标可见部分的外接矩形同时保证框里至少有 30% 的面积是真实目标像素。遮挡超过 70% 的我倾向于直接丢弃这张图里的这个目标不标也不当负样本。小目标的下限宽或高小于 8 像素的不标。低于这个尺度标注本身的主观误差就超过了信息量标了反而让模型学到噪声。倒伏的锥桶要标这是真实场景里高频出现的情况我专门攒了大概两百个倒伏样本。同一张图里锥桶数量超过 30 个的密集场景单独抽出来作为压力测试集不混进训练集用它来评估 NMS 参数是否合理。标注工具用常见的开源矩形框标注工具就够了导出格式选 YOLO 的 txt每行class x_center y_center width height全部归一化到 0~1。这里有个小坑归一化用的是图像原始宽高如果你在标注前做过缩放坐标就全错了。我的习惯是标注全程用原图缩放只在训练时的数据加载阶段做。标注完成后必须做一次自动校验检查四件事坐标是否都在 0~1 之间、宽高是否大于 0、是否存在重复框IoU 大于 0.9 的两行、图像文件与标签文件是否一一对应有没有图片没标签、有没有标签没图片。这四条我写了个几十行的脚本跑能挡掉八成的低级错误。2.3 数据集划分别让验证集骗了你这是我踩过最深的一个坑值得单独说。第一版我按 8:1:1 随机划分训练完 mAP0.5 到了 0.96我当时还挺得意。结果拿一段新视频一测漏检肉眼可见。排查了半天才想明白我的数据是从几段连续视频里抽帧的相邻帧之间目标位置只差几个像素随机划分会把几乎相同的图分到训练集和验证集里模型在验证集上等于做记忆题。正确的做法是按场景/视频源分组划分而不是按图片随机划分。具体来说先给每张图打上来源标签比如园区A下午、道路B夜间、无人机C俯拍然后按来源分组保证同一个来源的所有图只出现在一个子集里。这样验证集才是真正的没见过的场景指标才有参考价值。比例上我最后用的是训练 75%、验证 15%、测试 10%验证集用来调超参和早停测试集只在最后评估一次中途绝对不碰。如果某个场景的样本特别少比如夜间只有 40 张我会把它整体放进验证集专门看模型在弱光下的表现哪怕这会牺牲一点训练数据。还有一个细节测试集里要刻意留一些困难样本包括远距离小目标、严重遮挡、逆光剪影、密集排列。一个全是清晰正样本的测试集给你的 0.98 是虚假繁荣。3. 训练环境搭建与工程配置3.1 依赖版本对齐这件小事能卡你一整天环境这块我建议直接按官方仓库的requirements.txt装不要自作聪明升级。核心是三个东西的版本必须咬合PyTorch、torchvision、CUDA。我遇到最多的问题是torchvision::nms does not exist这个报错。原因几乎都是 PyTorch 和 torchvision 版本不匹配或者 CUDA 版本与预编译包对不上导致 torchvision 的 C 扩展加载失败。判断方法很简单开个 Python 交互环境跑import torch, torchvision print(torch.__version__, torchvision.__version__) print(torch.cuda.is_available()) from torchvision.ops import nms print(nms ok)如果最后一行报错别急着改代码先重装。我的稳妥组合是 Python 3.8 或 3.9 加 PyTorch 1.8 到 1.13 之间的某个版本配对应 CUDA 11.x 的官方预编译轮子。装完之后torch.cuda.is_available()必须是 True否则训练会掉到 CPU 上一个 epoch 跑几小时白等。另外两个容易忽略的依赖opencv-python建议装opencv-python-headless服务器上没有图形界面时避免冲突pyyaml版本不要太老否则读配置文件会有兼容问题。至于多卡训练、分布式这些单人项目完全用不上--device 0指定一张卡就行。显存这块提前算一下心里有数。以 yolov5s、输入 640、batch 16 为例模型权重加上梯度、优化器状态再算上 Mosaic 增强时一次要加载 4 张图拼成一张实际显存占用大概在 5GB 到 7GB 之间一张 8GB 的卡能跑但余量不多。如果显存不够优先降 batch降到 8 再降到 4其次降--img最后才考虑换更小的模型。3.2 目录结构和配置文件的具体写法YOLOv5 要求的目录结构其实很宽松只要 yaml 里路径指对就行。我习惯用下面这种扁平结构方便迁移cone_dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ └── cone.yaml关键点images 和 labels 的目录层级必须镜像对应YOLOv5 在找标签文件时是把路径里的/images/替换成/labels/再换后缀所以命名必须严格一致abc.jpg对应abc.txt不能有abc.JPG和abc.txt这种大小写不一致的情况。cone.yaml的内容# 数据集根路径用绝对路径最稳 path: /home/user/cone_dataset train: images/train val: images/val test: images/test # 类别数单类别就是 1 nc: 1 # 类别名顺序必须和标注里的 class id 对应 names: [cone]模型配置这边如果只是换类别数最省事的做法是不改yolov5s.yaml训练时用--data cone.yaml程序会自动把nc覆盖成 1并把检测头的输出通道数按(nc 5) × 3重算。但如果要重设 anchor就得复制一份 yaml 改。anchor 重聚类这件事对锥桶是有意义的。默认 anchor 来自通用数据集尺寸分布偏方而锥桶在平视视角下往往是高瘦的宽高比小于 1俯视视角下又是扁宽的。用 k-means 在自己的标注框上重新聚出 9 个 anchor分成三组给三个检测头对小目标的召回通常有一到两个点的提升。聚类时用 IoU 距离而不是欧氏距离迭代到中心不再变化为止然后按面积从小到大排好小 anchor 给高分辨率特征图80×80大 anchor 给低分辨率特征图20×20。3.3 预训练权重的取舍从零训练还是加载预训练权重对锥桶这种单类别小数据集答案毫无悬念是加载预训练。原因很直白你的数据集可能只有几千张但预训练模型是在百万级图像上学过边缘、纹理、颜色块这些通用特征的Backbone 已经具备很强的特征提取能力你只需要微调让它关注橙色圆锥这个特定模式。从零训练在几千张图上几乎必然过拟合而且收敛慢得离谱。具体用哪个权重如果你用 yolov5s 结构就加载yolov5s.pt用 m 就加载yolov5m.pt。注意结构必须对应拿 s 的权重去初始化 m 会报 shape mismatch。如果只是想换个输入尺寸权重不用换YOLOv5 支持动态输入训练时--img指定就行。还有一个技巧前期用--freeze 10冻结 Backbone 的前 10 层只训练 Neck 和 Head跑个 10 到 20 个 epoch 让检测头先适应新类别再解冻全量微调。这个做法在小数据集上很稳能明显减少前期的 loss 震荡。4. 训练过程与超参数的实际调法4.1 训练命令与每个参数背后的意图我的基线命令长这样python train.py \ --img 640 \ --batch 16 \ --epochs 150 \ --data data/cone.yaml \ --cfg models/yolov5s.yaml \ --weights yolov5s.pt \ --hyp data/hyps/hyp.scratch-low.yaml \ --optimizer SGD \ --patience 40 \ --device 0 \ --project runs/train \ --name cone_s_v1逐条解释为什么要这么设。--img 640是速度与精度的平衡点。锥桶在很多场景下是小目标理论上提高到 960 或 1280 对小目标召回有明显帮助因为目标在特征图上的像素更多了。但代价是显存占用按面积增长640 到 960 大约是 2.25 倍速度也明显下降。我的做法是先跑 640 拿到基线如果远景漏检严重再试 960做对比实验别一上来就 1280。--batch 16是在显存允许下的折中。batch 太小比如 2、4时 BN 层的统计量不稳定训练曲线会很抖batch 太大对收敛速度有影响学习率也要跟着调。经验上 8 到 32 之间都合理。--epochs 150配合--patience 40意思是如果在 40 个 epoch 内验证集 mAP 没有提升就提前停。这个早停机制很有用避免你为了等一个不存在的提升而空耗几小时。实际跑下来锥桶这种单类别任务80 到 120 个 epoch 基本就收敛了。--hyp data/hyps/hyp.scratch-low.yaml是低强度增强的超参文件。为什么选 low 而不是默认的 scratch因为锥桶的颜色和形状特征很关键默认配置里的 Mosaic、MixUp、色彩抖动强度偏大对单一类别的小数据集容易造成语义破坏——比如把锥桶涂成蓝色、把四个锥桶拼成一大团模型反而学不到稳定的颜色-形状关联。low 配置把 Mosaic 的概率从 1.0 降到 0.5 左右色彩抖动的幅度也收窄了我更推荐从这个起点开始。4.2 训练曲线的读法与常见异常训练开始后runs/train/cone_s_v1/目录下会生成results.csv和多张曲线图。我习惯盯四个量box_loss 和 obj_loss。正常情况下这两个都应该单调下降前期掉得快后期趋于平缓。如果 obj_loss 突然往上翘通常是学习率太大或者数据里有大量错误标注比如说好的都是锥桶结果混进了隔离墩。如果 box_loss 降得很慢但 obj_loss 降得快说明模型能判断这里有东西但框不准往往是 anchor 尺寸不匹配的信号。mAP0.5 和 mAP0.5:0.95。前者看整体检测能力后者看定位精度。如果前者高后者低得离谱比如 0.95 对 0.45说明框的大小位置偏差大可以考虑提高定位损失的权重或者重新聚类 anchor。precision 和 recall 的背离。如果 precision 很高但 recall 低说明模型很保守只对它确信的锥桶出框漏检多。这时候可以降低推理时的置信度阈值或者在训练时调低分类损失的权重。反过来 recall 高 precision 低就是框得太多太杂需要提高置信度阈值或者检查标注里有没有把非锥桶标成锥桶。过拟合的识别训练损失一直降、验证损失在某个点之后开始上升两条曲线明显分叉。这时候加数据是最有效的其次是加大增强强度最后才是减模型容量或者加正则。我的习惯是优先怀疑数据量不够因为锥桶这类任务模型容量通常不是瓶颈。4.3 三轮训练迭代的真实记录第一轮yolov5s640数据集 2800 张跑完 mAP0.5 是 0.87。看 badcase 发现主要问题在远景小目标和夜间样本远处锥桶大量漏检。第二轮没有加数据只是把--img提到 960同时用自己标注框聚类了 anchor。mAP0.5 到 0.91小目标召回明显改善但 GPU 显存吃紧batch 只能降到 8训练时间从 3 小时涨到 7 小时。这个性价比要自己权衡。第三轮补了约 1200 张数据重点补夜间、逆光、俯视这三个薄弱场景同时把倒伏锥桶单独补了 300 张。img 回到 640 但用 yolov5mmAP0.5 到 0.94mAP0.5:0.95 从 0.61 涨到 0.72。这一轮的收益最大也再次印证了那个老结论同样的时间花在数据上的回报远高于花在调参上。5. 推理验证与工程部署5.1 推理脚本的参数细节验证阶段用detect.py或者val.py。评估指标用val.pypython val.py --weights runs/train/cone_s_v1/weights/best.pt \ --data data/cone.yaml \ --img 640 \ --task val \ --conf-thres 0.001 \ --iou-thres 0.6注意这里的--conf-thres要给到 0.001 这么低因为 mAP 的计算需要遍历完整的 precision-recall 曲线阈值设高了曲线左边就缺了算出来的 mAP 会偏高不具有可比性。--iou-thres在验证阶段一般用 0.6比推理阶段的 0.45 稍高避免密集目标被过度抑制影响召回统计。真正推理跑视频或图片时参数就完全不一样了python detect.py --weights runs/train/cone_s_v1/weights/best.pt \ --source ./test_videos \ --img 640 \ --conf-thres 0.35 \ --iou-thres 0.45 \ --classes 0 \ --agnostic-nms \ --save-txt--conf-thres 0.35是我在锥桶上试出来的经验值。低于 0.25 时画面里的橙色消防栓、橙色锥形路障会被大量误检高于 0.5 时远处的小锥桶开始大量漏。0.3 到 0.4 之间是比较舒服的区间具体还要看你的场景对漏检和误检哪个更敏感——安全巡检宁可误检不要漏检那就往下压到 0.25。--iou-thres 0.45控制 NMS 的抑制强度。锥桶经常成排出现框之间重叠度不低如果这个值设得太小比如 0.3一排五个锥桶可能只留下两个。我用 0.45 到 0.5 之间密集场景下明显更稳。--agnostic-nms是类别无关的 NMS单类别任务里它其实没差别但如果你以后扩展成多类别锥桶、水马、隔离墩打开它能避免不同类别互相抑制。5.2 模型导出与部署侧的注意点训练完的.pt权重在 Python 环境下跑没问题但要部署到 C 服务或者边缘设备就得导出。常用的两条路# 导出 ONNX python export.py --weights best.pt --include onnx --img 640 --batch 1 --simplify # 导出 OpenVINOIntel 平台 python export.py --weights best.pt --include openvino --img 640 --batch 1导出 ONNX 时两个坑要记牢。一是--batch 1动态 batch 虽然支持但某些推理框架对动态维度的支持不完整固定 batch 1 最保险。二是--simplify它会跑一遍 onnx-simplifier 把冗余算子合并掉很多推理后端报不支持的算子就是因为没做这一步。导出后一定要做一次数值一致性校验用同一张图分别跑 PyTorch 和 ONNX比对输出的检测框坐标和置信度差值应该在 1e-3 量级以内。如果差得离谱通常是预处理不一致——比如 PyTorch 侧用的是 letterbox 填充ONNX 侧直接 resize 了输入分布就变了。这个对齐工作必须自己做别指望推理框架帮你处理。还有一个实际部署里绕不开的点后处理必须跟着模型一起走。YOLOv5 的输出是三个尺度的原始预测形状分别是 1×3×80×80×6、1×3×40×40×6、1×3×20×20×6在 nc1 时最后一维是 6解码、阈值过滤、NMS 这些都要在推理侧实现。如果你只导出模型不管后处理那等于把活干了一半。5.3 用什么指标判断能不能上线mAP 是个学术指标工程上我更多看三个数在目标距离上的召回率。我会把测试视频按目标框宽度分档小于 24 像素、24 到 64 像素、大于 64 像素分别统计召回。如果小目标档位的召回低于 70%这个模型在实际场景里就会频繁出现近了才看得见的尴尬。单位时间误检数。跑一段 10 分钟的正常道路视频画面里没有锥桶统计每秒误检框的数量。这个指标直接决定用户体验超过 0.5 个/秒就基本没法用了。推理帧率。在目标硬件上跑看能不能达到业务要求的帧率。GPU 上 yolov5s 640 输入通常能到 100 FPS 以上CPU 上可能只有个位数这个差距必须提前评估清楚别训练完了才发现部署设备跑不动。6. 常见问题排查速查与避坑心得6.1 问题速查表下面这张表是我这一年多攒下来的按现象查原因能省不少时间现象最可能的原因排查与解决训练 loss 变 NaN学习率过大 / 标注坐标越界降 lr 到 0.001跑标注校验脚本检查坐标范围mAP 一直卡在 0 附近类别名与标注 class id 不对应 / 标签路径没对上检查 yaml 的 names 顺序确认 labels 目录结构与 images 镜像验证集 mAP 奇高但实际效果差数据划分泄漏训练集与验证集同源改为按视频源/场景分组划分重跑远处锥桶大量漏检输入分辨率不足 / 小目标样本太少提高--img到 960补充远景样本并保留小 anchor同一排锥桶只检出两三个NMS 的 iou-thres 过小提到 0.5 左右密集场景可试 soft-NMS橙色物体大量误检负样本不足 / 置信度阈值过低补纯背景负样本图conf-thres 提到 0.4夜间几乎全漏训练集夜间样本占比过低夜间样本占比提到 15% 以上并做亮度扰动增强导出 ONNX 后结果全错预处理不一致 / 未做 simplify对齐 letterbox 逻辑加--simplify导出显存溢出 OOMbatch 或 img 过大依次降 batch、降 img、换小模型训练速度异常慢实际跑在 CPU 上 / dataloader 线程少确认 cuda.is_available()调--workers到 CPU 核数的 0.7 倍6.2 三条我觉得最值钱的经验第一条负样本比你想象的重要得多。我最初的数据集全是含锥桶的正样本训练出来模型对橙色极其敏感路边的消防栓、橙色的共享单车、快递柜上的橙色贴纸全被框成锥桶。后来我专门采集了 400 张绝对没有锥桶但颜色相近的图标签文件留空空 txt混进训练集。这一招直接把误检率砍掉了一半以上。负样本不需要多但要覆盖你的场景里那些长得像但不是的东西。第二条数据集要能长大别一次做完。我的做法是先标 800 张跑一轮拿模型去推理剩下的未标注图把高置信度的预测框导出来当预标注人工只需要修正效率能提高三四倍。这个主动学习的循环跑三轮数据量从 800 涨到 4000人工标注时间反而比一次性标 4000 张少。代价是要注意别让模型的偏见固化——每轮都要人工抽查一部分高置信度预测确认没有把错误当成正确喂回去。第三条别迷信 mAP 的小数点后两位。我在 0.93 和 0.94 之间折腾过整整两天换了好几个超参组合最后发现实际视频里的观感没有任何区别。真正带来质变的是补数据、换分辨率、改 anchor 这三件事。当你的 mAP 已经过了 0.9继续往上抠收益极低不如去分析 badcase 的场景分布看看是不是某类场景整体缺失。6.3 关于后续扩展的一点想法这个项目做扎实之后往外延的方向挺多。可以把类别从单一的cone扩展成锥桶 水马 隔离墩 施工围栏做成一个施工区域元素的检测器也可以把检测和跟踪结合用简单的 IoU 匹配或者卡尔曼滤波统计某段路上锥桶的数量变化判断围挡是否被移动过还可以把检测框和分割结合用分割结果判断锥桶是否倒伏——倒伏的锥桶在检测框里是看不出来的但分割掩码的形状能反映出来。如果你也在做类似的项目我最后分享一个自己一直在用的习惯每训练完一版都固定用同一段 3 分钟的黄金测试视频跑一遍把结果录下来存着。这段视频要覆盖你所有的目标场景。这样每次改动带来的效果变化是可视化、可对比的比看一堆曲线直观得多也更容易说服别人这个改动到底值不值。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑