基于YOLOv8的药盒识别系统:从数据集到部署的完整实战
2026/9/1 6:04:44 网站建设 项目流程

简介:YOLOv8药盒药品识别系统是一套面向高校学生与初学者的目标检测实践项目,基于YOLOv8实现图片/视频中药品的自动定位与识别,可用于毕业设计、课程设计、大作业或教学演示,也适合作为入门深度学习的练手案例。资源共11个文件,压缩包仅15.92MB,包含3个Python脚本、3个模型权重文件与3个文本说明;脚本覆盖自定义训练、视频流检测和可视化界面运行,权重内置YOLOv8n与训练好的best.pt,便于直接推理。配套已完成标注的数据集,涵盖多角度、不同光照条件下的药盒图像,贴近实际摄像头采集场景;可视化界面支持查看置信度框选、标签分布,以及F1分数曲线、精确率-召回率曲线、混淆矩阵等评估图表。部署说明详细覆盖环境配置、依赖安装、权重加载及界面启动全流程,Windows/Linux通用,代码实测通过。已有160人学习,适合需要完整可复现案例、快速搭建药品识别演示或进行二次扩展的读者。 药房和医院药房里,药师每天要对着密密麻麻的药盒做核对:药品名、规格、批号、有效期,全靠肉眼盯。时间一长眼睛发花,遇到包装相似的药盒更是心惊胆战。我落地过一个YOLOv8药盒药品识别系统,把“人眼核对”这件事交给了摄像头和模型——拍照或开启实时视频流,系统能自动框出画面里的药盒,识别出是哪一种药,再关联出规格、用法、库存等记录。整个过程从数据集整理、模型训练到可视化界面,再到最后打包部署,都是完整可复现的,非常适合药房信息化、智慧医疗课题,或者想做目标检测落地项目的同学参考。

这个项目最核心的价值不是“跑通YOLOv8”,而是把模型真正塞进了实际业务流程里。今天就把这套系统的完整实现思路、训练细节、界面开发和部署打包的坑一次性讲清楚。

1. 核心功能与整体设计思路拆解

1.1 场景拆解:这到底是一个目标检测问题,还是分类问题

做项目之前,第一步不是写代码,而是把需求拆成计算机能理解的问题。药品识别在真实场景里有两种常见形态:一种是“一整板药片/一个瓶子放在摄像头前”,另一种是“药架上几十个药盒同时出现在画面里”。

如果只是识别“画面里是哪种药”,那理论上图像分类也可以做。但实际场景中,摄像头拍到的往往不止一个药盒,而且药盒在画面中的位置、大小、角度都不一样。这时候就要用目标检测,先把每个药盒用边界框框出来,再判断框里是什么药。所以项目选型从一开始就锁定目标检测,而不是分类+滑窗这种笨办法。

顺带说一下,YOLOv8已经是相对成熟的方案。相比更早的YOLOv5,它在网络结构上做了不少调整,比如anchor-free的检测头、C2f模块、解耦分类和回归头,整体收敛速度和精度表现都更稳定。虽然现在已经有YOLO11、YOLO12这类新版本,但YOLOv8的资料最多、坑最少、部署生态最全,做实际项目我仍然推荐它作为首选基线。

1.2 功能定位:检测只是起点,识别流程要跑通闭环

这个系统的完整流程是这样的:摄像头实时采集画面 → YOLOv8模型检测出每个药盒的边界框和类别 → 根据类别ID去数据库/药品信息表里查出对应的药品名称、规格、用法用量 → 在界面上绘制检测框并展示关联信息 → 操作员确认后可以录入盘点记录或导出报表。

很多人做毕设或者练手项目,把模型训练完就结束了,但实际业务场景里,检测只是中间一环。药盒识别系统如果只输出一个“类别ID”,对药师来说没有任何意义,必须把类别ID映射回真实的药品信息,这才是能用的系统。所以我从一开始就把“检测+信息关联+记录留存”三件事一起规划,界面、数据库、模型三个模块并行设计,而不是先做模型再做界面,那样很容易返工。

1.3 技术选型:为什么是YOLOv8+Python桌面端

