☰
基于YOLOv10的超市空货架识别检测系统实战
2026/10/22 14:48:04 网站建设 项目流程

去年帮某连锁超市做自动化运营试点时,店长指着一排刚被顾客拿空的货架跟我说,每天最费时间的不是搬货上货,而是满场巡查“哪排空了、哪排要补”。这个痛点其实很普遍——超市补货决策长期依赖人力巡检,而人眼巡检效率低、覆盖不完整、巡检间隔一长就容易出现陈列空洞。当时我就琢磨,与其让人一趟趟跑,不如给货架装上“视觉感知”的能力。经过一个多月方案对比、现场拍摄、模型迭代,最终落地了一套基于YOLOv10的超市空货架识别检测系统。这篇文章我会把这套系统的完整实现过程拆开来讲,从方案选型、数据采集与标注、模型训练到UI界面搭建,把关键步骤、参数选择和踩过的坑一并整理出来,给打算做零售场景视觉识别的朋友一份可复现的实战参考。

这套系统本质上做了一件事:把摄像头传回来的货架画面,实时识别出哪些货位已经卖空。它不仅替代了人工巡检的大部分工作,还能把空货架的位置、时间、次数记录下来,为补货计划和陈列管理提供量化依据。无论你是在做零售数字化相关项目,还是想拿YOLOv10练手做一个完整的落地Demo,这篇内容都值得你从头到尾看一遍。

1. 项目定位与方案选型

1.1 空货架识别到底在解决什么问题

超市运营里有个说法叫“陈列空洞率”,指的是货架上缺货、陈列不饱满的货位占总货位的比例。这个指标直接影响销售额和顾客体验——顾客想买的商品不在货架上,转手就去隔壁买了。所以补货管理是超市运营的核心环节,而补货决策依赖的却是最原始的手段:员工拿着巡检表,隔几个小时走一圈,靠眼睛看哪排空了、哪排快空了。

这套人工巡检流程有几个很现实的问题:

  • 巡检频率有限,非营业高峰时段经常出现长时间无人关注空货架的情况
  • 人的注意力会疲劳,货架层数多、商品密集时,漏看很常见
  • 巡检结果靠纸质记录,无法形成结构化的时间分析数据

我在项目启动前实地蹲过几天,发现同一个门店,高峰期过后半小时内就能产生十几处空货位,而员工当时可能正在仓库备货。所以这个项目的核心不是“识别得有多准”这种技术炫技,而是为补货管理提供一套低成本的自动化感知能力——摄像头常态化监测,系统实时提示,员工按图补货。这是整个方案设计的第一原则。

1.2 为什么最终选了YOLOv10

选型阶段其实对比过好几条路线,包括传统图像处理方案、YOLOv5系列,以及当时已经发布的YOLOv8和YOLOv10。最终选择YOLOv10,主要看中它在检测性能和部署成本之间做到了很理想的平衡。

说几个具体理由:

  • 端到端架构节省推理时间:YOLOv10引入了无NMS训练机制,模型推理时不需要额外的后处理去重流程,端到端延迟更低。在批量处理货架图片时,吞吐量比需要NMS后处理的同参数级模型明显要好。
  • 小目标检测能力够用:货架上的商品往往很小,一瓶饮料在画面里可能只占几十个像素。YOLOv10的轻量级分类头和空间解耦设计对小目标召回有专门优化,实测下来对小瓶装商品和货架角落空位的检出率不错。
  • 模型体积可控:空货架检测这种场景不需要超大模型,用YOLOv10的s/m级模型就能达到实用精度,训练和推理对硬件要求都不高,店面级部署成本可控。

可能有人会问,为什么不直接用现成的目标检测API方案?原因也很简单:一是店面摄像头画面需要实时本地处理,云端方案有带宽和延迟问题;二是空货架识别这个场景公共模型数据集里没有对应训练,需要自建数据集微调,开源模型体系更适合做这种定制化训练;三是数据和预测结果需要和门店补货流程打通,本地化部署更容易实现系统集成。

1.3 系统整体架构与工作流程

