十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

基于YOLOv8的商场货架商品识别系统:从模型训练到Web部署全流程

基于YOLOv8的商场货架商品识别系统:从模型训练到Web部署全流程 简介本资源是一套面向计算机、人工智能及相关专业在校学生与初学者的实战型毕业设计项目聚焦商场货架商品陈列识别这一典型计算机视觉应用场景基于YOLOv8目标检测框架构建端到端解决方案。资源共8个文件包含3个核心Python脚本训练、推理与可视化界面、3个模型权重文件含预训练与最佳训练结果、2个说明文档README与系统说明总大小15.91MB结构精炼、模块职责明确开箱即用。已有48人下载学习适用于课程设计、大作业、毕设立项及AI入门实践。用户可直接运行获得完整评估体系输出包括验证集预测结果、标签分布统计、混淆矩阵、F1分数与PR曲线等关键指标可视化图表并配套详细部署教程与测试验证说明确保从环境配置到结果呈现全流程可复现。1. 项目概述与核心价值最近在整理过往项目时翻出了一个挺有意思的“存货”——一个基于YOLOv8的商场货架商品陈列识别系统。这玩意儿当初是为了解决一个很实际的痛点大型商超或连锁便利店如何高效、自动化地巡检成千上万个货架检查商品是否缺货、陈列是否符合标准、价格标签是否正确。传统靠人工拿着表格去一个个对效率低不说还容易出错。这个项目就是把计算机视觉里的目标检测技术打包成一个从数据到部署的完整解决方案。简单来说它就是一个“智能货架巡检员”。你给它一张货架的照片或者一段实时视频流它就能自动框出照片里所有的商品并告诉你每个框里是什么东西比如“可口可乐330ml罐装”、“奥利奥原味夹心饼干”。更进一步结合一些业务逻辑就能判断“这个货位是不是空了”、“这个品牌的商品是不是摆在了竞品的旁边”等等。对于计算机视觉的初学者、需要做毕设或课程设计的同学以及想快速验证某个零售场景AI应用的小团队这个项目提供了一个非常不错的起点。它把模型训练、界面开发、数据集处理、部署上线这些环节都串了起来形成了一个闭环你拿到手简单配置一下环境就能跑起来看到效果然后再根据自己的需求去修改和深化。2. 系统整体设计与技术选型考量2.1 为什么选择YOLOv8作为核心检测模型在目标检测领域框架选择很多从老牌的Faster R-CNN、SSD到YOLO系列的各代版本。最终选定YOLOv8是经过多方面权衡的。首先速度与精度的平衡是零售场景的核心诉求。货架识别往往需要在边缘设备如巡检机器人、店内工控机甚至移动端上运行对实时性要求高。YOLOv8在保持YOLO系列一贯高速推理优势的同时通过新的骨干网络和检测头设计进一步提升了精度。对于商品检测这种目标尺寸相对固定瓶装、盒装、但类别可能非常多的任务YOLOv8的精度完全够用同时能保证流畅的视频流处理。其次易用性和生态成熟度是关键。YOLOv8由Ultralytics公司维护提供了极其友好的Python API和命令行工具。从安装、数据准备、模型训练到模型导出支持ONNX、TensorRT等格式都有清晰的文档和示例。这对于课程设计或毕设项目来说大大降低了入门门槛学生可以把更多精力放在业务逻辑和系统集成上而不是在模型调试上耗费大量时间。再者社区支持与预训练模型。YOLOv8有在COCO等大型通用数据集上预训练的模型权重我们可以直接拿来在自己的商品数据集上进行微调Fine-tuning这比从头训练要快得多效果也更有保障。项目里提供的完整数据集正是为了这个微调步骤准备的。2.2 系统架构与模块拆解整个系统不是只有一个模型文件而是一个包含前后端的完整应用。其核心架构可以划分为四个层次数据层这是系统的基石。包含了项目提供的“完整数据集”。这个数据集通常已经做好了标注格式是YOLO格式每个图片对应一个.txt文件里面是归一化的目标框和类别ID。数据集的质量图片清晰度、标注准确性、类别覆盖度直接决定了最终模型的上限。模型层这是系统的“大脑”。基于YOLOv8框架使用提供的数据集进行训练得到一个能够识别特定商品集合的.pt模型文件。训练过程需要在有GPU的机器上进行但训练好的模型可以在CPU或GPU上推理。服务层这是系统的“躯干”。通常是一个用Python例如Flask或FastAPI框架搭建的后端服务。它负责加载训练好的YOLOv8模型接收前端传来的图片调用模型进行推理并将检测结果包括边界框坐标、类别名称、置信度以结构化的数据如JSON返回给前端。这一步是连接模型和界面的桥梁。应用层这是系统的“脸面”。即“可视化界面”。通常是一个Web页面用HTML/CSS/JavaScript开发可能基于Streamlit、Gradio等快速开发工具也可能是一个独立的桌面应用如PyQt。用户通过这个界面上传图片或开启摄像头界面将图片发送给后端服务并接收返回的检测结果最后将带有检测框和标签的图片渲染展示给用户。此外部署教程会详细指导如何将这套系统从开发环境搬到真正的运行环境可能包括Python环境依赖打包、服务进程管理用systemd或Supervisor、以及如何配置Web服务器如Nginx进行反向代理等。注意一个常见的误区是认为有了模型就万事大吉。实际上数据准备、服务封装和界面交互的工程量往往不亚于甚至超过模型训练本身。这个项目的价值就在于它提供了一个全栈的范例。3. 核心细节解析与实操要点3.1 数据集的理解与预处理项目附带的“完整数据集”是宝藏也是第一个需要仔细检查的环节。一个标准的YOLO格式数据集目录结构通常如下dataset/ ├── images/ │ ├── train/ # 训练集图片 │ └── val/ # 验证集图片 └── labels/ ├── train/ # 训练集标签与images/train一一对应 └── val/ # 验证集标签与images/val一一对应每个标签文件如00010752.txt内容示例0 0.5 0.5 0.2 0.3 1 0.7 0.3 0.15 0.25每一行代表一个检测目标格式为class_id center_x center_y width height。所有坐标都是相对于图片宽度和高度的归一化值0-1之间。实操要点与常见坑点数据均衡检查打开dataset.yaml配置文件通常项目会提供查看每个类别的图片数量和实例数量。如果某个类别比如“小众进口饮料”的样本只有几十个而“矿泉水”有几千个模型就会严重偏向于多数类。你需要通过数据增强如旋转、裁剪、色彩抖动来人工增加少数类样本的“多样性”或者在损失函数中引入类别权重。标注质量抽查随机打开一些图片和对应的标签文件用可视化脚本YOLOv8自带yolo val命令可以生成预测图检查标注框是否准确、完整。常见问题包括框太大包含背景、框太小没包住整个商品、重叠商品标成了一个框、相似商品标错了类别如“无糖可乐”标成了“经典可乐”。图片格式与损坏处理就像热词里提到的E:\yolov8\images\val\00010752.png: ignoring corrupt image/label这种错误在开始训练前一定要用脚本批量检查图片是否能正常打开。可以用Python的PIL或OpenCV库遍历所有图片进行读取测试将损坏的图片和对应的标签文件移出数据集。3.2 YOLOv8模型训练的关键参数调优拿到干净的数据集后就可以开始训练了。YOLOv8的训练命令很简单但里面的参数决定了模型的性能。一个基础的训练命令如下yolo taskdetect modetrain modelyolov8n.pt datadataset.yaml epochs100 imgsz640 batch16这里有几个关键参数需要理解modelyolov8n.pt这里指定了模型尺度。yolov8n是“nano”版最小最快精度也最低还有s(small),m(medium),l(large),x(extra large)版本。对于商品检测如果类别不多50yolov8s通常是个不错的起点平衡了速度和精度。如果你的商品非常细小密集或者类别上百可能需要考虑l或x版但也要考虑部署设备的算力。epochs100训练轮数。不是越大越好要观察验证集损失val/loss和指标mAP50-95的变化。通常当这些指标在连续10-20个epoch内不再显著提升时就可以提前停止训练防止过拟合。YOLOv8支持patience参数来实现早停。imgsz640输入图片的尺寸。YOLOv8会将所有图片缩放到这个尺寸进行训练。更大的尺寸如1280能保留更多细节可能提升对小目标的检测能力但会显著增加显存消耗和训练时间。对于货架商品640或768通常足够。batch16批大小。这个值受你的GPU显存限制。在显存允许的情况下较大的batch size能使训练更稳定。如果出现CUDA out of memory错误就需要减小batch或imgsz。训练过程监控训练开始后YOLOv8会在终端输出日志并在runs/detect/train目录下生成一系列可视化结果包括损失曲线、精度曲线、混淆矩阵、验证集上的预测样例图。务必定期查看这些图它们是诊断模型问题的关键。例如如果训练损失持续下降但验证损失上升就是过拟合的典型信号需要增加数据增强强度或减少模型复杂度。3.3 可视化界面的实现方式选择“可视化界面”是这个项目用户体验的关键。根据技术栈和需求主要有几种实现路径基于Web的轻量级界面推荐使用Gradio或Streamlit。这两个都是Python库可以用极少的代码构建交互式Web应用。例如用Gradio核心代码可能就十几行import gradio as gr from ultralytics import YOLO model YOLO(best.pt) def predict(image): results model(image) return results[0].plot() # 返回带标注框的图片 iface gr.Interface(fnpredict, inputsgr.Image(typepil), outputsimage) iface.launch()这种方式开发速度极快非常适合演示、原型验证和课程设计。缺点是定制化程度相对较低界面风格比较固定。自定义Web前端使用Flask/FastAPI后端 HTML/JS前端。这提供了最大的灵活性。后端用Flask提供图片上传和模型推理的API接口前端用JavaScript可以配合Vue/React框架构建美观的页面使用fetch或axios调用后端API并用canvas绘制检测结果。这种方式更贴近企业级应用但开发工作量较大。桌面图形界面使用PyQt5或Tkinter。适合需要离线、单机运行的场景。你可以拖拽控件设计窗口实现本地图片选择、摄像头调用、结果展示等功能。PyQt5功能强大但学习曲线稍陡Tkinter是Python标准库简单但界面比较老旧。选择建议对于毕设或快速验证强烈推荐Gradio。它几乎零前端基础要求能快速做出一个效果不错、可分享链接的演示系统把精力集中在模型和核心逻辑上。4. 从零开始的完整部署实操流程假设我们在一台全新的Ubuntu 20.04服务器或本地电脑上部署这个系统。这里我们选择“Flask后端 简单HTML前端”的方案因为它兼具灵活性和学习价值。4.1 环境准备与依赖安装首先确保系统有Python 3.8或以上版本。然后创建一个独立的虚拟环境避免包冲突。# 1. 更新系统包 sudo apt-get update # 2. 安装Python3和pip如果未安装 sudo apt-get install python3 python3-pip -y # 3. 安装虚拟环境工具 pip3 install virtualenv # 4. 创建项目目录并进入 mkdir shelf_detection cd shelf_detection # 5. 创建虚拟环境 virtualenv venv # 6. 激活虚拟环境 source venv/bin/activate接下来安装核心依赖。创建一个requirements.txt文件内容如下# 核心AI框架 torch1.7.0 # 根据CUDA版本选择CPU版用 torch torchvision torchaudio torchvision0.8.0 ultralytics8.0.0 # 这是YOLOv8官方库 # Web后端 Flask2.0.0 Flask-CORS # 处理跨域请求如果前后端分离需要 # 图像处理 opencv-python4.5.0 Pillow9.0.0 # 其他工具 numpy1.20.0然后安装pip install -r requirements.txt注意torch的安装需要特别注意。如果你的机器有NVIDIA GPU并已安装CUDA可以去 PyTorch官网 获取对应的安装命令如pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118。如果没有GPU就安装CPU版本。这将极大影响模型推理速度。4.2 后端服务Flask API开发在项目根目录创建app.py文件作为后端主程序。from flask import Flask, request, jsonify, send_from_directory from werkzeug.utils import secure_filename import os from ultralytics import YOLO import cv2 app Flask(__name__) app.config[UPLOAD_FOLDER] ./uploads app.config[RESULT_FOLDER] ./results os.makedirs(app.config[UPLOAD_FOLDER], exist_okTrue) os.makedirs(app.config[RESULT_FOLDER], exist_okTrue) # 加载训练好的模型确保 best.pt 模型文件在项目根目录或指定路径 model YOLO(./model/best.pt) app.route(/) def index(): # 返回前端页面 return send_from_directory(., index.html) app.route(/api/detect, methods[POST]) def detect(): if file not in request.files: return jsonify({error: No file part}), 400 file request.files[file] if file.filename : return jsonify({error: No selected file}), 400 # 保存上传的图片 filename secure_filename(file.filename) upload_path os.path.join(app.config[UPLOAD_FOLDER], filename) file.save(upload_path) # 使用YOLOv8进行推理 results model(upload_path) # 处理结果 detection_list [] for result in results: boxes result.boxes for box in boxes: # 获取坐标、置信度、类别ID x1, y1, x2, y2 box.xyxy[0].tolist() conf box.conf[0].item() cls_id int(box.cls[0].item()) cls_name result.names[cls_id] detection_list.append({ class: cls_name, confidence: round(conf, 3), bbox: [round(x1,1), round(y1,1), round(x2,1), round(y2,1)] }) # 保存带标注的结果图片可选 result_img_path os.path.join(app.config[RESULT_FOLDER], fresult_{filename}) annotated_img results[0].plot() # 获取带框的图片 cv2.imwrite(result_img_path, annotated_img) return jsonify({ filename: filename, detections: detection_list, result_image_url: f/results/result_{filename} }) app.route(/results/filename) def get_result_image(filename): return send_from_directory(app.config[RESULT_FOLDER], filename) if __name__ __main__: # debugTrue仅用于开发生产环境需关闭 app.run(host0.0.0.0, port5000, debugTrue)这个后端做了几件事1) 提供了一个简单的根路由返回前端页面2) 提供了一个/api/detect接口接收图片文件3) 调用加载好的YOLOv8模型进行预测4) 将检测结果类别、置信度、坐标以JSON格式返回并保存一张带标注框的结果图供前端显示。4.3 前端界面HTMLJavaScript开发在项目根目录创建index.html文件。!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title商场货架商品识别系统/title style body { font-family: sans-serif; max-width: 1200px; margin: 20px auto; padding: 20px; } .container { display: flex; gap: 30px; } .upload-area, .result-area { flex: 1; border: 2px dashed #ccc; padding: 20px; border-radius: 10px; min-height: 400px; } .upload-area { text-align: center; } #preview, #resultImg { max-width: 100%; max-height: 350px; display: block; margin: 10px auto; } table { width: 100%; border-collapse: collapse; margin-top: 15px; } th, td { border: 1px solid #ddd; padding: 8px; text-align: left; } th { background-color: #f2f2f2; } .btn { background-color: #4CAF50; color: white; padding: 10px 20px; border: none; border-radius: 5px; cursor: pointer; font-size: 16px; } .btn:hover { background-color: #45a049; } .btn:disabled { background-color: #cccccc; cursor: not-allowed; } /style /head body h1基于YOLOv8的商场货架商品识别系统/h1 p上传一张货架图片系统将自动识别其中的商品。/p div classcontainer div classupload-area h3上传图片/h3 input typefile idfileInput acceptimage/* brbr img idpreview src alt图片预览 br button classbtn onclickuploadImage() iddetectBtn开始检测/button p idstatus/p /div div classresult-area h3检测结果/h3 img idresultImg src alt检测结果 div iddetectionTable/div /div /div script const fileInput document.getElementById(fileInput); const preview document.getElementById(preview); const resultImg document.getElementById(resultImg); const detectBtn document.getElementById(detectBtn); const statusText document.getElementById(status); const detectionTable document.getElementById(detectionTable); // 图片预览 fileInput.addEventListener(change, function(e) { const file e.target.files[0]; if (file) { const reader new FileReader(); reader.onload function(e) { preview.src e.target.result; preview.style.display block; resultImg.src ; detectionTable.innerHTML ; } reader.readAsDataURL(file); } }); // 上传并检测 async function uploadImage() { const file fileInput.files[0]; if (!file) { alert(请先选择一张图片); return; } detectBtn.disabled true; statusText.textContent 检测中请稍候...; statusText.style.color blue; const formData new FormData(); formData.append(file, file); try { const response await fetch(/api/detect, { method: POST, body: formData }); if (!response.ok) { throw new Error(HTTP error! status: ${response.status}); } const data await response.json(); statusText.textContent 检测完成共发现 ${data.detections.length} 个商品。; statusText.style.color green; // 显示结果图片 resultImg.src data.result_image_url; resultImg.style.display block; // 生成结果表格 if (data.detections.length 0) { let tableHtml table trth序号/thth商品类别/thth置信度/thth边界框坐标/th/tr; data.detections.forEach((item, index) { tableHtml tr td${index 1}/td td${item.class}/td td${(item.confidence * 100).toFixed(1)}%/td td[${item.bbox.join(, )}]/td /tr; }); tableHtml /table; detectionTable.innerHTML tableHtml; } else { detectionTable.innerHTML p未检测到任何商品。/p; } } catch (error) { console.error(Error:, error); statusText.textContent 检测失败 error.message; statusText.style.color red; } finally { detectBtn.disabled false; } } /script /body /html这个前端页面提供了一个简洁的上传区域和结果展示区域。用户选择图片后可以预览点击按钮调用后端的API然后将返回的JSON数据解析用表格展示检测到的商品列表并显示带标注框的结果图片。4.4 生产环境部署与优化在开发环境python app.py运行没问题后我们需要考虑更稳定的生产环境部署。使用WSGI服务器Flask自带的开发服务器性能弱不稳定。我们使用Gunicorn一个Python WSGI HTTP服务器。pip install gunicorn # 在项目根目录启动指定4个工作进程 gunicorn -w 4 -b 0.0.0.0:5000 app:app使用Nginx作为反向代理Gunicorn擅长处理动态请求但不擅长处理静态文件如图片、CSS、JS。Nginx可以高效地处理静态文件并将动态请求转发给Gunicorn还能提供负载均衡、SSL加密等功能。 安装Nginx后配置一个站点文件如/etc/nginx/sites-available/shelf_detectionserver { listen 80; server_name your_domain_or_ip; # 你的域名或IP location / { proxy_pass http://127.0.0.1:5000; # 转发给Gunicorn proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } # 让Nginx直接处理静态文件减轻Flask负担 location /static { alias /path/to/your/shelf_detection/static; # 如果你的静态文件放在static文件夹 } location /uploads { alias /path/to/your/shelf_detection/uploads; } location /results { alias /path/to/your/shelf_detection/results; } }然后启用配置并重启Nginx。使用进程管理为了让Gunicorn在后台稳定运行并在崩溃后自动重启可以使用Supervisor。 创建一个Supervisor配置文件如/etc/supervisor/conf.d/shelf_detection.conf[program:shelf_detection] command/path/to/venv/bin/gunicorn -w 4 -b 127.0.0.1:5000 app:app directory/path/to/shelf_detection useryour_username autostarttrue autorestarttrue stderr_logfile/var/log/shelf_detection.err.log stdout_logfile/var/log/shelf_detection.out.log然后更新Supervisor并启动程序sudo supervisorctl reread sudo supervisorctl update sudo supervisorctl start shelf_detection至此一个相对完整的、可在生产环境运行的货架商品识别系统就部署完成了。用户可以通过服务器的IP地址或域名直接访问Web界面使用。5. 常见问题与排查技巧实录在实际部署和运行过程中你几乎一定会遇到下面这些问题。这里记录了我踩过的坑和解决方法。5.1 模型推理相关的问题问题1CUDA out of memory (GPU显存不足)现象在推理或训练时程序崩溃报错显示显存耗尽。排查与解决降低输入尺寸在推理时可以通过model.predict(sourceimage, imgsz480)来指定更小的推理尺寸而不是默认的640。减少Batch Size在训练时这是首要调整项。将batch16改为batch8或batch4。使用更小的模型将yolov8l.pt换成yolov8s.pt或yolov8n.pt。清理显存在Python代码中可以使用torch.cuda.empty_cache()手动清理缓存。确保没有其他程序占用GPU。使用CPU模式如果实在无法解决在加载模型时指定设备model YOLO(best.pt).to(cpu)但速度会慢很多。问题2检测结果置信度普遍很低或者漏检严重现象上传图片后要么检测框很少要么检测出来的框置信度都在0.3以下。排查与解决检查训练数据确认你的训练数据中是否包含了与当前测试图片光照、角度、背景差异过大的情况模型可能没有学习到这种场景。需要补充更多样化的训练数据。调整置信度阈值YOLOv8推理时有一个conf参数默认是0.25。你可以调低它来召回更多目标但也会增加误检。在推理时设置results model(sourceimage, conf0.15)。验证模型性能在训练集和验证集上跑一下评估命令yolo val modelbest.pt datadataset.yaml查看mAP指标。如果验证集mAP本身就很低比如小于0.5说明模型没学好需要回头检查数据标注质量、类别是否均衡、训练轮数是否足够。域不匹配你的训练数据全是白底精拍图但测试的是杂乱货架图这属于域差异。需要在训练数据中加入大量类似真实场景的图片。5.2 前后端与服务部署问题问题3前端上传图片后后端收到None或报错现象前端点击检测浏览器F12控制台显示网络错误或者后端日志显示没有收到文件。排查与解决检查FormData确保前端JavaScript代码正确构建了FormData对象并且键名file与后端request.files[file]中的file完全一致。检查文件大小限制Flask默认限制文件上传大小。可以在后端代码中增加配置app.config[MAX_CONTENT_LENGTH] 16 * 1024 * 1024 # 16MB。检查CORS跨域如果前端页面和后端API不在同一个域名/端口下浏览器会因为同源策略阻止请求。需要在Flask后端安装flask-cors并初始化from flask_cors import CORS; CORS(app)。或者在Nginx配置中添加CORS头。问题4Gunicorn或Nginx报错服务无法访问现象浏览器访问IP地址显示“502 Bad Gateway”或“Connection refused”。排查与解决检查端口占用使用sudo netstat -tlnp | grep :5000查看5000端口是否被Gunicorn正确监听。检查Gunicorn进程使用sudo supervisorctl status shelf_detection查看进程状态。如果是FATAL或BACKOFF去查看/var/log/shelf_detection.err.log错误日志里面通常有详细的Python报错信息比如某个模块没找到。检查Nginx配置语法使用sudo nginx -t测试Nginx配置是否正确。检查防火墙确保服务器防火墙如ufw开放了80端口HTTP或443端口HTTPSsudo ufw allow 80/tcp。5.3 性能优化与扩展思路当系统能跑起来后你可能会考虑如何让它更快、更强。模型导出与加速YOLOv8的.pt模型在Python中运行效率并非最优。可以将其导出为ONNX格式或TensorRT引擎能获得显著的推理速度提升尤其是在GPU上。# 导出ONNX yolo export modelbest.pt formatonnx然后可以使用onnxruntime库来加载和推理ONNX模型。TensorRT的导出和部署稍复杂但加速比极高。实现批量处理和异步任务如果一次需要处理成百上千张图片同步的Web请求会超时。可以引入消息队列如Celery Redis。前端上传任务后立即返回一个“任务ID”后端将图片路径放入队列由Celery工作进程在后台调用模型处理处理完成后将结果存入数据库或文件前端再通过任务ID轮询查询结果。增加更多业务功能基础的检测完成后可以在此基础上增加货架排面分析通过检测框的位置和大小估算每个商品在货架上的陈列排面数即横向陈列了几个。缺货识别与标准的货架图Planogram对比识别出哪个固定货位应该是A商品但现在空了或者被B商品占据了。价格标签识别OCR在检测到商品后截取商品下方的价格标签区域使用OCR技术如PaddleOCR识别价格与系统中的价格进行比对。这个项目就像一个功能齐全的“毛坯房”水电管线数据、模型、服务、界面都已铺好能直接入住运行。但它的价值更在于为你提供了一个清晰的蓝图和坚固的地基你可以根据自己的想法和需求在这个基础上进行任意的装修和扩建把它变成解决特定零售场景痛点的强大工具。无论是用于学习、毕业设计还是作为商业项目的原型它都是一个非常扎实的起点。本文还有配套的精品资源点击获取
返回列表