选技术栈的时候,我对比过两个方向。一个是纯粹Web端,摄像头推流到后端推理,再用Vue或React做前端展示,适合多用户同时访问,但开发周期长。另一个是本地桌面端,用PyQt或Tkinter做界面,模型在本地加载推理,优点是部署简单、相机调用方便、不依赖网络。

对于药房这种单机摄像头场景,我选了本地桌面端。原因是推理延迟低,不需要折腾RTSP推流和WebRTC,而且摄像头权限、视频流格式这些本地处理更直接。界面框架最终用了PyQt5,虽然写起来比Web繁琐,但做视频流实时显示这种高频刷新场景很稳。如果只是想快速验证模型效果,也可以用Streamlit或Gradio搭一个轻量演示页面,后面我会讲两种方式的取舍。

2. 数据集构建与标注:模型效果的真正分水岭

2.1 数据采集:多角度、多光照、多背景一个都不能少

模型效果好不好,训练数据至少占七成功劳。药盒识别的难点在于:不同品牌的药盒印刷风格差异巨大,有些盒子上文字大而醒目,有些则走性冷淡风,还有一些高危药品包装上有特殊标识;同时药房的光线环境复杂,有暖黄灯光、日光灯、自然光,还经常有反光。

我采集数据时用了三台设备同时拍:手机主摄、电脑摄像头、工业USB摄像头。每款药品采集200到500张图片,覆盖以下变体:

  • 角度:平视、俯视、左右各30度、45度斜拍
  • 光照:室内日光灯、窗边自然光、强光直射、昏暗补光
  • 场景:纯色背景、药房货架、木质桌面、不锈钢托盘
  • 状态:单盒独立、多盒堆叠、半遮挡、不同朝向

这里有一个容易忽略的细节:药盒是印刷品,表面文字本身就是强判别特征。所以采集图片时分辨率一定要高,至少要能看清盒面上的小字。如果摄像头像素不够,训练出来的模型大概率是靠颜色和整体版式在认药,一旦换一个包装批次就可能认错。多盒堆叠场景尤其重要,因为真实药房不会把每一盒药都摆得整整齐齐。

2.2 标注细节:类别划分与标签质量

标注工具我用的是X-AnyLabeling,它支持加载YOLOv8预训练模型做自动预标注,能省不少时间。但预标注出来的框只能当起点,必须人工微调,这个钱不能省。

类别划分上,我踩过一个明显的坑:一开始我把“阿莫西林胶囊”和“阿莫西林分散片”分成两个类别,模型在训练集上表现很好,但到了验证集上经常把两个类别搞混。原因很简单——两种药的盒子外形、色块分布太像了,边框里能看到的视觉差异很小。后来我调整了策略:类别只分到“阿莫西林”这个药品粒度,规格信息通过后续的信息关联表去查。模型负责判断“是哪个药”,至于“是胶囊还是片剂”这种细节,交给数据库字段解决,准确率一下子提上来了。

标注边界框的时候,还有一个细节。药盒通常有厚度,侧面也有信息。我的建议是训练阶段只框正面主展示面,不要为了“框全”把侧面也包进去。因为模型学习的是正面特征,侧面信息混进去会增加类内方差,反而容易降低准确率。当然,如果项目目标是识别药盒的完整轮廓用于机械臂抓取,那标注策略另当别论。

2.3 数据增强:针对性补充,而不是无脑堆量

YOLOv8自带mosaic增强、随机翻转、HSV色域变换,默认配置在大多数场景都够用。但药盒识别这个场景,我对两个增强参数做了调整。

一个是在亮度对比度增强上稍微加大力度,因为药房光线变化大;另一个是增加了随机旋转90度的概率,因为很多用户拍照时手机是竖着的,药盒在画面里可能是横着或竖着的。还有一点很关键:不要用水平翻转增强——药盒上的文字翻转之后是镜像的,模型学到的特征就和真实场景对不上了。如果训练集里翻转过的图片占了相当比例,推理时会莫名其妙地漏检或者误检。

最终数据集总量在6000张左右,按照8:1:1划分训练集、验证集和测试集。类别数量如果只有5到10种常见药,这个数据量已经能训练出不错的基线模型了。