这套系统的架构可以分为四个模块,结构比较清晰:

  • 图像采集模块:使用门店已有的监控摄像头接入RTSP视频流,系统从中抽取关键帧用于分析。没有现成摄像头的测试环境,也可以先用图片导入接口做验证。
  • 检测推理模块:加载训练好的YOLOv10模型,对抽取的视频帧做目标检测,识别“空货架”和“非空货架”两类目标。检测结果按货位坐标框输出,并附置信度分数。
  • 业务逻辑模块:对检测结果做业务化处理,比如统计空货位数量、计算空置率、判断空置持续时间、生成补货提醒。
  • 可视化UI模块:提供桌面级操作界面,展示实时视频画面、检测结果叠加框、统计数据面板和历史记录查询。

这个架构看起来不复杂,但每个模块都有不少细节要处理。比如摄像头角度不固定怎么办?不同时段光照差异大怎么办?空货架判定边界怎么定义?这些我都会在后面逐一展开。

2. 数据集构建与标注规范

2.1 数据采集时最容易忽略的坑

空货架识别不是像COCO那样的通用场景,市面上没有现成的公开数据集可用。所以数据这块必须自己搞,而这一步恰恰是很多项目翻车的重灾区——模型效果不好,八成是数据出了问题。

采集阶段我的建议是不要图省事只在同一个角度拍。货架识别面对的摄像头视角可能五花八门:正向的、斜45度的、俯视的,甚至低角度仰视的。训练数据里只覆盖正向视角,部署到斜视角摄像头就会掉精度。我踩过的坑就是第一批数据只拍了正向的,换到现场斜视角测试时,空货架的召回率直接掉了一截。后来补拍了一大批不同视角的样本,模型才稳下来。

采集时要注意几个方面:

  • 多时段覆盖:营业前、营业高峰期、傍晚补货后都要拍,因为光照条件完全不同,货架上商品的分布状态也不一样
  • 多货架类型:普通层板货架、端架堆头、冷柜货架都要覆盖,不同货架类型的“空”的表现形式差异很大
  • 空/半空/满的均衡:不要只拍“全满”和“全空”两个极端,要留一部分“还剩两三件商品”的中间状态样本,这种边缘情况最考验模型
  • 分辨率控制:采集图片至少不低于1280x720,画面上货架区域占比太小的话,单独处理局部区域更合适

2.2 “空”的判定标准怎么定

数据标注前必须先明确一个问题:什么算“空货架”?听起来很简单,实际操作中边界很模糊。货架上还剩一瓶饮料算不算空?还剩一排但只有前面被拿空了算不算空?这些判定规则直接决定标注质量,而标注质量直接影响模型学习效果。

我最后定了一套可操作的标准,供你参考:

状态判定标准标注处理
完全空置货位隔板范围内商品全部被取走,露出底部背板标注为空货架
接近售罄剩余商品数量不超过该货位陈列量的10%(通常只剩一两件)标注为空货架
部分空缺商品被拿走大半,但仍有明显陈列,比如还有3件以上不标注
正常陈列商品基本填满货位,视觉上没有明显空洞标注为非空货架

这套标准的核心思路是:只要货位的“陈列饱满度”低到顾客一眼扫过去觉得“这里缺货”的程度,就判为空货架。接近售罄的货位本来就是补货黄金时机,提前报出来对运营更有利。部分空缺的货位虽然也有缺口,但还能撑一段时间,不着急提醒。

2.3 YOLO格式标注的操作要点

标注工具我用的LabelImg,设置成YOLO格式输出,每个图片对应生成一个同名的txt文件,里面每一行是一个目标的标注信息:类别ID、中心点x坐标、中心点y坐标、目标宽度、目标高度(这些值都被归一化到0到1之间)。

标注过程中的实操细节:

  • 类别ID我就不设太多,0代表空货架,1代表非空货架。类别少,模型的学习负担小,不容易混淆
  • 标注框要贴合货位区域,不要只框空洞部分,而是框整个货位隔板范围。原因是模型需要学习的是“这个货位处于空置状态”,而不是“这里有个空洞形状”
  • 一个画面里如果有多排货架,尽量把每一排都标出来,让模型学会区分不同排次的货位状态
  • 标注完用脚本做一次校验,看看有没有漏标、框超出图片范围、类别ID越界之类的问题

这里有个经验之谈:标注框不要标得太“抠”。有些朋友总想把框贴合到毫米级,其实没这个必要。货架检测只需要判断到货位级别,稍微松一点、让框包含一部分货架隔板的边缘,反而能让模型把“货位”和“货位状态”更好地对应起来,训练效果更稳。

