
简介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 技术选型为什么是YOLOv8Python桌面端选技术栈的时候我对比过两个方向。一个是纯粹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 datapharmacy.yaml modelyolov8s.pt epochs120 imgsz640 batch16 device03.2 理解训练过程中的关键指标训练过程中我最常盯的三个损失是box_loss边界框回归损失、cls_loss分类损失、dfl_loss分布焦点损失。正常情况下这三个值都应该随着epoch增加而下降且验证集上的损失和训练集上的损失趋势要基本一致。如果训练损失降到很低但验证损失先降后升那就是过拟合了需要加正则化、调低epochs或者增加数据增强。如果训练损失和验证损失都降不下去一般是学习率设置不合理或者数据本身噪声太大。药盒识别还有一个特有问题如果某些类别图片太少它们的类别损失会一直偏高。解决办法是给稀有类别多补数据或者启用类别权重。训练结束后不要只看mAP50虽然这是最常用的指标但它对边界框位置不敏感框大一点小一点都能算对。更要关注mAP50-95这个指标对框的定位精度更苛刻。做药品识别这种对边界框要求严格的应用mAP50-95比mAP50更有参考价值。我最终的模型在验证集上mAP50达到0.97mAP50-95在0.82左右对于药盒识别来说已经够用。再往上提成本很高实际使用中差异用户几乎感知不到。3.3 模型导出与边缘情况处理训练完成后需要把模型导出成部署格式。我的部署方案是把模型转成ONNX格式再用ONNX Runtime做CPU推理因为药房工作电脑大多没有NVIDIA显卡纯CPU推理更普适。yolo export modelbest.pt formatonnx opset12导出ONNX时有几个参数值得说一下。opset版本建议10到12版本太高旧版ONNX Runtime可能不兼容导出时加上dynamicTrue可以允许动态输入尺寸但会牺牲一点推理速度。我的项目里固定输入尺寸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_FOURCC为MJPG格式分辨率设成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__里而不是每帧都加载。还有一个容易忽视的点摄像头采集帧率太高比如1920x108030fps模型推理跟不上画面就会越来越卡。把采集分辨率降到640x480帧率限制在20帧流畅度和识别准确率能找到一个很好的平衡。6.3 一次现场调试的完整排错过程有一次我在门诊药房做现场部署遇到一个很有意思的问题模型在自己笔记本上测试一切正常到了现场电脑上识别结果完全乱了套已经训练好的药盒被识别成完全不相干的类别。排查了一整天最后发现是现场电脑用的是4:3的旧显示器PyQt窗口默认尺寸拉伸之后摄像头画面被纵向拉伸药盒在画面里变成了“长条”训练时没见过这种长宽比的实例模型当然就懵了。解决方法是把摄像头采集的画面按原始比例居中显示多余部分用黑边填充不拉伸不裁剪。这类问题在测试环境很难遇到只有到了真实使用环境才能暴露所以部署调试时一定要让画面比例保持和训练数据一致这是摄像头类识别项目最容易被忽略的一个点。做这个项目最大的体会是目标检测模型本身只是整个系统里的一个组件真正决定系统能不能落地的是数据质量、界面交互、部署兼容性这些模型之外的工程问题。药盒识别尤其如此——模型分类容错率其实可以比较宽容但信息关联错了就是用药事故。所以我在系统里凡是对应关系不明确的检测结果都默认提示“请人工复核”而不是直接输出绝对结论。系统辅助人而不是替代人这应该是所有医疗相关AI产品的底线。如果后续你想在这个项目上继续扩展可以考虑从单帧识别升级到视频流时序平滑或者接入药品追溯码做二次校验这些都是实用且贴合场景的改进方向。本文还有配套的精品资源点击获取