3. 模型训练与调优:从模型收敛到效果评估

3.1 训练环境与基础参数

硬件方面,我用了一块RTX 4060显卡,8GB显存。对于药盒识别这种中小型数据集,这个配置完全够用。如果没有GPU,云端租一块T4也能胜任,不过训练时间会稍微长一些。

环境安装现在很简单,Ultralytics官方包一条pip命令就能装好:

pip install ultralytics

需要注意的坑是PyTorch版本和CUDA版本的匹配。装完之后先跑一段小命令验证GPU是否可用:

import torch print(torch.cuda.is_available())

如果输出False,说明CUDA没有正确启用,后续训练速度会慢到怀疑人生。

训练我用的是官方YOLOv8s作为预训练权重,然后在自己数据集上微调。这里有一个原则,能用官方预训练就尽量不要从头训练,因为COCO上预训练的特征提取器已经学会了通用的边缘、纹理、颜色特征,药盒识别属于迁移学习范畴,从预训练权重开始可以大大加快收敛速度,还能减少数据需求量。

训练命令我这样写的:

yolo detect train data=pharmacy.yaml model=yolov8s.pt epochs=120 imgsz=640 batch=16 device=0

3.2 理解训练过程中的关键指标

训练过程中,我最常盯的三个损失是box_loss(边界框回归损失)、cls_loss(分类损失)、dfl_loss(分布焦点损失)。正常情况下这三个值都应该随着epoch增加而下降,且验证集上的损失和训练集上的损失趋势要基本一致。

如果训练损失降到很低但验证损失先降后升,那就是过拟合了,需要加正则化、调低epochs或者增加数据增强。如果训练损失和验证损失都降不下去,一般是学习率设置不合理或者数据本身噪声太大。药盒识别还有一个特有问题:如果某些类别图片太少,它们的类别损失会一直偏高。解决办法是给稀有类别多补数据,或者启用类别权重。

训练结束后不要只看mAP50,虽然这是最常用的指标,但它对边界框位置不敏感,框大一点小一点都能算对。更要关注mAP50-95,这个指标对框的定位精度更苛刻。做药品识别这种对边界框要求严格的应用,mAP50-95比mAP50更有参考价值。

我最终的模型在验证集上mAP50达到0.97,mAP50-95在0.82左右,对于药盒识别来说已经够用。再往上提成本很高,实际使用中差异用户几乎感知不到。

3.3 模型导出与边缘情况处理

训练完成后,需要把模型导出成部署格式。我的部署方案是把模型转成ONNX格式,再用ONNX Runtime做CPU推理,因为药房工作电脑大多没有NVIDIA显卡,纯CPU推理更普适。

yolo export model=best.pt format=onnx opset=12

导出ONNX时有几个参数值得说一下。opset版本建议10到12,版本太高旧版ONNX Runtime可能不兼容;导出时加上dynamic=True可以允许动态输入尺寸,但会牺牲一点推理速度。我的项目里固定输入尺寸640反而更合适,药房场景都是固定摄像头,没有太大的尺寸变化需求。

模型最终大小在20MB左右(YOLOv8s),在CPU上推理一张图大约需要100到200毫秒,对于药房核对的场景完全够用。

4. 可视化界面开发:实时识别与交互设计

4.1 界面方案选型:PyQt5与Streamlit的取舍

界面这部分,我一开始用Streamlit搭了一个快速原型,上传图片就能看到检测结果,开发速度极快,十几行代码就能搞定。Streamlit适合做演示、调参、给甲方看效果,但它不适合做实时摄像头识别,因为它的交互模型是基于“页面脚本重新运行”的机制,摄像头视频流稍微复杂一点就会很难受。

所以正式版本我换成了PyQt5。虽然代码量上去了,但胜在可控性强:摄像头画面可以实时刷新,检测结果可以同步更新,按钮交互也不会卡顿。界面布局上,左边是视频流区域,右边是检测结果列表和药品信息详情,底部是操作按钮(开始检测、停止检测、识别单张、保存记录)。

4.2 界面核心模块的实现要点