2.4 数据增强与划分策略

标注完成后,数据集需要做增强和划分。数据增强的目的是提升模型对不同环境的泛化能力,尤其针对超市场景里光照变化、摄像头抖动这类问题。我用Albumentations库做了几类增强:

  • 亮度对比度调整:模拟早晚不同光照条件下货架画面的差异
  • 随机水平翻转:扩大样本多样性
  • 随机裁剪后resize:模拟不同摄像头距离下的视角差异
  • HSV颜色扰动:不同色温的荧光灯下画面色调会有偏移
  • 模糊增强:模拟摄像头画面轻微失焦的状态

增强比例不用太猛,翻一倍到两倍就够。原来采集和标注了大约1800张图片,增强后得到4000多张,类别基本平衡。

数据划分用8:1:1的比例,即训练集、验证集、测试集。划分时注意按“货架场景组”分组,同一组场景的图片不要同时出现在训练集和测试集里。不然模型的泛化性测试就失真了,现场部署时换个角度就翻车。

3. 模型训练与调参实战

3.1 训练环境与依赖准备

训练环境我用的GPU方案,一张12GB显存的显卡就能跑YOLOv10的s和m模型,显存不是瓶颈,关键是CUDA环境别搞乱。

基础环境版本如下(实测兼容性稳定):

组件版本说明
操作系统Ubuntu 22.04Windows也能跑,但路径处理麻烦些
Python3.10太老或太新的版本可能和框架有兼容性问题
CUDA11.8与PyTorch版本严格对应
PyTorch2.1.0必须>=2.0,否则YOLOv10部分算子加载不了
ultralytics8.2.xYOLOv10官方实现集成在ultralytics库中

安装命令很简单,但有一个坑值得提醒:pip install ultralytics会附带安装它依赖的PyTorch CPU版本,如果你机器上有GPU而默认装成CPU版,训练速度会非常慢。我的建议是先装CUDA版PyTorch,再装ultralytics,并且用--no-deps参数避免依赖覆盖。

3.2 关键训练参数的选择逻辑

YOLOv10的训练参数,表面上看是一堆可以随便填的数字,但实际上每个参数的设置都和你的数据规模、硬件条件、任务目标直接挂钩。说一下我实际用的参数配置:

# yolo10_supermarket.yaml task: detect mode: train model: yolov10s.pt data: ./dataset/data.yaml epochs: 150 batch_size: 16 imgsz: 640 lr0: 0.01 lrf: 0.01 momentum: 0.937 weight_decay: 0.0005 warmup_epochs: 3.0 close_mosaic: 10

选这几个参数的理由,逐个解释:

  • imgsz设为640:这是速度和精度的默认平衡点。货架画面里目标尺寸偏小,如果显存够用,试试imgsz=960能提升小目标检测效果,但推理时间会变长。我用640配合多尺度训练效果已经够用
  • epochs设150:数据集4000多张、类别只有两类,150轮足够收敛。训练时观察验证集loss曲线,大概在110轮左右就平稳了。设太多反而可能过拟合
  • batch_size=16:显存12GB跑yolov10s刚好。batch调到32会提示显存不足,强行用梯度累积也会拖慢速度,没必要
  • lr0=0.01:这个值是训练启动的初始学习率,迁移训练用默认的0.01比较稳。如果是从零训练(不用预训练权重),建议降到0.005,否则前几轮loss会飞
  • close_mosaic=10:最后10轮关闭马赛克增强。马赛克增强能提升模型泛化,但在最后阶段会让模型在小物体上的定位细节变粗,关掉后精调一轮,精度会回升。这个是训练的一个重要细节

3.3 迁移学习用不用预训练权重

这个问题值得单独说。很多人觉得自己的数据集和目标场景特殊,就应该从零训练一个模型,这个想法是理解上存在误区。YOLOv10s自带的预训练权重是在大型目标检测数据集上学习过通用特征的模型,这些底层特征——边缘、纹理、形状——对货架场景同样有效。从预训练权重继续训练,收敛速度快得多,最终精度也更高,因为模型不用从零学“什么是物体边缘”。

实际操作中,我直接指定了预训练权重文件加载,在预训练模型基础上对货架数据做微调。训练了大概3个小时,mAP50就到了0.89左右。如果从零训练,同样的数据和轮数,mAP50可能只到0.7,差距非常明显。

