简介:本资源是一套基于YOLOv8的商场货架商品陈列识别系统完整实现,面向计算机、人工智能、自动化等专业的本科生及初学者,解决零售场景中商品类别识别、陈列合规性检测等典型计算机视觉应用问题,特别适合作为毕业设计、课程设计或项目立项演示方案。压缩包共8个文件(3个Python主程序含可视化界面与推理脚本、3个PyTorch模型文件含预训练与最优权重、2个说明文档),总大小15.91MB,结构精炼、模块职责清晰,开箱即用。已有48人下载学习,资源经作者毕设实测验证,运行稳定,可一键生成精确率-召回率曲线、混淆矩阵、F1分数趋势图、验证集预测结果热力图及标签分布统计等核心评估图表,配套详细部署教程与README指引,兼顾教学性与工程落地性,小白可直接运行,进阶者亦便于二次开发与功能拓展。
1. 项目概述与核心价值
最近在整理过往项目时,翻出了一个挺有意思的“存货”——一套基于YOLOv8的商场货架商品陈列识别系统。这项目最初是给一个零售科技公司的POC(概念验证)做的,后来经过几轮迭代,功能已经相当完善了。它包含了从模型训练、可视化界面到一键部署的全套材料,我把它整理成了一个开箱即用的资源包。无论是计算机视觉的初学者想找个有深度的练手项目,还是临近毕业的同学在发愁毕设或课程设计,这套系统都能提供一个非常扎实的起点。你不需要从零开始爬数据、标注、调参,我已经把坑都踩得差不多了,源码、界面、数据集、部署教程一应俱全,目标就是让你能快速跑起来,看到效果,然后再根据自己的想法去修改和深化。
这个系统的核心,是解决零售场景下一个非常实际的问题:如何自动化、高效率地监控货架上的商品陈列情况。传统的人工巡检耗时耗力,还容易出错。通过摄像头拍摄货架图像,用YOLOv8模型自动识别出图像中的各个商品,并统计其数量、位置,系统就能判断出是否缺货、陈列是否合规(比如某品牌商品是否摆在了规定的黄金位置)、价格标签是否对应等。这对于门店运营、供应链补货决策都有直接的价值。我提供的这个版本,已经内置了一个针对常见快消品(如饮料、零食、日化用品)构建的数据集,模型也经过了充分的训练和优化,识别准确率在测试集上能达到不错的水平。更重要的是,我配套了一个用PyQt5开发的可视化桌面界面,你不需要懂任何Web前端,就能通过点选按钮完成图片检测、视频流分析、结果导出等所有操作,极大降低了使用门槛。
2. 系统整体架构与技术选型解析
2.1 为什么选择YOLOv8作为核心检测模型
在目标检测领域,框架选择很多,从老牌的Faster R-CNN、SSD到YOLO系列。我最终锁定YOLOv8,是经过一番权衡的。对于货架商品识别这个场景,我们需要在精度和速度之间找到一个最佳平衡点。货架图像背景相对固定,但商品种类多、尺寸差异大(从一大瓶可乐到一小包口香糖),且可能存在遮挡和密集摆放的情况。
YOLOv8在YOLOv5的基础上做了大量改进,其Anchor-Free的设计(使用了TaskAlignedAssigner正样本分配策略)让它在处理尺寸变化大的目标时表现更稳定,这对于大小不一的商品盒非常友好。其次,它提供的模型尺寸从nano到x-large一应俱全。在项目初期,我对比了YOLOv8s和YOLOv8m两个模型,在自建数据集上,m模型比s模型mAP@0.5提升了约3%,但推理速度(在GTX 1660 Ti上)从每秒120帧降到了85帧。考虑到实际部署可能是在性能普通的工控机或边缘设备上,最终我选择了YOLOv8s作为默认模型,它在保证足够识别精度的前提下,提供了优异的实时性能。如果你手头有更强的GPU(如RTX 3060以上),完全可以选择YOLOv8m甚至l模型来换取更高的精度。
另一个关键点是生态和易用性。Ultralytics官方维护的YOLOv8库,其API设计非常清晰,训练、验证、预测、导出模型到各种格式(如ONNX、TensorRT)的流程高度标准化,文档也齐全。这大大减少了工程上的不确定性,让我们能把精力更多集中在业务逻辑和数据本身。
2.2 系统模块化设计思路
为了让项目结构清晰、易于理解和二次开发,我将整个系统进行了模块化拆分,核心分为四大模块:
- 模型训练与验证模块:基于YOLOv8框架,包含数据准备(数据集格式转换、划分)、模型训练脚本、超参数配置文件、以及训练过程监控(损失曲线、精度指标可视化)。我提供了完整的训练代码和注释,你可以用自己的数据重新训练或微调模型。
- 核心推理引擎模块:这是一个独立的Python类,封装了YOLOv8模型的加载、图像预处理、推理和后处理(非极大值抑制NMS、结果解析)过程。所有与模型直接交互的逻辑都集中在这里,界面层和其他业务模块通过调用这个引擎来获得检测结果。
- 可视化交互界面模块:采用PyQt5开发。之所以选PyQt5而非Web框架(如Flask + HTML),主要是为了部署的简便性。一个可执行文件或脚本就能在所有主流桌面系统运行,无需配置服务器环境。界面包含了文件选择、实时摄像头拉流、检测结果展示(带类别标签和置信度的检测框)、统计信息面板(如各类商品数量)和结果导出(JSON/Excel)功能。
- 实用工具与部署模块:包含环境配置脚本(一键安装依赖)、数据集说明文档、以及详细的部署教程。特别是针对常见问题,如“GTX 1660 Ti跑YOLOv8”的CUDA/cuDNN配置,提供了步骤截图和问题排查指南。
这种设计使得数据流非常清晰:界面捕获输入(图片/视频) -> 调用推理引擎 -> 引擎返回结构化结果 -> 界面渲染结果并生成报告。你可以轻松地替换其中任何一个模块,比如把PyQt5界面换成Flask Web服务,或者把YOLOv8引擎换成其他检测模型。
3. 数据集构建与模型训练实战
3.1 数据集的准备与处理技巧
任何AI项目,数据都是基石。我提供的完整数据集中包含了约5000张标注好的货架图片,涵盖了超市中常见的6个大类、超过50种具体商品。数据采集自多个真实超市货架,考虑了不同的光照条件(日光灯、暖光灯)、拍摄角度(平视、俯视)和遮挡情况,以确保模型的泛化能力。
数据集采用YOLO格式,每张图片对应一个.txt标注文件,内容为<class_id> <x_center> <y_center> <width> <height>,坐标进行了归一化。在准备你自己的数据时,有几点心得:
- 标注质量是关键:对于边界框,务必紧贴商品边缘,尤其是对于长方体盒子,避免包含太多背景。对于“连包销售”(如六连包酸奶)的商品,是标成一个整体还是每个单独标,需要根据业务定义统一。本项目是按最小销售单元(即单个商品)进行标注的。
- 类别平衡:检查数据集中各类别的图片数量。如果“可口可乐”有1000张,而“某小众果汁”只有50张,模型肯定会偏向于前者。可以通过过采样少数类别图片,或在数据增强中针对性增强这些类别来缓解。
- 数据增强策略:在
data.yaml配置文件中,我启用了Mosaic、MixUp、随机旋转、亮度对比度调整等增强方式。这对于增加数据多样性、防止过拟合非常有效。但要注意,对于货架场景,水平翻转是安全的,但垂直翻转可能不合逻辑(商品不会倒置摆放),需谨慎使用。
注意:如果你拿到的是类似“CCPD”车牌数据集或“DOTA”遥感数据集等其他格式,需要先进行格式转换。网上有大量转换脚本(如
labelme2yolo、voc2yolo),务必检查转换后的标注框是否准确。
3.2 模型训练的超参数调优与监控
训练不是在命令行里敲一句yolo train就完事了,超参数的设置直接影响最终模型性能。我在项目中提供了一个精心调整过的hyp.yaml(超参数配置文件)和args.yaml(训练参数配置文件)。
- 学习率(lr0):这是最重要的参数之一。我初始设置为0.01,并使用了余弦退火调度器(cosine scheduler),让学习率随着训练周期从初始值平滑下降,有助于模型在后期更精细地收敛。如果你发现训练早期损失值剧烈震荡,可以尝试调低到0.001或0.005。
- 优化器选择:YOLOv8默认使用SGD。但我发现在商品检测任务上,使用AdamW优化器(设置
optimizer=AdamW)有时能获得更快的初始收敛速度。你可以在配置文件中尝试切换并对比效果。 - 损失函数权重:YOLOv8的损失由分类损失(cls_loss)、边界框损失(box_loss)和分布焦点损失(dfl_loss)组成。一般不需要改动,但如果你发现模型定位不准(框不准)但分类很准,可以适当提高
box_loss的权重。 - 训练监控:一定要利用好TensorBoard或Ultralytics自带的训练日志。重点关注
train/box_loss和val/box_loss的曲线。理想情况是两者同步平稳下降,且验证损失在训练后期没有明显上升(否则可能是过拟合)。metrics/mAP@0.5则是衡量精度最直观的指标。
训练命令示例:
yolo task=detect mode=train model=yolov8s.pt data=./data/shelf.yaml epochs=100 imgsz=640 batch=16 workers=4这里workers是数据加载的进程数,根据你的CPU核心数设置,可以加快数据读取速度。如果训练时出现内存不足,首先尝试减小batch大小。
4. 可视化界面的设计与功能实现
4.1 PyQt5界面布局与交互逻辑
为了让系统好用,我花了不少心思在界面上。主窗口采用经典的左右布局:左侧是控制面板和图像显示区,右侧是检测结果列表和统计信息。
- 控制面板:包含了“打开图片”、“打开摄像头”、“打开视频”、“停止”、“导出结果”等按钮。其中“打开摄像头”的下拉框会自动枚举系统可用的摄像头设备(通过
cv2.VideoCapture的索引遍历),方便切换。 - 图像显示区:使用
QLabel组件来显示图片。这里有个关键点:原始图片和带检测框的图片尺寸可能很大,需要将其缩放至适合QLabel显示的大小,同时又要保存原始坐标用于后续分析。我的做法是,在QLabel中显示缩放后的图片,但所有检测框的坐标计算都在原始图片尺寸上进行,确保精度。 - 结果列表:使用
QTableWidget组件,实时显示当前画面中检测到的所有商品信息,包括类别名称、置信度、边界框坐标。点击列表中的某一行,可以在图像上高亮对应的检测框,方便核对。 - 统计面板:使用
QChart或简单的QLabel来展示各类商品的数量柱状图或饼图,让陈列情况一目了然。
所有耗时的操作,如图片推理、视频流处理,都放在独立的线程(QThread)中完成,避免阻塞主界面导致“未响应”。这是PyQt5开发桌面应用必须掌握的一点。
4.2 核心功能点的代码级剖析
以“打开图片并检测”这个核心流程为例,看看代码是如何串联起来的:
- 信号与槽连接:在界面初始化时,将“打开图片”按钮的
clicked信号连接到一个自定义的槽函数on_open_image_clicked()。 - 文件选择与加载:在槽函数中,使用
QFileDialog弹出对话框让用户选择图片文件。然后用OpenCV的cv2.imread读取图片,并转换为RGB格式(因为YOLOv8和PyQt5都使用RGB)。 - 调用推理引擎:将读取的图片数组传递给之前封装好的
YOLOv8InferenceEngine类的detect方法。在这个方法内部,会进行预处理(缩放、归一化)、模型推理、NMS后处理,最终返回一个包含所有检测框信息的列表。 - 结果可视化与展示:收到检测结果列表后,界面线程遍历这个列表,使用
cv2.rectangle和cv2.putText在原图上画出边界框和标签。然后将绘制好的图片(依然是NumPy数组)转换为Qt能显示的QImage,再设置为QLabel的像素图。同时,将结果列表的数据填充到右侧的QTableWidget中,并更新统计面板。
视频和摄像头流的处理逻辑类似,但是在一个循环中不断抓帧、检测、显示。关键在于控制好循环的频率,避免超过显示刷新率造成资源浪费,我通常使用一个定时器(QTimer)来控制处理频率。
5. 系统部署与运行指南
5.1 环境配置与依赖安装
为了让部署过程尽可能平滑,我提供了两种方式:
- 方式一(推荐):使用Conda环境。项目根目录下有一个
environment.yaml文件。你只需要安装好Miniconda或Anaconda,然后在终端中切换到项目目录,执行conda env create -f environment.yaml,就能自动创建一个包含所有正确版本依赖的独立Python环境。这能完美解决不同项目间包版本冲突的问题。 - 方式二:使用pip。我也提供了一个
requirements.txt文件。你可以通过pip install -r requirements.txt来安装。但请注意,这种方式需要你自行管理Python版本和系统级依赖(如OpenCV可能需要系统库)。对于新手,更推荐第一种方式。
核心依赖包括:torch(PyTorch深度学习框架,需根据你的CUDA版本选择安装命令)、ultralytics(YOLOv8官方库)、opencv-python(图像处理)、pyqt5(界面)、pandas(数据导出)、numpy等。在environment.yaml中,我已经锁定了经过测试的稳定版本号。
5.2 一键运行与常见问题排查
环境配置好后,运行系统非常简单。激活Conda环境(conda activate shelf_detect),然后运行主程序脚本即可:python main.py。
在部署过程中,以下几个问题是高频出现的,我整理了排查思路:
问题:导入PyTorch或Ultralytics时报错,提示CUDA不可用。
- 排查:首先在Python中运行
import torch; print(torch.cuda.is_available()),如果返回False,说明PyTorch没有安装GPU版本,或者CUDA驱动、CUDA Toolkit版本不匹配。 - 解决:确认你的显卡是NVIDIA显卡且支持CUDA。去NVIDIA控制面板查看驱动版本,然后去 PyTorch官网 使用对应的命令重新安装。例如,对于CUDA 11.8,命令是
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118。
- 排查:首先在Python中运行
问题:运行后界面打开,但点击“打开摄像头”黑屏或报错。
- 排查:这通常是摄像头索引错误或摄像头被其他程序占用。我的代码中默认索引是0,但有些电脑上内置摄像头可能是0,外接USB摄像头可能是1。
- 解决:尝试在界面的摄像头下拉框中选择不同的索引号。如果还不行,可以先用系统自带的相机应用测试摄像头是否正常工作。
问题:检测速度很慢,达不到实时。
- 排查:首先确认任务管理器中的GPU是否被调用(NVIDIA GPU使用率是否上升)。如果GPU使用率很低,可能还是在用CPU推理。
- 解决:确保PyTorch是GPU版本且CUDA可用。其次,可以尝试在推理时设置
half=True使用半精度(FP16)推理,这能显著提升速度且精度损失很小。在代码中,可以在加载模型时设置model = YOLO(‘best.pt’).to(‘cuda’).half()。
问题:检测结果不准,很多商品检不出或误检。
- 排查:这通常是模型在新场景下泛化能力不足。首先用项目自带的测试图片看看效果,如果自带图片效果好而你的图片效果差,说明数据分布不一致。
- 解决:最好的办法是用你的场景数据对模型进行微调(fine-tuning)。收集几十张到几百张新场景的图片,用LabelImg等工具标注,然后以预训练模型(
yolov8s.pt或项目提供的best.pt)为起点,用较小的学习率(如0.0001)训练少量epoch(如20-50轮)。
为了方便大家,我把这些常见问题和解决方案做成了一个速查表:
| 问题现象 | 可能原因 | 排查步骤与解决方案 |
|---|---|---|
| 程序无法启动,提示缺少模块 | Python依赖未正确安装 | 1. 确认已激活正确的Conda环境。 2. 执行 pip list检查ultralytics,pyqt5等核心包是否存在。3. 重新运行 pip install -r requirements.txt。 |
| 模型加载失败或推理报错 | 模型文件损坏或路径错误 | 1. 检查best.pt模型文件是否在指定路径,文件大小是否正常。2. 尝试用绝对路径加载模型。 |
| 检测框全部为0或结果异常 | 图片预处理/后处理逻辑错误 | 1. 检查输入图片的通道顺序是否为RGB。 2. 检查推理引擎返回的坐标格式(归一化/像素值)与绘图代码是否匹配。 3. 在关键步骤打印中间结果进行调试。 |
| 内存占用持续增长(内存泄漏) | 线程或资源未正确释放 | 1. 检查视频/摄像头循环中,每一帧处理后是否及时释放cv2.VideoCapture对象或清空不必要的变量。2. 确保子线程在界面关闭时被正确终止。 |
6. 项目扩展方向与高级应用
这个基础系统完全可以作为一个平台,进行多方向的深化和扩展,以满足更复杂的商业需求。
方向一:增加细粒度识别与属性分析目前的模型只识别到商品大类(如“可乐”)。你可以进一步收集数据,训练模型识别具体的品牌、口味和规格(如“330ml罐装可口可乐无糖”)。更进一步,可以结合OCR技术,从检测框截图中识别出价格标签上的数字,实现价格巡检自动化。
方向二:实现多摄像头管理与云端部署将单机桌面应用升级为C/S(客户端/服务器)或B/S(浏览器/服务器)架构。例如,使用Flask或FastAPI将模型封装成RESTful API服务,部署在门店的本地服务器或云端。桌面端或移动端App通过调用API来获取识别结果。这样可以集中管理多个摄像头的视频流,并进行统一的数据分析和报表生成。
方向三:与业务系统集成,形成闭环识别出的缺货、陈列错误等结果,不能仅仅停留在显示层面。可以通过系统提供的导出功能(如生成Excel报表),或直接编写接口,将结构化数据推送至门店的库存管理系统(IMS)或任务调度系统,自动生成补货单或店员巡检任务,真正实现从“看到问题”到“解决问题”的闭环。
方向四:模型轻量化与边缘部署如果需要在算力有限的设备(如嵌入式AI相机、移动设备)上运行,可以考虑模型轻量化。YOLOv8官方支持导出为ONNX格式,然后可以使用ONNX Runtime进行高效推理,或者进一步使用TensorRT、OpenVINO等工具进行优化加速,在Jetson Nano等边缘设备上实现实时识别。
在我实际交付给客户的项目中,正是沿着“单点验证 -> 多店试点 -> 系统集成”的路径推进的。最初就是这个桌面版原型说服了客户,后续才逐步发展成覆盖数百个摄像头的云端分析系统。所以,别小看这个“毕业设计级别”的项目,它的内核包含了解决一个真实商业问题的完整技术链条。希望这份详细的拆解和配套的资源,能帮你少走弯路,快速搭建起属于自己的视觉应用。
本文还有配套的精品资源,点击获取