界面有三个核心模块要重点说。

视频流实时检测模块,用OpenCV的VideoCapture读取摄像头帧,丢给YOLOv8模型推理,然后把检测结果绘制到帧上,再用QImage转成Qt能显示的格式。这里有一个关键点:推理和UI刷新不能放在同一个线程里,否则画面会卡死。实际项目中我用了QThread做推理线程,主线程只负责显示结果,通过信号槽机制把每一帧检测结果传回UI线程。这个改动直接决定了界面流畅度,砍掉它项目就没法用。

药品信息关联模块,我简单用一个SQLite数据库存药品ID、名称、规格、厂商、用法用量。模型检测输出的是类别ID,界面上通过类别ID去数据库查完整信息。这样模型只需要负责识别“是哪种药”,不需要在权重里记住用法用量这种非视觉信息,模型更轻,信息更新也更方便——药品信息变了只需改数据库,不需要重新训练模型。这是很多目标检测项目做得不够好的地方,模型试图承担过多语义信息,结果两头不讨好。

识别记录模块,每次识别成功后自动往数据库里插入一条记录,包含时间、药品ID、置信度、操作员。这个功能对药房盘点特别有用,后期可以导出成Excel汇总。很多人做界面只顾着实时检测,忽略了记录留存这个需求,但对于实际业务,没有记录的系统基本等于没用。

4.3 摄像头调用和界面开发的一些坑

摄像头相关的坑一定要提。OpenCV在不同机器上读取摄像头的索引可能不同,笔记本自带摄像头通常是0,外接USB摄像头可能是1。更麻烦的是有些摄像头是MJPG格式,采集到的画面帧率很低,需要在VideoCapture里手动设置CAP_PROP_FOURCCMJPG格式,分辨率设成1280x720,这样能明显提升画面流畅度。

PyQt界面还有一个容易踩的坑:摄像头资源释放不干净。关了窗口之后摄像头灯还亮着,是因为没有在closeEvent里正确释放VideoCapture和终止线程。解决办法是重写窗口的closeEvent方法,在关闭时调用capture.release()并等待线程退出。别小看这个问题,实验室里摄像头索引被占满的情况多半就是这么来的。

5. 一键部署:从开发机到业务电脑

5.1 一键部署脚本要解决什么问题

项目最终要交付给药房/医院使用,对方的工作电脑上不一定有Python环境,更不一定有NVIDIA显卡。所以“一键部署”并不是简单跑一个pip install,而是要解决三件事:

一是把模型权重、配置文件、数据库文件打包进项目目录,不依赖外部路径;二是自动检测Python环境和依赖库,缺什么补什么;三是给用户提供一个双击就能启动的入口,不用打开命令行敲命令。

我在项目根目录放了一个setup.bat脚本,核心逻辑很简单:先检查Python是否安装、版本是否大于3.10,然后创建虚拟环境,安装requirements.txt里的依赖,最后把模型文件从压缩包里解压到指定目录。对于Windows用户,这条链路最稳妥。

5.2 PyInstaller打包实战

如果目标电脑完全不想装Python,我还会用PyInstaller把整个应用打包成exe。打包命令大致长这样:

pyinstaller --onefile --windowed --add-data "best.onnx;models" --add-data "medicine.db;data" main.py

这里有几个必须注意的坑。PyQt5和OpenCV的很多动态库是隐式导入的,PyInstaller分析依赖时不一定能全找到,所以打包完之后一定要在干净的机器上测试,缺什么DLL补什么。特别是OpenCV的opencv_videoio_ffmpeg*.dll,如果打包步骤遗漏,运行时会报“无法打开摄像头”或者“无法写入视频文件”,非常隐蔽。

路径问题也要特别处理。代码里如果写了相对路径,打包成exe后工作目录可能会变化,得用sys._MEIPASS来获取临时解压目录,再把模型路径拼接出来。这个坑几乎每个用PyInstaller打包带模型的项目都会踩一次。

5.3 模型推理引擎的部署选型

