
简介本资源为面向药品目标检测任务的布洛芬检测数据集适合从事药品识别、智能零售、医药分拣等场景的算法工程师与深度学习学习者使用可用于训练和验证单类别目标检测模型。压缩包共1430个文件包含476张jpg图片、476个VOC格式xml标注文件、476个YOLO格式txt标注文件及少量说明文件整体约19.62MBVOC与YOLO双格式并存便于直接接入YOLO系列或Faster R-CNN等主流检测框架。标注采用labelImg完成类别为buluofen共657个矩形框标注规范统一。目前已有175人学习下载。数据集覆盖多角度、多背景下的布洛芬药盒图像可直接用于模型训练、数据增强与迁移学习实验帮助读者快速搭建药品检测基线节省数据采集与标注成本。1. 药品布洛芬检测数据集476 张 VOCYOLO 双格式到底能训出什么药房自动盘点、药品分拣线、智能药柜补货这些场景里最先卡住你的往往不是模型结构而是数据。你手里有一批布洛芬包装盒的实拍图想训一个目标检测模型把盒子从货架上框出来结果发现公开数据集里全是 COCO、VOC 那种通用类别根本没有「布洛芬」这个类。这份 476 张的药品布洛芬检测数据集就是冲着这个缺口来的它把布洛芬包装盒单独标成一个类同时给了 VOC 的 XML 标注和 YOLO 的 txt 标注两套格式省掉你自己写转换脚本的功夫。它适合两类人——一类是刚入门目标检测、想拿一个真实小数据集跑通 yolov8 训练自己数据集全流程的新手另一类是做医药零售或工业分拣、需要一个能快速验证布洛芬识别可行性的从业者。476 张不算多但足够让你把「数据能不能训、训完能不能用」这件事在一天内问出答案而不是先花两周标数据。2. 476 张布洛芬数据集拆开看VOC 与 YOLO 两套标注的差异和选型拿到一个压缩包第一件事不是急着解压丢进训练脚本而是先搞清楚里面两套标注各自长什么样、什么时候该用哪套。很多人翻车就翻在这里以为 VOC 和 YOLO 只是换个后缀结果坐标对不上训练 loss 一路飘红还找不到原因。2.1 VOC XML 与 YOLO txt 的坐标体系到底差在哪VOC 格式的标注是一个图对应一个 XML 文件核心节点是object里面用bndbox记录xmin、ymin、xmax、ymax四个值这四个值是绝对像素坐标原点在图片左上角。YOLO 格式则是一个图对应一个 txt 文件每行是类别索引 cx cy w h这五个值里后四个都是归一化到 0~1 的相对值cx、cy是框中心点w、h是框宽高全部除以图片的宽和高得到。这个差异带来的直接后果是VOC 的框可以直接画在图上验证YOLO 的框必须先乘回图片尺寸才能画。如果你拿 YOLO 的 txt 当绝对坐标去画框会得到一堆挤在左上角的小点这就是最常见的「标注看起来全错」的假象。反过来把 VOC 的绝对坐标直接喂给 YOLO 训练模型会学到一堆超出图像范围的框loss 不收敛是必然的。转换公式本身不复杂但有两个边界必须处理一是坐标要裁剪到[0, width]和[0, height]防止标注时手抖画出界二是归一化后w、h不能为 0否则这个框在 YOLO 里等于不存在。下面这段脚本就是干这件事的把 VOC 的 XML 批量转成 YOLO 的 txtimport os import xml.etree.ElementTree as ET # 类别映射布洛芬数据集通常只有一个类索引从 0 开始 CLASS_MAP {ibuprofen: 0} def voc_to_yolo(xml_path, img_w, img_h, out_txt_path): tree ET.parse(xml_path) root tree.getroot() lines [] for obj in root.findall(object): name obj.find(name).text.strip().lower() if name not in CLASS_MAP: continue cls_id CLASS_MAP[name] bnd obj.find(bndbox) xmin float(bnd.find(xmin).text) ymin float(bnd.find(ymin).text) xmax float(bnd.find(xmax).text) ymax float(bnd.find(ymax).text) # 裁剪到图像边界防止越界框 xmin max(0, min(xmin, img_w)) xmax max(0, min(xmax, img_w)) ymin max(0, min(ymin, img_h)) ymax max(0, min(ymax, img_h)) # 转成中心点 宽高的归一化值 cx (xmin xmax) / 2.0 / img_w cy (ymin ymax) / 2.0 / img_h w (xmax - xmin) / img_w h (ymax - ymin) / img_h if w 0 or h 0: continue # 宽高为 0 的框直接丢弃 lines.append(f{cls_id} {cx:.6f} {cy:.6f} {w:.6f} {h:.6f}) with open(out_txt_path, w) as f: f.write(\n.join(lines))这段代码里img_w、img_h必须从对应图片真实读取不能写死。CLASS_MAP的 key 要和 XML 里name节点的文本完全一致大小写和空格都要对否则continue会静默跳过所有目标最后得到一堆空 txt训练时表现为「模型什么都没学到」。:.6f保留六位小数是 YOLO 官方推荐的精度够用且不会让文件膨胀。2.2 什么时候用 VOC、什么时候用 YOLO选型其实取决于你下游接什么框架。如果你用 ultralytics 系的 yolov8、yolov11直接吃 YOLO txt省一步转换如果你用 MMDetection、Detectron2 或者老一些的 Faster R-CNN 代码库它们默认读 VOC 或 COCO这时候保留 XML 更省事。这份数据集两套都给本质是让你不用在格式上做取舍。但要注意一个坑两套标注如果来源不同步可能出现同一张图 VOC 标了 2 个框、YOLO 只标了 1 个框的情况。拿到数据集后建议先做一次一致性抽查随机抽 20 张图把 XML 转成 YOLO 后和自带的 txt 逐行比对数量对不上就说明标注不同步得决定以哪套为准。这个检查花不了十分钟但能避免你训到一半发现指标虚高、实际漏检。2.3 目录结构怎么摆才能直接被 yolov8 读进去YOLO 训练对目录结构有硬性约定摆错了报错信息往往很含糊。常见做法是摆成下面这样dataset/ ├── images/ │ ├── train/ # 训练图片 │ └── val/ # 验证图片 ├── labels/ │ ├── train/ # 对应训练图片的 txt │ └── val/ # 对应验证图片的 txt └── data.yaml关键点是images/train/xxx.jpg必须对应labels/train/xxx.txt文件名不含后缀要完全一致。476 张按 8:2 切大约 380 张训练、96 张验证。切分时不要用随机切因为药品包装图往往同一盒拍多张随机切会让同一盒的图同时出现在训练和验证里验证指标虚高。按拍摄批次或包装盒个体切更靠谱。data.yaml内容如下path: ./dataset train: images/train val: images/val nc: 1 names: [ibuprofen]nc是类别数布洛芬数据集通常就是 1。names的顺序必须和 txt 里的类别索引对应索引 0 对应ibuprofen写反了模型会把布洛芬当背景。3. 用 yolov8 把这份布洛芬数据集跑起来从环境到第一个收敛曲线环境配置这块新手最容易在 CUDA 和 PyTorch 版本对上卡住。我的建议是别一上来就追最新版先用一个确定能跑的组合把流程走通再考虑升级。3.1 环境配置一条命令装完 ultralytics如果你有 NVIDIA 显卡先确认驱动和 CUDA 版本然后建一个干净的 conda 环境conda create -n yolo_ibuprofen python3.10 -y conda activate yolo_ibuprofen # 先装匹配 CUDA 的 torch这里以 CUDA 11.8 为例 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 # 再装 ultralytics pip install ultralytics装完用下面这行验证 GPU 是否可用import torch print(torch.cuda.is_available()) # 期望输出 True print(torch.cuda.get_device_name(0))如果输出False先别怀疑 ultralytics九成是 torch 装成了 CPU 版。用pip list | grep torch看版本号里有没有cu字样没有就重装。这一步过了后面训练才有意义。3.2 训练命令与关键参数怎么设环境通了训练命令其实很短yolo detect train \ data./dataset/data.yaml \ modelyolov8n.pt \ epochs100 \ imgsz640 \ batch16 \ device0 \ projectruns/ibuprofen \ nameexp1逐项说下为什么这么设。modelyolov8n.pt用 nano 版476 张的小数据集上大模型极易过拟合nano 反而更稳而且训练快适合先验证数据本身有没有问题。epochs100对小数据集够用配合早停默认patience50不会白跑。imgsz640是 YOLO 的默认输入尺寸药品包装盒在图中占比通常不小640 足够。batch16看显存8G 显存跑 640 的 nano 模型 16 没问题显存小就降到 8。训练启动后重点看三件事box_loss是否稳定下降、mAP50是否在涨、有没有出现nan。如果 loss 前几个 epoch 就变nan八成是标注里有非法值坐标越界或宽高为 0回到第 2 章的转换脚本检查。如果mAP50一直卡在 0 附近先怀疑类别名对不上或 txt 和图片没配对。3.3 训练完怎么验证模型真的学到了布洛芬训练结束会在runs/ibuprofen/exp1/weights/下生成best.pt和last.pt。用best.pt在验证集上跑一次yolo detect val \ modelruns/ibuprofen/exp1/weights/best.pt \ data./dataset/data.yaml \ imgsz640看输出的mAP50和mAP50-95。476 张单类数据集如果标注质量过关mAP50上到 0.85 以上是合理的低于 0.6 就要回头查数据。更直观的是拿几张没参与训练的图做推理yolo detect predict \ modelruns/ibuprofen/exp1/weights/best.pt \ source./test_imgs \ conf0.25 \ saveTrueconf0.25是默认置信度阈值药品场景如果漏检多就降到 0.15 看召回误检多就升到 0.4。这一步别只看指标一定要肉眼过一遍框的位置指标高但框歪的情况在小数据集上很常见。4. 小数据集训练避坑476 张布洛芬最容易踩的 5 个坑小数据集训练有个特点报错少但结果莫名其妙。下面这几条是我在类似规模数据集上反复遇到的按「现象 → 原因 → 解决」写清楚。现象一训练 loss 正常下降但验证 mAP 始终为 0。原因通常是验证集的 txt 路径或文件名和图片对不上YOLO 找不到标注就当成全背景图模型学不到任何目标。解决写个脚本遍历labels/val/检查每个 txt 是否有对应的images/val/同名图片反过来也查一遍缺哪个补哪个。现象二模型在训练集上框得很准换一张新图就乱框。这是典型过拟合。476 张里如果同一盒药拍了几十张角度相近的图模型记住的是背景而不是布洛芬。解决切分数据时按拍摄批次分别随机分同时开数据增强YOLO 默认的mosaic、hsv增强对小数据集帮助很大别关掉。现象三训练到一半 loss 突然变 nan。原因基本是标注里有非法值比如xmax xmin、坐标超出图片尺寸、或者归一化后宽高为 0。解决跑一遍第 2 章的转换脚本它做了边界裁剪和宽高过滤能挡掉大部分脏数据。如果还有手动 grep 一下 txt 里有没有负数或大于 1 的值。现象四推理时同一个布洛芬盒子被框出好几个重叠框。这是 NMS 阈值的问题不是模型没学好。默认iou0.7对密集场景偏松。解决推理时把iou降到 0.5 左右重叠框会明显减少。如果框本身位置就偏那是训练数据标注框不紧得回去修标注。现象五换了台机器训练同样的数据和参数结果差很多。原因通常是随机种子、CUDA 版本或 cuDNN 行为不一致。解决训练时固定seed0并在同一台机器上做对比实验。跨机器复现本来就有随机性别把精力耗在这上面先把单机结果做稳。5. 从 476 张到能用把布洛芬检测推到实际场景的几个技巧476 张训出来的模型直接上产线大概率不够用但作为基线完全合格。真正决定它能不能落地的是后面这几步。第一是难例挖掘。拿训好的模型去跑实际场景的图货架、分拣线、不同光照把漏检和误检的图挑出来人工补标后加进训练集。这个循环跑两三轮往往比一开始就标几千张更有效。我一般会写个脚本把conf在 0.1~0.3 之间的预测单独存出来这些是模型最不确定的样本补标价值最高。第二是输入分辨率别死守 640。药品包装盒上的文字和图案如果很小640 会丢细节。可以试试imgsz960或1280代价是显存和推理时间上升。判断标准很简单把同一张图用 640 和 960 各推一次看小目标召回有没有明显提升有就值得升。第三是类别扩展要趁早。如果你后面还要识别其他药品别等布洛芬模型调完美了再加类。多类一起训模型学到的特征更通用单类反而容易过拟合到布洛芬特有的包装颜色。加类时记得同步改data.yaml的nc和names并重新生成所有 txt 的类别索引。第四是导出格式按部署端选。如果部署在 NVIDIA 边缘设备上用 TensorRT 导出能明显提速yolo export modelbest.pt formatengine halfTrue device0halfTrue是 FP16 量化速度提升明显精度损失通常可接受。如果部署在 CPU 或 ARM 上用 ONNX 更稳。导出后一定要拿几张图对比导出前后的框确认没有因为量化导致框偏移。最后说个我自己的习惯每次训完模型我都会把best.pt、data.yaml、训练命令和当时的 git commit 记在一个小本子上。小数据集实验迭代快不记的话两周后你根本想不起来哪个权重对应哪次改动。这个习惯帮我省过好几次「到底哪个模型才是好的」的纠结。希望帮到你。本文还有配套的精品资源点击获取