
简介本资源为药品布洛芬目标检测数据集面向从事药品识别、智能零售与医药分拣等方向的算法工程师、学生及研究者可用于训练与验证单类别目标检测模型。包内共1430个文件包含476张jpg图片、476个VOC格式xml标注文件、476个YOLO格式txt标注文件及少量说明文件压缩包约19.62MBVOC与YOLO双格式并存便于直接接入YOLO系列或Faster R-CNN等主流框架。标注类别仅buluofen一类共657个矩形框采用labelImg工具绘制标注规范统一。目前已有175人学习下载。读者可据此快速构建药品检测训练集省去采集与标注成本并借助双格式标注灵活切换训练流程适合作为课程设计、毕业设计或算法对比实验的数据基础。1. 药品布洛芬检测数据集476张VOCYOLO格式到底能跑出什么药房里最容易被拿错的一类药就是那些铝塑泡罩包装长得几乎一模一样的小药片。布洛芬作为解热镇痛类的常用药单盒外观和感康、阿莫西林、对乙酰氨基酚摆在一起肉眼扫过去差别极小。如果你正在做一个药品分拣、药房盘点或者智能药柜的项目第一个卡住你的往往不是模型结构而是「我上哪找一批标注好的布洛芬图片」。这个476张、VOCYOLO双格式的目标检测数据集解决的就是这个冷启动问题——它让你在半天内跑通一条从数据到检测框的完整链路而不是花两周去拍图、标框、转格式。适合谁适合刚接触目标检测、想拿一个真实小样本数据集练手的人也适合已经在做药品视觉识别、需要一个可快速验证的基线数据的工程师。476张不算多但足够你把YOLO的训练流程、格式转换、过拟合判断这几件事全部走一遍。2. 先搞清楚VOC和YOLO两种格式差在哪别拿到压缩包就急着训练2.1 VOC的XML结构和YOLO的TXT结构字段对应关系VOC格式的核心是每张图配一个同名的XML文件标注信息全在里面。YOLO格式则是每张图配一个同名的TXT文件一行一个目标。这两种格式不是简单的「换个后缀」坐标体系完全不同VOC用的是绝对像素坐标YOLO用的是归一化后的中心点坐标加宽高。你拿到数据集后第一件事不是解压完就丢给训练脚本而是先确认两种格式的目录结构对不对。VOC的典型目录长这样VOC2007/ ├── Annotations/ # 存放XML标注文件 │ ├── 000001.xml │ └── ... ├── JPEGImages/ # 存放原始图片 │ ├── 000001.jpg │ └── ... ├── ImageSets/ │ └── Main/ # 存放训练/验证集划分文件 │ ├── train.txt │ ├── val.txt │ └── trainval.txt └── SegmentationClass/ # 分割任务用检测任务可忽略YOLO的典型目录长这样dataset/ ├── images/ │ ├── train/ # 训练集图片 │ └── val/ # 验证集图片 ├── labels/ │ ├── train/ # 训练集标注TXT │ └── val/ # 验证集标注TXT └── data.yaml # 数据集配置文件一个VOC的XML文件内容大致是annotation folderJPEGImages/folder filename000001.jpg/filename size width640/width height480/height depth3/depth /size object nameibuprofen/name !-- 类别名 -- bndbox xmin120/xmin !-- 左上角x绝对像素 -- ymin85/ymin !-- 左上角y绝对像素 -- xmax310/xmax !-- 右下角x绝对像素 -- ymax260/ymax !-- 右下角y绝对像素 -- /bndbox /object /annotation对应的YOLO TXT文件内容是一行0 0.3359 0.3594 0.2969 0.3646这五个数的含义分别是类别索引、中心点x归一化值、中心点y归一化值、框宽归一化值、框高归一化值。归一化的分母就是图片的宽和高。很多人第一次转格式时框全偏了就是因为把绝对坐标直接除以了错误的尺寸或者忘了VOC的xmax/ymax是包含边界的而YOLO的宽高是算出来的差值。2.2 476张图为什么还要分VOC和YOLO两份选型理由你可能会问既然YOLO训练只用TXT为什么数据集还要附带VOC格式原因有三个。第一VOC是很多标注工具的默认导出格式LabelImg、Labelme这些工具原生输出就是XML保留VOC等于保留了「原始标注证据」万一YOLO的TXT转错了你还能从XML重新转一遍。第二有些框架和评估脚本仍然吃VOC格式比如早期的Faster R-CNN实现、部分比赛提交格式。第三VOC的XML里除了框还有图片尺寸、深度、文件夹路径这些元信息排查问题时比光秃秃的TXT有用得多。对于476张这个量级我的建议是训练用YOLO格式但VOC那份别删。你后面做数据增强、做错例分析、甚至想换到MMDetection框架时VOC的XML能省掉你重新标注的功夫。这不是冗余是后悔药。2.3 用脚本把VOC转成YOLO转换逻辑与边界处理如果你拿到的数据集里VOC和YOLO是分开的两个文件夹那直接用YOLO那份就行。但如果你只有VOC或者想验证两份是否一致就需要自己写转换脚本。下面这个Python脚本是我常用的版本处理了类别映射、坐标归一化和边界裁剪import xml.etree.ElementTree as ET import os import glob # 类别映射根据你的数据集实际类别修改 CLASSES [ibuprofen] def voc_to_yolo(xml_path, output_dir, img_w, img_h): 将单个VOC XML转为YOLO TXT xml_path: XML文件路径 output_dir: TXT输出目录 img_w, img_h: 图片宽高用于归一化 tree ET.parse(xml_path) root tree.getroot() # 用文件名不含后缀作为TXT文件名 base_name os.path.splitext(os.path.basename(xml_path))[0] txt_path os.path.join(output_dir, base_name .txt) lines [] for obj in root.findall(object): cls_name obj.find(name).text if cls_name not in CLASSES: continue # 跳过不在类别表里的目标 cls_id CLASSES.index(cls_name) bbox obj.find(bndbox) xmin float(bbox.find(xmin).text) ymin float(bbox.find(ymin).text) xmax float(bbox.find(xmax).text) ymax float(bbox.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 lines.append(f{cls_id} {cx:.6f} {cy:.6f} {w:.6f} {h:.6f}) with open(txt_path, w) as f: f.write(\n.join(lines)) # 批量转换示例 xml_dir VOC2007/Annotations out_dir labels os.makedirs(out_dir, exist_okTrue) # 注意这里需要你从图片或XML的size节点读取宽高 # 如果XML里有size节点可以直接从XML读不用额外传参 for xml_file in glob.glob(os.path.join(xml_dir, *.xml)): tree ET.parse(xml_file) size tree.getroot().find(size) w int(size.find(width).text) h int(size.find(height).text) voc_to_yolo(xml_file, out_dir, w, h)这段代码的关键点有三个。第一CLASSES列表必须和你的数据集类别严格对应顺序错了类别索引就全错。第二边界裁剪那四行不能省药品数据集的标注有时候框会压到图片边缘甚至超出几个像素不裁剪的话归一化后会出现负数或大于1的值训练时直接报错。第三归一化保留6位小数足够YOLO训练时对精度不敏感但格式必须统一。参数方面img_w和img_h优先从XML的size节点读这样最准。如果XML里没有size节点有些标注工具会省略你就得用OpenCV或PIL去读图片实际尺寸千万别用固定值。3. 用YOLOv8跑通476张药品检测从data.yaml到第一次推理3.1 环境配置与data.yaml的四个必填字段环境这块我不绕弯子直接给一套能跑通的组合Python 3.9以上、PyTorch 2.0以上、ultralytics 8.x。安装命令就一行pip install ultralytics装完之后yolo命令就能用了。接下来是数据集配置文件data.yaml这是YOLO训练最容易被忽略但最不能错的文件。它长这样path: /home/user/ibuprofen_dataset # 数据集根目录 train: images/train # 训练集图片相对路径 val: images/val # 验证集图片相对路径 nc: 1 # 类别数量 names: [ibuprofen] # 类别名称列表四个字段里path是根目录train和val是相对于path的路径nc和names必须一一对应。我见过太多人把nc写成类别名数量但names里多写了一个空格结果训练时类别索引越界。还有一个坑train和val指向的是图片目录不是标签目录YOLO会自动去找同级的labels目录。所以你的目录结构必须是images/train和labels/train并列不能把标签塞到别的地方。3.2 训练命令与关键参数epochs、imgsz、batch怎么定476张图属于小样本训练策略和大数据集不一样。下面是我在这个量级上常用的命令yolo detect train \ datadata.yaml \ modelyolov8n.pt \ epochs150 \ imgsz640 \ batch16 \ lr00.01 \ patience30 \ augmentTrue \ projectruns/ibuprofen \ nameexp1逐个说参数。modelyolov8n.pt选的是nano版本476张图用大模型纯属浪费nano足够跑出一个可用的基线。epochs150是因为小样本需要多轮才能收敛但别设500过拟合会来得很快。imgsz640是YOLO的默认输入尺寸药品图片如果分辨率不高可以降到416或320能明显提速。batch16取决于你的显存8G显存跑640尺寸的nano模型16基本是上限。lr00.01是初始学习率小样本可以适当降到0.005收敛更稳。patience30是早停耐心值30轮验证集指标不提升就停省时间。augmentTrue开启内置数据增强476张图必须开否则模型见到的样本太单一。训练过程中重点看两个指标mAP50和mAP50-95。mAP50到0.8以上说明框基本找准了mAP50-95到0.5以上说明框的精度也还行。如果mAP50很高但mAP50-95很低说明框的位置不够准可能是标注质量有问题。3.3 推理验证用训练好的权重跑单张图和批量图训练完权重默认存在runs/ibuprofen/exp1/weights/best.pt。跑单张推理yolo detect predict \ modelruns/ibuprofen/exp1/weights/best.pt \ sourcetest_images/ \ conf0.25 \ saveTrueconf0.25是置信度阈值低于这个值的框不显示。药品检测场景下我一般会把conf调到0.3到0.4因为药盒之间的误检比漏检更麻烦——你把一个不是布洛芬的盒子框成布洛芬分拣线就出错了。saveTrue会把带框的图片存到runs/detect/predict目录下方便你肉眼检查。批量推理就是把source指向一个文件夹YOLO会遍历里面所有图片。如果你要集成到自己的Python代码里用下面这段from ultralytics import YOLO model YOLO(runs/ibuprofen/exp1/weights/best.pt) results model(test_images/, conf0.3, saveTrue) # 遍历结果打印每个框的类别和坐标 for r in results: boxes r.boxes for box in boxes: cls_id int(box.cls[0]) conf float(box.conf[0]) xyxy box.xyxy[0].tolist() # 左上右下坐标 print(f类别: {model.names[cls_id]}, 置信度: {conf:.2f}, 坐标: {xyxy})这段代码里box.xyxy返回的是绝对像素坐标和VOC的格式一致方便你后续做裁剪或计数。model.names是类别索引到名称的映射直接从模型里读不用自己维护。4. 476张小样本训练的避坑清单这五个坑我替你踩过了4.1 坑一训练loss正常下降但mAP一直是0现象训练日志里box_loss和cls_loss都在降但验证集的mAP50始终是0模型好像什么都没学到。原因九成是data.yaml里的names和标注TXT里的类别索引对不上。比如你的TXT里写的是0但names列表里第一个类别不是布洛芬或者nc写成了2但实际只有1类。YOLO不会报错它会默默地把所有预测都归到错误的类别上导致mAP计算时匹配不上。解决打开一个标注TXT看第一个数字是几然后确认data.yaml里names列表对应索引位置的类别名是不是布洛芬。再检查nc是否等于len(names)。改完重新训练一般前10个epoch就能看到mAP往上走。4.2 坑二验证集mAP很高但实际推理框全偏了现象训练完看验证集指标mAP50有0.9感觉不错。但拿几张没参与训练的图片一跑框的位置明显偏移有的框甚至框到了背景上。原因476张图如果划分验证集时用了随机划分而图片之间高度相似比如同一个药盒的不同角度验证集和训练集分布几乎一样指标虚高。另外如果标注时框画得太松模型学到的就是松框推理时也会偏。解决划分验证集时按「不同拍摄批次」或「不同背景」来分别用纯随机。如果数据量实在小至少保证验证集里有几张和训练集明显不同的图。标注质量方面用LabelImg重新过一遍框把明显偏大的框收紧。4.3 坑三batch设太大导致显存溢出但报错信息看不懂现象训练启动几秒后报CUDA out of memory但你的显存明明还有空余。原因YOLO训练时的显存占用不是线性的batch和imgsz是乘数关系。640尺寸下batch16可能刚好卡在8G显存的边缘加上数据加载的缓存就爆了。另外如果开了augmentTrue数据增强也会占额外显存。解决先把batch降到8如果还爆就降到4。或者把imgsz从640降到416显存占用大约能降一半。还有一个技巧是设workers2减少数据加载进程数也能省一点显存。别硬撑小样本训练batch小一点反而梯度更稳。4.4 坑四VOC转YOLO后框全部挤在左上角现象转换完TXT用可视化工具一看所有框都缩在图片左上角一小块区域。原因归一化时除错了分母。VOC的坐标是绝对像素YOLO需要除以图片的宽和高。如果你把x坐标除以了高、y坐标除以了宽或者用了固定的640和480去归一化但实际图片尺寸不是这个框就会全偏。解决归一化前先打印几张图片的实际尺寸确认和XML里size节点一致。然后用img_w除x相关坐标img_h除y相关坐标别搞反。转换完随机抽5张图用OpenCV把YOLO框画回图片上肉眼确认位置对不对。4.5 坑五训练完模型只认识训练集里的那几种摆放角度现象训练集里布洛芬都是正面朝上拍的推理时遇到侧放或倒放的药盒模型完全检测不到。原因476张图如果拍摄角度单一模型学到的特征就是「正面朝上的布洛芬」没有见过其他姿态。这不是模型的问题是数据分布的问题。解决训练时开启YOLO内置的旋转增强。在训练命令里加degrees10.0让图片在正负10度内随机旋转。如果数据量允许手动补拍一些侧放、倒放、部分遮挡的图片。药品检测场景下遮挡是常态药盒叠在一起时只露出一角模型也得能认出来。5. 把476张用到极致小样本药品检测的进阶技巧476张图训练一个能用的模型不难难的是让它稳定。我自己的习惯是训练完第一版之后不急着调参先做一件事把验证集里所有预测错的图挑出来一张一张看。错例分析比盲目调epochs有用十倍。下面这张表是我常用的错例分类框架你可以直接套错例类型典型表现优先处理方式漏检图里有布洛芬但没框出来检查标注是否漏标补标后重训误检把背景或其他药盒框成布洛芬增加负样本调高conf阈值框不准框到了但位置偏大或偏小重新收紧标注框检查归一化类别混淆框对了但类别标错确认names列表顺序检查TXT索引错例分析做完如果漏检和误检都集中在某几种背景上那就针对性地补拍那几种背景的图片。476张不够就补到600张补图比调参见效快。另一个技巧是冻结 backbone 做微调。如果你之前用其他药品数据集训练过YOLO可以把backbone冻结只训练检测头。命令里加freeze10表示冻结前10层。这样476张图能在更少的epoch里收敛而且不容易过拟合。我一般会在数据量低于500张时优先试这个策略。还有一个容易被忽略的点推理时的输入尺寸。训练用640推理也可以用640但如果你的实际部署环境是边缘设备推理尺寸可能要降到320。这时候别直接拿640训练的模型去跑320的推理精度会掉。正确做法是训练时就把imgsz设成320让模型在目标尺寸上收敛。我吃过这个亏训练时640部署时320mAP直接掉了15个点血泪经验。最后说一个验证方法把数据集里最难的10张图单独拎出来不参与训练作为「测试集」。每次调完参先跑这10张看框得怎么样。这10张图的表现比验证集指标更能反映真实水平。如果这10张能框准模型基本就稳了。我自己的习惯是拿到任何一个小样本数据集先跑通基线再做错例分析最后才动参数。476张布洛芬图片不多但足够你把目标检测的完整流程走一遍。别指望一次训练就完美迭代三轮是常态。希望帮到你。本文还有配套的精品资源点击获取