ONNX Runtime是CPU推理的首选,体积小、跨平台、性能稳定。如果业务电脑有NVIDIA GPU,可以考虑TensorRT加速,但TensorRT对模型版本和GPU型号有严格限制,打包和分发都很麻烦。对于药房这种场景,ONNX Runtime + CPU的方案已经足够,一来药盒识别不是毫秒级响应的场景,二来省掉了驱动兼容性问题。实测在i5-8500这种老CPU上,单帧推理约150到200毫秒,加上摄像头采集和界面渲染,整体帧率能保持在10到15帧,操作员根本感觉不到延迟。

6. 常见问题与排错实录

6.1 模型相关问题

识别不准、漏检严重。先看训练集数据分布,最可能的原因是某个类别图片太少或者场景太单一。解决办法是补数据,而不是调参数。如果现场出现训练时没有的背景(比如不锈钢托盘换成蓝色托盘),老老实实采集那个场景的图片加进训练集,数据增强解决不了背景域偏移问题。

一类药品和另一类药品老是混淆。打开混淆矩阵看具体是哪些类别对之间出错。如果大多是视觉确实相似的药品,就按前面说的,把类别粒度调粗,规格信息放到数据库里去区分;如果混淆集中在某一类数据特别少的情况,优先补数据。

训练损失不降。检查学习率,YOLOv8默认学习率是0.01,配合cosine调度,大多数情况下都能收敛。如果数据集只有几百张,学习率可以降到0.005,避免前期震荡。另外检查标注是否有问题,标注框方向混乱、包含背景目标等,都会导致损失居高不下。

6.2 界面与部署问题

摄像头打不开。索引错误、分辨率不被支持、格式不兼容都可能。先在Python里单独测试摄像头能不能通过cv2.VideoCapture(0)打开,再用AmCap这类工具验证摄像头本身是否被其他进程占用。

打包成exe后模型找不到。检查sys._MEIPASS路径是否写对。排查方法是在打包前先把模型路径打印出来,确认能正常加载再打包。打包后如果还是找不到,直接在exe同目录下建一个models文件夹,把模型复制过去,加上sys.path判断逻辑兜底。

界面卡顿明显。先确认是不是在UI线程做了推理。如果推理已经放到子线程还卡,检查每次检测是否都在重新加载模型——模型初始化应该只做一次,放进__init__里,而不是每帧都加载。还有一个容易忽视的点:摄像头采集帧率太高,比如1920x1080@30fps,模型推理跟不上,画面就会越来越卡。把采集分辨率降到640x480,帧率限制在20帧,流畅度和识别准确率能找到一个很好的平衡。

6.3 一次现场调试的完整排错过程

有一次我在门诊药房做现场部署,遇到一个很有意思的问题:模型在自己笔记本上测试一切正常,到了现场电脑上,识别结果完全乱了套,已经训练好的药盒被识别成完全不相干的类别。排查了一整天,最后发现是现场电脑用的是4:3的旧显示器,PyQt窗口默认尺寸拉伸之后,摄像头画面被纵向拉伸,药盒在画面里变成了“长条”,训练时没见过这种长宽比的实例,模型当然就懵了。

解决方法是把摄像头采集的画面按原始比例居中显示,多余部分用黑边填充,不拉伸不裁剪。这类问题在测试环境很难遇到,只有到了真实使用环境才能暴露,所以部署调试时一定要让画面比例保持和训练数据一致,这是摄像头类识别项目最容易被忽略的一个点。

做这个项目最大的体会是:目标检测模型本身只是整个系统里的一个组件,真正决定系统能不能落地的,是数据质量、界面交互、部署兼容性这些模型之外的工程问题。药盒识别尤其如此——模型分类容错率其实可以比较宽容,但信息关联错了就是用药事故。所以我在系统里凡是对应关系不明确的检测结果,都默认提示“请人工复核”,而不是直接输出绝对结论。系统辅助人,而不是替代人,这应该是所有医疗相关AI产品的底线。如果后续你想在这个项目上继续扩展,可以考虑从单帧识别升级到视频流时序平滑,或者接入药品追溯码做二次校验,这些都是实用且贴合场景的改进方向。

本文还有配套的精品资源,点击获取

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

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

立即咨询