有个细节要注意:迁移学习放学习率不能太高,0.01就是上限。我有一次lr0设成0.02,结果训练前20轮损失函数剧烈震荡,模型预训练特征被冲掉不少,最后效果反而不如从零训练。发现不对马上停掉重来,浪费了一个多小时,但教训算记住了。

3.4 训练过程监控与效果评估

训练过程中我主要盯四个指标,不只是看最后的mAP:

  • 训练损失和验证损失:两者差距过大说明过拟合,验证损失先降后升说明训练过度
  • mAP50:IoU阈值为0.5时的平均精度均值,货架检测这种场景看这个指标为主
  • mAP50-95:更严格的综合指标,用于评估检测框定位的精细程度
  • Precision和Recall:超市场景我更看重Recall,宁肯误报一两次,也好过漏掉一个空货位

训练完成后在测试集上跑了一轮评估,最终结果:mAP50=0.94,mAP50-95=0.78,Precision=0.93,Recall=0.90。这个水准应用到实际场景已经完全够用。

打印出混淆矩阵后发现了有意思的地方:错分样本主要集中在“接近售罄”的货位被模型判为非空,而“完全空置”的判错很少。这说明模型对极端状态学得很清楚,对中间状态偶尔拿不准,正好印证了前面说的——中间状态的数据要多采集、多标注。

4. UI界面设计与业务集成

4.1 界面框架选型对比

一个检测系统如果没有界面,对业务人员来说基本等于没用。空货架检测的产出是“提醒”和“报表”,不是一堆框和数字,得让店长和理货员能看得懂、用得上。

界面框架我对比了两种主流方案:

  • PyQt5桌面应用:启动快、运行稳定,适合单店部署在本地电脑上,可绑定摄像头录流。缺点是界面样式比较古朴,做现代感强的面板要花不少功夫
  • Flask + Web前端:浏览器访问、界面现代化程度高,可以集中管理多个门店的摄像头。缺点是实时视频流处理链路长一些,需要写前后端接口

最后我选了PyQt5。原因很直接:单店部署场景,桌面应用打开就能用,不需要维护服务器,也不占额外资源。架构上把界面逻辑和检测逻辑分层,后续要改成Web版,核心推理代码不用动,只换展示层就行。

4.2 功能模块规划与主界面实现

UI的整体布局按功能分三块:

  • 左侧画面区:实时展示视频流画面,检测结果以带置信度的框叠加在画面上
  • 右上数据面板:显示当前画面空货架数量、总货位数量、空置率,以及今日累计补货提醒次数
  • 下方历史记录区:表格列出最近检测到的空货位记录,包含时间、货位坐标、截图缩略图和状态标签

界面技术要点,讲两个容易忽略的地方:

  • 视频流播放用OpenCV读取每一帧,检测推理在子线程中执行,结果通过信号量机制传回主线程更新画面。PyQt的UI更新必须在主线程,直接在推理线程里调用控件更新方法会导致界面卡死。这个是从PyQt开发里容易踩的经典坑,一定要用信号与槽机制
  • 画面上的检测框不要每帧都重绘整个控件,用update()局部刷新叠加层,否则在高分辨率画面下界面会掉帧

4.3 业务联动与数据记录

做界面不只是为了看得见检测结果,更重要的是把检测结果变成可执行的业务信息。我在系统里加了三个业务层的功能:

  • 连续帧判定机制:单帧检测到空货架不立即触发提醒,连续3帧以上都检到同一个货位空置才计入记录。这样能过滤掉顾客正在从货架取货、身体遮挡货位的瞬时误报
  • 空置时长统计:从第一次确认空置开始计时,到货位被补满并重新检测到非空状态为止,计算空置持续时间。这个数据对分析补货效率非常有用
  • 补货工单导出:一键导出当前所有空货位列表,按货架编号排序,理货员直接拿着单子去仓库拿货补货

这三个功能实现起来不复杂,但让系统的价值提升了一个档次——从“机器能看到”变成了“机器能辅助决策”。哪怕只是一个几千块摄像头加一台旧电脑的部署方案,对门店运营效率的提升也很明显。

5. 推理部署与性能优化实践

5.1 模型导出与推理加速

