ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

基于YOLOv8的仓库货物盘点系统:从训练到部署全流程实战

基于YOLOv8的仓库货物盘点系统:从训练到部署全流程实战 简介本资源为基于YOLOv8的仓库货物盘点系统完整项目包面向计算机、人工智能、通信工程等专业的在校学生与教师适合作为毕业设计、课程设计或大作业的参考方案也便于初学者进阶学习目标检测的落地流程。包内共97个文件以70个Python源码为核心辅以4个pt权重文件、5个xml配置、12个pyc缓存及mp4演示视频等压缩包约24.21MB涵盖模型训练、检测推理、可视化界面与部署说明等模块。项目已通过运行测试可生成核心指标曲线、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果与标签分布图并配有可视化页面部署简单、操作直观。目前已有48人学习下载读者可据此快速复现完整盘点流程理解YOLOv8训练与推理细节并在此基础上修改扩展功能满足答辩与项目演示需求。1. 仓库货物盘点系统为什么值得用 YOLOv8 重做一遍做过仓库盘点的人都清楚传统方式无非两种人工拿着 PDA 逐个扫码或者靠电子标签、地磅、称重来间接推算。前者慢一个人一天盘不了几个货架后者贵改造一套 RFID 或称重货架的成本中小仓库根本扛不住。而基于 YOLOv8 的仓库货物盘点系统本质上是把「看一眼就知道有多少箱、什么品类、有没有缺货」这件事交给摄像头和检测模型来做——固定机位拍货架模型识别货箱类别与数量再叠加一个可视化界面把结果呈现出来配合完整数据集和部署教程简单部署即可运行。这套方案真正吸引人的地方在于门槛被拉低了。YOLOv8 本身是 Ultralytics 维护的单阶段检测框架训练脚本封装得相当干净yolov8n.pt这种小模型在普通显卡甚至 CPU 上都能跑推理。仓库货物盘点这个场景又天然适合检测任务货箱边界清晰、类别有限、光照相对可控不像自动驾驶那样有极端的长尾情况。所以它特别适合两类人——一类是拿它做毕设或课程设计的学生需要一套功能完善、操作简单、能演示、能写进论文的完整项目另一类是仓库一线想先做个原型验证的工程师想用最低成本看看视觉盘点到底靠不靠谱。我先把结论放这儿这套东西能跑通但「能跑通」和「盘得准」之间隔着数据集的坑、类别定义的坑和部署环境的坑。下面几章我会把从环境搭建、数据集处理、训练调参到界面部署的完整路径拆开讲中间专门留一章讲我踩过的坑最后一章讲怎么验证它到底值不值得投入。2. 从零把 YOLOv8 仓库盘点环境跑起来2.1 环境选型CPU 版还是 GPU 版先想清楚很多人一上来就纠结装哪个版本其实判断标准很简单你是要训练还是要推理。如果只是拿现成权重跑推理、做界面演示CPU 版完全够用yolov8n在 CPU 上单张图推理大概几百毫秒盘点场景不需要实时 30 帧够看。但如果你要拿自己的数据集重新训练那必须上 GPUCPU 训练一个 epoch 能让你等到怀疑人生。我一般推荐 Ubuntu 20.04 作为基础系统Python 用 3.9 或 3.10这两个版本和 PyTorch、Ultralytics 的兼容性最稳。Windows 也能跑但后面部署到边缘设备或者做服务化的时候Linux 会省很多事。下面是一套 CPU 版的最小安装流程GPU 版把 torch 的安装命令换成对应 CUDA 版本即可。# 创建独立环境别污染系统 Python conda create -n warehouse python3.10 -y conda activate warehouse # CPU 版 PyTorch体积小、装得快 pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu # 安装 ultralytics它会自动带上 opencv、numpy 等依赖 pip install ultralytics # 验证安装能打印版本号就说明通了 yolo version这段命令的逻辑是先隔离环境再装 PyTorch 作为推理后端最后装 ultralytics 这个高层封装。参数上唯一要注意的是--index-url它决定了你装的是 CPU 版还是 CUDA 版装错了不会报错但训练时会发现用不上显卡。验证那一步别省yolo version能跑通说明命令行入口已经注册好了后面所有yolo开头的命令才有意义。提示如果你用的是 GPU把第二条命令换成pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118具体 cu 版本要和你显卡驱动支持的 CUDA 版本对齐装完用torch.cuda.is_available()确认返回 True。2.2 目录结构先规划好别等训练完再搬家仓库盘点项目文件不少——数据集、权重、配置文件、界面代码、部署脚本。我见过太多人把所有东西堆在一个文件夹里最后自己都找不到哪个权重是哪个数据集训出来的。建议一开始就按下面的结构组织warehouse_inventory/ ├── datasets/ │ └── warehouse/ │ ├── images/ │ │ ├── train/ │ │ └── val/ │ ├── labels/ │ │ ├── train/ │ │ └── val/ │ └── data.yaml ├── runs/ # 训练输出ultralytics 自动生成 ├── weights/ │ └── best.pt ├── ui/ # 可视化界面代码 └── deploy/ # 部署脚本这个结构的核心是datasets和runs分离。datasets放原始数据和标注runs是训练过程自动产出的日志、权重、曲线图两者混在一起会让你在清理实验时误删数据。data.yaml是 YOLOv8 读取数据集的入口文件它的路径写法直接决定训练能不能启动下一节会专门讲。2.3 data.yaml 怎么写三个路径字段一个都不能错data.yaml是训练配置里最容易翻车的地方因为它对路径的解析规则有点反直觉。一个能用的仓库盘点配置长这样# 数据集根目录建议写绝对路径避免相对路径歧义 path: /home/user/warehouse_inventory/datasets/warehouse train: images/train val: images/val # 类别数和类别名顺序必须和标注文件里的 class id 对应 nc: 5 names: 0: carton_large 1: carton_small 2: pallet 3: bag 4: empty_slot这里的关键是path和train/val的关系train和val是相对于path的路径不是相对于 yaml 文件本身。很多人把train写成绝对路径结果和path拼接后变成双重路径训练直接报找不到图片。nc和names必须严格对应names的 key 就是标注文件里每行开头的数字写错一个模型就会把货箱学成托盘。注意empty_slot这个类别是我强烈建议加的。仓库盘点不只是数货还要发现空位把「空货位」当成一个类别去检测比事后用规则判断更稳。2.4 用预训练权重先跑一次推理确认链路通在动训练之前先用官方预训练权重跑一次推理确认环境、模型加载、结果保存这条链路是通的。这一步能帮你排除掉 80% 的环境问题。# 用最小的 yolov8n 权重对一张货架图做推理 yolo predict modelyolov8n.pt source./test_shelf.jpg saveTrue conf0.25 # 输出会保存在 runs/detect/predict/ 下model指定权重第一次运行会自动下载yolov8n.ptsource可以是单张图、文件夹甚至摄像头编号saveTrue把带框的结果图存下来conf0.25是置信度阈值低于这个值的框不显示。跑完去看输出图如果框的位置离谱或者一个框都没有先别怀疑模型大概率是图片路径或者图片本身有问题。这一步跑通说明你的 YOLOv8 环境是健康的可以进入数据集环节了。3. 数据集处理仓库货物盘点标注与格式转换3.1 仓库场景的数据集该怎么采、怎么标数据集是这套系统里最花时间、也最决定上限的部分。仓库场景的采集有几个要点机位要覆盖你实际部署时会用的角度一般是斜上方俯拍货架光照要包含白天和夜间开灯两种因为仓库晚上灯光和白天差别很大货箱的堆叠状态要多样单箱、满架、半空都要有。数量上每个类别至少 200 到 300 个实例5 个类别的话1000 到 1500 张图是个比较现实的起点。标注工具用 labelme 或 labelImg 都行但要注意YOLOv8 要的是 YOLO 格式的 txt不是 labelme 默认的 json。如果你用 labelme 标需要转换用 labelImg 直接选 YOLO 格式导出更省事。标注时有个血泪经验——货箱边界框要贴着箱体边缘不要把整个货架层都框进去否则模型学到的「货箱」会包含大量背景推理时框会偏大。3.2 从 labelme 的 json 转成 YOLO 的 txt如果你手上是 labelme 标注的 json下面这个脚本能批量转换。它的逻辑是读每个 json 里的多边形点算出外接矩形再按图像宽高归一化成 YOLO 需要的class cx cy w h格式。import json import os from pathlib import Path # 类别名到 id 的映射必须和 data.yaml 里的 names 一致 class_map {carton_large: 0, carton_small: 1, pallet: 2, bag: 3, empty_slot: 4} def convert(json_dir, out_dir, img_w, img_h): os.makedirs(out_dir, exist_okTrue) for jf in Path(json_dir).glob(*.json): data json.loads(jf.read_text(encodingutf-8)) lines [] for shape in data[shapes]: label shape[label] if label not in class_map: continue # 跳过未定义类别避免训练时报错 pts shape[points] xs [p[0] for p in pts] ys [p[1] for p in pts] # 计算外接矩形并归一化 cx (min(xs) max(xs)) / 2 / img_w cy (min(ys) max(ys)) / 2 / img_h w (max(xs) - min(xs)) / img_w h (max(ys) - min(ys)) / img_h lines.append(f{class_map[label]} {cx:.6f} {cy:.6f} {w:.6f} {h:.6f}) # 同名 txt 输出 (Path(out_dir) / (jf.stem .txt)).write_text(\n.join(lines), encodingutf-8) convert(./labels_json, ./labels_txt, 1920, 1080)参数说明img_w和img_h必须是你标注时那张图的真实尺寸写错了归一化坐标就全错模型会学到完全错误的框。class_map要和data.yaml的names严格一致顺序错了类别就串了。转换完建议随机抽几张用可视化脚本把框画回图上确认一遍别直接扔进训练。3.3 数据集划分与目录落位转换完的 txt 和原图要按 train/val 分开放。常见做法是 8:2 划分但仓库场景我建议 7:3因为不同货架的差异比较大验证集太小会看不出过拟合。划分脚本很简单核心就是随机打乱后按比例复制import random, shutil from pathlib import Path imgs list(Path(./images_all).glob(*.jpg)) random.seed(42) # 固定种子保证可复现 random.shuffle(imgs) split int(len(imgs) * 0.7) for i, img in enumerate(imgs): subset train if i split else val shutil.copy(img, f./datasets/warehouse/images/{subset}/{img.name}) lbl Path(./labels_txt) / (img.stem .txt) if lbl.exists(): shutil.copy(lbl, f./datasets/warehouse/labels/{subset}/{lbl.name})random.seed(42)是为了让每次划分结果一致方便复现实验。图片和标签必须同名同批移动漏掉标签的图片在训练时会被当成负样本反而干扰模型。落位完成后目录结构要和第 2 章规划的一致data.yaml里的train/val指向images/train和images/val即可。4. 训练、调参与模型导出让盘点模型真正可用4.1 启动训练一条命令背后的参数含义数据集准备好后训练本身是一条命令的事但参数决定了你得到的是能用的模型还是废权重。yolo detect train \ datadatasets/warehouse/data.yaml \ modelyolov8n.pt \ epochs100 \ imgsz640 \ batch16 \ lr00.01 \ patience20 \ projectruns/warehouse \ nameexp1逐个说data指向你的 yamlmodelyolov8n.pt表示从预训练权重开始微调这比从零训练收敛快得多仓库这种小数据集千万别从零训epochs100是上限实际会被patience提前终止imgsz640是输入分辨率货箱目标如果很小可以提到 960 甚至 1280但显存和速度会成倍变化batch16按显存调爆显存就减半lr00.01是初始学习率微调场景这个值比较稳patience20表示 20 个 epoch 验证指标不提升就停这是省时间的后悔药。4.2 关键参数怎么调三个最影响盘点效果的旋钮训练参数几十个但真正影响仓库盘点效果的我认为就三个。第一个是imgsz。仓库货架图往往是高分辨率货箱在整图里占比不大640 可能让远处的小箱变成几个像素。我的经验是如果验证时发现漏检集中在远货架就把imgsz提到 960同时batch减半。第二个是数据增强里的mosaic和mixup。YOLOv8 默认开 mosaic它把四张图拼成一张对小目标友好但仓库场景货箱堆叠有固定结构过度拼接会让模型学到不真实的组合。我一般把mosaic0.5调低mixup保持默认或关掉。第三个是类别不平衡。如果empty_slot样本远少于货箱模型会倾向不预测它。可以在 yaml 里给类别加权或者干脆多补采空货位的图。这个没有一键参数只能靠数据层面解决。4.3 看训练曲线怎么判断该停还是该救训练跑起来后runs/warehouse/exp1/下会有results.csv和一堆曲线图。重点看三条线train/box_loss和val/box_loss的差距如果验证损失很早就开始上升而训练损失还在降就是过拟合该早停或者加数据metrics/mAP50是主指标仓库盘点一般能到 0.85 以上算可用metrics/mAP50-95更严格能反映框的精度如果它明显偏低说明框的位置不够准回去检查标注质量。如果 mAP 卡在 0.5 左右上不去先别调参回去看验证集的预测图。十有八九是标注框偏大、类别标错或者验证集里有训练集没见过的货架类型。调参救不了数据问题这是我踩过最深的坑。4.4 导出模型给界面和部署用训练完的best.pt是 PyTorch 权重界面调用可以直接用。但如果要部署到边缘设备或者追求推理速度可以导出成 ONNX# 导出 ONNX动态轴适配不同输入尺寸 yolo export modelruns/warehouse/exp1/weights/best.pt formatonnx dynamicTrue simplifyTrueformatonnx指定导出格式dynamicTrue让输入尺寸可变simplifyTrue会做图优化减小体积、提升推理速度。导出后的 onnx 文件可以脱离 ultralytics 环境用 onnxruntime 加载这对部署到没有 Python 环境的设备很关键。如果你的目标是 RK3588 这类板端还需要进一步转成 RKNN那是另一套流程核心是把 ONNX 作为中间格式。5. 可视化界面与部署把模型变成能演示的系统5.1 界面选型Gradio 最快PyQt 最像「系统」可视化界面这块取决于你的用途。如果是毕设演示、快速验证Gradio 是首选几十行代码就能做出上传图片、显示检测结果、统计数量的网页界面。如果要求是一个能打包成 exe 的桌面「系统」那 PyQt 或 PySide 更合适看起来更正式但开发量大。Gradio 的最小实现长这样import gradio as gr from ultralytics import YOLO model YOLO(runs/warehouse/exp1/weights/best.pt) def detect(img): results model(img, conf0.3) # 统计每个类别的数量用于盘点 counts {} for box in results[0].boxes: cls model.names[int(box.cls)] counts[cls] counts.get(cls, 0) 1 # 返回带框的图和统计文本 annotated results[0].plot() summary \n.join(f{k}: {v} for k, v in counts.items()) return annotated, summary gr.Interface( fndetect, inputsgr.Image(typenumpy), outputs[gr.Image(typenumpy), gr.Textbox(label盘点结果)], title仓库货物盘点系统 ).launch(server_name0.0.0.0, server_port7860)conf0.3是界面里的置信度阈值比训练时略高是为了减少误检盘点场景宁可漏检也别把空位误报成货箱。results[0].plot()直接返回画好框的 numpy 图省去自己画框。counts字典就是盘点结果按类别汇总数量。server_name0.0.0.0让局域网内其他设备也能访问方便演示。5.2 部署到服务器用 systemd 保活界面跑起来只是第一步要让它长期稳定运行得用进程守护。Linux 下用 systemd 是最省心的# /etc/systemd/system/warehouse.service [Unit] DescriptionWarehouse Inventory UI Afternetwork.target [Service] Userubuntu WorkingDirectory/home/ubuntu/warehouse_inventory ExecStart/home/ubuntu/miniconda3/envs/warehouse/bin/python ui/app.py Restartalways RestartSec5 [Install] WantedBymulti-user.targetExecStart要用你 conda 环境里的 python 绝对路径否则 systemd 找不到依赖。Restartalways保证崩溃后自动拉起RestartSec5是重启间隔。写完systemctl daemon-reload systemctl enable --now warehouse就能开机自启。这套配置我在多个项目里用过比 nohup 靠谱得多。5.3 部署到边缘设备模型转换的注意点如果要把盘点系统放到仓库现场的边缘盒子上比如 RK3588 这类带 NPU 的板子流程是 PyTorch → ONNX → RKNN。关键注意点有两个一是导出 ONNX 时输入尺寸最好固定动态轴在板端转换时容易出问题二是量化INT8 量化能大幅提速但仓库场景里货箱颜色接近量化后精度可能掉几个点建议先用 FP16 验证精度再决定要不要 INT8。板端部署的坑主要在算子支持上转换时如果报某个算子不支持通常需要换更简单的模型结构或者手动替换算子。6. 避坑与排查仓库盘点项目里最容易翻车的五件事6.1 训练 loss 正常但 mAP 一直是 0现象训练日志里 box_loss 在降但 mAP50 始终是 0 或者极低。原因九成是data.yaml的names顺序和标注文件的 class id 对不上或者nc写错。模型在学但学到的类别和验证时对不上指标自然为 0。解决随便打开一个标注 txt看每行第一个数字和 yaml 里的 names 逐一对再确认nc等于 names 的条目数。这个坑我见过太多次改完立刻正常。6.2 推理时框全堆在货架顶部现象检测结果里所有框都集中在图像上方位置明显不对。原因标注时用了错误的图像尺寸做归一化比如原图是 1920x1080转换脚本里却传了 640x640。归一化坐标是按错误尺寸算的模型学到的框位置整体偏移。解决重新用正确尺寸转换一遍标注或者写个脚本批量校验归一化坐标是否都在 0 到 1 之间超出范围的直接暴露问题。6.3 界面能跑但一上传大图就卡死现象Gradio 界面上传手机拍的高分辨率图页面转圈很久甚至超时。原因模型推理前会把图缩放到imgsz但读图和预处理本身在高分辨率下很耗时加上 CPU 推理单张图可能要好几秒。解决在detect函数里先把输入图缩到长边 1280 再送模型或者把imgsz设小一点。如果还是慢考虑导出 ONNX 用 onnxruntime 推理CPU 上通常比 PyTorch 快一截。6.4 换了个仓库就完全盘不准现象在 A 仓库训的模型拿到 B 仓库推理漏检误检一大堆。原因模型过拟合到了 A 仓库的货架结构、光照和货箱外观泛化性不足。解决这不是调参能解决的要么在 B 仓库补采数据做微调要么在训练时就加入多仓库、多光照的数据增强。我的习惯是训练集里至少混入两个不同货架布局的数据哪怕每个少一点泛化性会好很多。6.5 部署后服务莫名其妙挂掉现象systemd 服务跑一段时间就重启日志里看不出明显错误。原因多半是内存泄漏或者显存没释放尤其是反复加载模型或者处理大图时。解决把模型加载放在全局只做一次不要在每次请求里重新YOLO(...)处理完的中间变量及时释放在 systemd 里加MemoryMax限制超了让它重启而不是拖垮整机。这个坑比较隐蔽加个内存监控日志会好排查很多。7. 怎么验证这套盘点系统值不值得投入到这一步系统能跑、能演示了但真正决定要不要投入生产得看几个硬指标。我一般会做一轮小规模实测选一个真实货架人工数一遍作为 ground truth然后用系统盘三遍看三次结果的一致性和与人工的偏差。如果同一张图三次结果都不一样说明模型不稳定可能是置信度阈值卡在了边界上如果稳定但和人工差得多那是模型精度问题。验证时重点看两个数盘点准确率识别正确的货箱数 / 实际货箱数和误报率把空位或杂物误判成货箱的比例。仓库场景里误报比漏检更烦人因为漏检你还能靠人工补误报会让你以为有货实际没有。所以阈值宁可调高一点conf从 0.3 起根据实测往上加。还有一个容易被忽略的验证维度不同光照下的稳定性。白天和夜间开灯各测一轮如果夜间掉得厉害要么补夜间数据要么在摄像头端加补光。这个不是模型的问题是采集端的问题但会直接决定系统能不能 24 小时用。最后说个我自己的习惯。每次训完一个版本我都会把best.pt、data.yaml、results.csv和当时的验证图打包存一份命名带上日期和数据集版本。因为仓库盘点这种项目你永远不知道哪天老板会说「上个月那个版本好像更准」。留好后悔药比事后重新训一遍省太多事。这套基于 YOLOv8 的仓库货物盘点系统从技术路径上完全可行成本也压得住值不值得做取决于你的场景里货箱类别是否稳定、光照是否可控——这两点满足就可以动手了。希望帮到你。本文还有配套的精品资源点击获取
返回列表