训练完成的模型文件是PyTorch格式,部署时为了提高推理速度和兼容性,我做了模型导出的处理。YOLOv10原生支持导出为多种格式,实测下来:

  • 追求CPU推理速度优先用ONNX Runtime,通过加载导出的onnx模型跑推理,比PyTorch原生推理快30%到50%
  • 追求更低延迟可以用TensorRT(NVIDIA显卡),但YOLOv10的端到端设计在TensorRT上优化效果很好,推理时间可以压到个位数毫秒级
  • 纯CPU环境如果连ONNX Runtime都嫌慢,可以用OpenVINO导出,在新款CPU上有不错的加速效果

对超市场景来说,店面办公室一般没有好显卡,我最终方案选定ONNX Runtime CPU推理。1080p画面一张图推理时间约60毫秒,货架摄像头通常不会一直连续检测,设定每10秒抽一帧检测,CPU占用率不到15%,完全不影响办公电脑的其他使用。

5.2 摄像头集成与画面质量处理

接入摄像头时遇到一个典型问题:门店的监控摄像头接入系统后,画面流畅度虽然正常,但检测效果比在实验图片上差不少。排查后定位到两个原因:

  • 画面过曝:很多门店监控为了看清全店,摄像头自动曝光参数偏高,货架区域白花花一片,商品纹理丢失严重,模型判断失常
  • 隔行扫描畸变:部分老摄像头输出隔行扫描格式,快速转动时画面有横向锯齿,货架层板边缘出现重影,影响检测框定位

解决办法如下:

  • 在摄像头接入层增加了画面预处理管道,先做自动亮度校正,再适度提升对比度,让货架区域纹理更清晰
  • 尽量引导门店把摄像头设置为固定角度、固定焦距,避免自动变焦导致画面反复拉近拉远
  • 如果视频流帧率过高,检测模块做抽帧处理,控制频率在每秒一帧以内就足够

5.3 常见问题排查速查表

部署运行阶段的问题零零碎碎,整理一张常用排查表,照着查能省很多时间:

现象排查方向解决方法
模型推理结果为空输入图像尺寸是否被resize异常检查推理前预处理,确保图像按模型要求的640x640尺寸输入,并保持通道顺序BGR/RGB正确
收到视频流但界面不显示画面OpenCV VideoCapture的RTSP握手失败用VLC单独测试该视频流地址是否可播放,排查摄像头并发连接数限制
检测框位置偏移摄像头画面被裁剪过记录检测框在原图上的坐标,比对输入预处理时的缩放与填充量是否正确还原
空货架误报频繁数据中缺少“顾客遮挡”负样本采集一些顾客正在取货的画面标为负样本,或者在业务层加连续帧确认机制
晚上灯光变暗后检测精度下降训练数据缺少夜间场景采集夜间画面加入训练集,或增加暗光增强效果与gamma调整
界面卡顿明显推理阻塞了UI线程把推理放进独立线程,通过信号与槽机制完成跨线程界面更新

5.4 场景扩展方向

这套系统跑通之后,其实可以横向复制到很多相关场景,不只是超市空货架这一件事。简单列几个方向,给做完项目之后想继续扩展的朋友一点参考:

  • 货架商品热度分析:把检测结果按时段聚合,哪个货位频繁出现空置,说明对应商品销售快,这本身就是商品热度的信号。再叠加销售数据,可以做更智能的补货预测
  • 陈列规范检查:不只是“空不空”,还可以检测商品有没有倒放、乱放、跨货位摆放等陈列异常,本质上就是目标检测的类别再细分一层
  • 冷链设备状态监测:如果摄像头能拍到冷柜内部,空置检测的逻辑同样适用,还能结合温度传感器做联动,判断是补货问题还是设备问题
  • 连锁门店统一管理:单店系统升级为平台化部署,总部实时看到所有门店的空置率排行、补货响应速度对比,运营管理从“巡店”变成“看数”

每个方向都值得再投入一个完整项目周期来做。不过不管怎么扩展,底层那套“采集—标注—训练—部署—反馈迭代”的闭环逻辑是通用的,这次跑通的流程,后面做其他零售视觉场景时还能继续复用。

最后再分享一个实操中的小经验:如果你准备部署这套系统,先别急着接入全部摄像头,找一个货架品类丰富、客流适中的区域先跑一周,把误报数据收集起来。我最初就是跳过这个验证环节直接全店部署,结果冷柜区灯管反光导致大量误报,处理反馈花了一天半。先试点、再铺开,一套流程下来省心得多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询