
简介这是一套面向YOLO目标检测的医学图像数据集与配套教程聚焦红细胞、白细胞和血小板的检测识别适合医学影像分析、细胞分类计数等课程设计及入门实战。图片来自真实场景使用LabelImg标注标注框质量较高同时提供VOC(xml)、COCO(json)、YOLO(txt)三种格式标签分目录存放可无缝接入YOLO系列模型训练。资源共2000个文件以xml、txt标签文件为主辅以HTML格式的环境搭建与训练案例教程、Python格式的数据集划分脚本以及YAML配置文件压缩包大小约29.34MB。随包还附Linux/Windows双平台的YOLO环境搭建说明、按案例修改训练自己数据集的详细教程以及可灵活生成训练集、验证集、测试集划分的脚本帮助读者省去数据清洗与格式转换的时间。目前已有191人学习下载适合需要快速上手医学细胞检测的深度学习者、研究者及课程项目使用。1. 拿到一份 YOLO 血细胞检测数据集从 1000 张图到能跑的模型中间要过三道关做目标检测的人迟早会遇到一个尴尬开源数据集要么太大跑不动要么领域不对口自己拿 labelimg 从零标注又要耗掉半个月。这份 YOLO 红白细胞血小板检测数据集刚好卡在“能直接上手”的尺寸——1000 张真实场景图红细胞、白细胞、血小板三类目标每张图同时给出 VOCxml、COCOjson、YOLOtxt三种格式标签分别存放在不同文件夹下拿到手不需要再做格式转换。对刚入门 YOLO 的人来说它是零障碍的训练闭环入口对要做医疗图像迁移的熟手它是一个干净的起点可以替换成自己的数据。下面按 格式解析 → 划分脚本 → 环境搭建 → 训练调参 → 排错 → 推理验证 六步走完把脚本里的参数位点和几个容易翻车的坑都放在明处。2. 三种标注格式的底子VOC、COCO、YOLO 的目录结构与选型逻辑2.1 VOC 格式XML 里存的是绝对像素坐标labelimg 的第一站输出用 labelimg 拉框保存时默认写出的就是 Pascal VOC 格式的 XML。这个格式最老牌理解它等于理解了目标检测标注的基本盘一张图片对应一个 XML 文件文件名与图片同名dataset 里一般单独放进 Annotations 目录。核心字段有两块一是size记录图片的宽、高和通道数二是object每个目标一个块里面name是类别名bndbox里是 xmin、ymin、xmax、ymax 四个绝对像素坐标。annotation folderJPEGImages/folder filenameblood_001.jpg/filename size width640/width height480/height depth3/depth /size object nameRBC/name bndbox xmin120/xmin ymin80/ymin xmax170/xmax ymax130/ymax /bndbox /object /annotation这段 XML 的逻辑很简单框的四个坐标都是像素值直接受图片分辨率影响图片缩放后坐标就失效。所以 VOC 格式只适合作为“中间态”给人读、给标注软件读可以喂给 YOLO 训练器之前通常要转成归一化坐标。这个数据集里 XML 存放在 voc 标签目录下文件名和图片一一对应解析的时候按filename去匹配图片比按“同名文件”更稳。2.2 COCO 格式一个大 JSON 装下全部标注类别走 id 索引COCO 是另一个常见分发格式特征是把整份数据集的标注塞进一个 JSON 文件。结构上分成 images、annotations、categories 三大段images 数组记录每张图的 id 和宽高categories 数组定义类别 id 到名称的映射annotations 数组里每条标注通过 image_id 挂到对应图片bbox 给的是[x, y, width, height]的绝对像素值area 是框面积供计算 mAP 时用。{ images: [ {id: 1, file_name: blood_001.jpg, width: 640, height: 480} ], annotations: [ {id: 1, image_id: 1, category_id: 1, bbox: [120.0, 80.0, 50.0, 50.0], area: 2500.0, iscrowd: 0} ], categories: [ {id: 1, name: RBC}, {id: 2, name: WBC}, {id: 3, name: Platelet} ] }注意一个细节COCO 的 bbox 是左上角坐标加宽高不是中心点转换时千万别写成和 YOLO 一样的中心点格式。另外 categories 的 id 从 1 开始而 YOLO 的类别索引从 0 开始两者差 1转格式时最容易在这里翻车。我一般拿到 JSON 后先写三行代码把 categories 打印出来确认 id 和名称的对应关系再去做批量转换。2.3 YOLO 格式每张图一个 txt坐标归一化后直接喂训练器YOLO 系列使用的 txt 标签是最接近训练器的格式每行一个目标五个字段依次是 类别索引、中心点 x、中心点 y、框宽、框高全部归一到 01 之间和图片原始分辨率无关。正因为归一化图片在训练时无论 resize 到 640 还是 1280框都不会错位这是它比 VOC/COCO 更适合做训练格式的根本原因。import xml.etree.ElementTree as ET def voc_to_yolo(xml_path, out_path, class_names): tree ET.parse(xml_path) root tree.getroot() size root.find(size) w int(size.find(width).text) # 注意取的是 int后面做除法 h int(size.find(height).text) lines [] for obj in root.findall(object): name obj.find(name).text if name not in class_names: continue # 过滤掉不想训练的类别 cls_id class_names.index(name) # 字符串转索引顺序必须固定 box obj.find(bndbox) xmin float(box.find(xmin).text) ymin float(box.find(ymin).text) xmax float(box.find(xmax).text) ymax float(box.find(ymax).text) # 核心绝对坐标转相对中心点 相对宽高 x_center (xmin xmax) / 2.0 / w y_center (ymin ymax) / 2.0 / h bw (xmax - xmin) / w bh (ymax - ymin) / h lines.append(f{cls_id} {x_center:.6f} {y_center:.6f} {bw:.6f} {bh:.6f}) with open(out_path, w) as f: f.write(\n.join(lines)) class_names [RBC, WBC, Platelet] voc_to_yolo(Annotations/blood_001.xml, labels/blood_001.txt, class_names)这段转换脚本里最需要盯的是两处一是类别列表 class_names 的顺序必须和训练配置里的 names 完全一致否则框还在、类别全错位这是最坑的“静默错误”二是坐标全部做完归一化再写文件不要混入绝对像素值。YOLO 标签文件命名为“图片同名 .txt”对应图片 blood_001.jpg 就写入 blood_001.txt。这份数据集里 txt 已预先放在 yolo 标签目录你拿到手后建议先随机打开两三个 txt用cat labels/blood_001.txt看一眼前几个数字是否都在 01 区间再做后续操作。三种格式对比如下格式存储单位坐标类型文件组织典型用途VOC(xml)每张图一个 xml绝对像素(xmin,ymin,xmax,ymax)Annotations 目录标注软件、中间交换COCO(json)整个数据集一个 json绝对像素(x,y,w,h)单一 json 文件社区分发、综合评测YOLO(txt)每张图一个 txt归一化(中心点,宽高)labels 目录直接训练3. 划分脚本实操把 1000 张图拆成训练、验证、测试三份注意标签别掉队3.1 三份脚本怎么选按你的训练习惯决定用哪一份资源包里带了三份 Python 脚本和一份 train_list.txt很多人第一次打开会困惑该跑哪个。按我的使用经验三份脚本解决的是三个不同层次的问题训练集、验证集、测试集划分脚本图片标签划分写入新文件夹.py最完整把图片和标签同时搬进 train/val/test 三个新目录跑完直接对着 YOLO 需要的目录结构喂训练。如果你用 YOLOv5/v8 这类仓库选它。训练集、验证集划分脚本图片标签划分写入新文件夹.py只分 train 和 val适用于你已经单独留好测试图、或者只想快速验证训练流程的场景。split_train_val 生成 ImageSets 下 txt 文件划分脚本.py不搬文件只在 ImageSets/Main 下生成 train.txt、val.txt 这样的路径清单适合 VOC 系训练管线或者你不想复制文件、只想记录哪些图入队的情况。train_list.txt 是常见的训练路径清单文件有的训练脚本会按它逐行读取图片路径。它可以是第三份脚本的产物也可以自己手动维护关键在于里面每一行路径对应的标签文件必须真实存在。选择逻辑不复杂新手上路选第一份它帮你把目录树一次建好后续你要反复调划分比例第二份更快如果哪天你想退回 VOC 老式训练管线第三份才用得上。我自己的习惯是先跑第一份看结果稳定后再用第二份做快速迭代。3.2 核心逻辑图片和同名标签必须成对搬进新目录这三份脚本的核心动作都一样把文件名列表打乱按比例切片然后复制文件。最容易出错的地方不是随机而是“只搬了图片、忘了搬标签”或者“搬了 VOC 的 xml 却忘了搬 YOLO 的 txt”。一份正常能用的划分脚本核心应该长这样import os import random import shutil # ---------- 可调参数 ---------- random.seed(42) # 固定随机种子保证每次划分结果一致 train_ratio 0.8 # 训练集比例 val_ratio 0.2 # 验证集比例测试集可自行预留 img_ext .jpg label_ext .txt # 标签后缀YOLO 用 .txtVOC 用 .xml # ---------------------------- img_dir JPEGImages # 原始图片目录 label_dir labels # 原始标签目录 train_img_dir train/images train_label_dir train/labels val_img_dir val/images val_label_dir val/labels for d in [train_img_dir, train_label_dir, val_img_dir, val_label_dir]: os.makedirs(d, exist_okTrue) images [f for f in os.listdir(img_dir) if f.endswith(img_ext)] random.shuffle(images) train_n int(len(images) * train_ratio) train_list images[:train_n] # 前 80% 进训练 val_list images[train_n:] # 后 20% 进验证 def move_pair(img_file, img_out, label_out): 一张图和它的同名标签必须一起搬走 label_file img_file.replace(img_ext, label_ext) label_src os.path.join(label_dir, label_file) if not os.path.exists(label_src): print(f[警告] 标签缺失: {label_file}) return shutil.copy(os.path.join(img_dir, img_file), img_out) shutil.copy(label_src, label_out) for img in train_list: move_pair(img, train_img_dir, train_label_dir) for img in val_list: move_pair(img, val_img_dir, val_label_dir) print(f训练集 {len(train_list)} 张验证集 {len(val_list)} 张)逻辑上值得注意的有三点第一random.seed(42)让随机可复现你跑十次和前一个人跑十次结果完全一致排查问题时不至于“这次缺这张图、下次缺那张”第二move_pair里用replace把图片后缀替换成标签后缀天然保证成对搬运但前提是标签目录里真的存在同名文件所以我加了一层os.path.exists检查并打印警告第三目标目录用makedirs(exist_okTrue)自动创建避免因为目录不存在而中断。如果你用的是 VOC 格式标签把label_ext改成.xml再改一下 label_dir 指向 Annotations 目录即可。三份脚本之间的本质差别就在这里其他逻辑基本是同一套。3.3 参数调整比例、随机种子和类别过滤的位点脚本的参数位点通常就集中在文件开头几十行。训练/验证/测试的比例我一般按 8:1:1 或者 7:2:1 来设1000 张图的话 8:1:1 意味着验证集 100 张、测试集 100 张足够看出模型是否过拟合。比例不是越大越好验证集太小会导致 mAP 波动剧烈本来掉 2 个点可能只是运气问题。随机种子值得单独说它是排查问题的后悔药。有一次我划分完训练发现某张关键图片始终不在训练集里就是因为换了机器、random 状态不同导致划分结果漂移。固定 seed 之后任何复现都有据可查。还有一个隐藏位点是类别过滤。血细胞数据集里三类目标数量是不均匀的血小板通常比白细胞多得多。如果某些脚本内置了按类别数量过滤的功能注意别把它打开否则稀疏类别的样本会被进一步削掉训练出来的模型对白细胞、血小板的召回会非常难看。数据不平衡的问题应该交给训练时的采样策略去解决而不是在划分阶段提前砍数据。提示划分完成之后检查一下 train/labels 和 val/labels 目录里的 txt 数量是否和 images 目录里的 jpg 数量完全一致。数量不一致说明有标签在搬运过程中掉队了先去修这个问题再开训练。4. 训练闭环搭建Linux 和 Windows 环境下的配置、命令与日志解读4.1 环境搭建CUDA、PyTorch 和 YOLO 仓库版本的三角关系资源包里给了 Linux 和 Windows 两套 YOLO 环境搭建教程还有一份 Ubuntu 环境安装教程覆盖了从系统到框架的完整链路。环境搭建真正要处理的是 CUDA、PyTorch、YOLO 仓库三者之间的版本配对问题。常见做法是先确定 YOLO 版本再往上选 PyTorch最后反推 CUDA 版本。比如用 YOLOv5 的 v6.0 以上版本搭配 PyTorch 1.13 或 2.xCUDA 11.7 到 12.1 都在安全区间如果换 YOLOv8直接跟官方要求的 PyTorch 版本走。Linux 下的搭建和 Windows 下最大的区别在驱动层Linux 要装 NVIDIA 驱动再配 CUDA toolkitWindows 通常只需要在显卡官网装一个带 CUDA 的驱动然后 pip 装 torch 即可。教程里给的顺序一般先是显卡驱动再是验证nvidia-smi能看到驱动版本接着装 PyTorch最后 clone YOLO 仓库装依赖。# Linux 下最常见的安装顺序 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 git clone https://github.com/ultralytics/yolov5 cd yolov5 pip install -r requirements.txt python -c import torch; print(torch.cuda.is_available())这段命令的含义是第一行指定了 CUDA 11.8 对应的 PyTorch 预编译包不要图省事用默认源装 CPU 版第二、三行把 YOLO 仓库和依赖拉齐最后一行验证 GPU 是否真的被 PyTorch 识别。torch.cuda.is_available()返回 True 才说明环境搭通了返回 False 的话后面训练会全程跑 CPU1000 张图可能要跑到天荒地老。Windows 上的差别只是把 pip 命令放到 CMD 或 PowerShell 里执行教程里通常还会补一步设置环境变量的操作。4.2 把数据集改成 YOLO 训练结构data.yaml 与目录布局环境就绪后要把划分好的数据组织成 YOLO 承认的结构。这步是整个流程里最容易被忽略的“软性配置”——目录不对训练器会报各种看不懂的警告类别数不对训练直接崩。YOLOv5 和 YOLOv8 都认这样的结构dataset/ ├── train/ │ ├── images/ │ └── labels/ ├── val/ │ ├── images/ │ └── labels/ └── data.yaml对应的 data.yaml 内容如下train: ./dataset/train/images val: ./dataset/val/images nc: 3 names: [RBC, WBC, Platelet]train和val指向图片目录训练器会自动到同级的 labels 目录找同名 txtnc是类别数必须和 names 列表长度一致。这里有个很隐蔽的坑如果图片目录叫 images、标签目录叫 labelsYOLO 会默认找images的同级labels。你要是把标签目录改名叫别的训练器就会一路 Warning “label file not found”。4.3 训练启动、参数位点和损失日志里该看的东西data.yaml 配好训练命令就极短。YOLOv5 和 YOLOv8 的区别只在于入口脚本名一个是 train.py一个是 yolo train参数逻辑几乎通用python train.py --data data.yaml --weights yolov5s.pt --epochs 100 --batch-size 16 --imgsz 640各参数的调整逻辑weights选 yolov5s.pt 是速度和精度的平衡点1000 张图的小数据集用不上大模型yolov5m 以上纯属浪费显存batch-size取决于显卡8G 显存跑 16 没压力跑不动就降到 8imgsz用 640 是通用默认。血细胞目标比较小如果 val mAP 上不去可以试试把 imgsz 提到 960代价是显存占用和训练时间同步上升。训练开始后日志里每轮输出的box_loss、obj_loss、cls_loss不用每行都看,只需要盯整体趋势前三四十轮损失掉得很快是正常的后面进入平台期也正常。真正要警惕的是验证集 mAP 出现过山车比如第 60 轮 0.92、第 61 轮掉到 0.8 又弹回来这种波动通常说明验证集太小或者验证集里包含了几张标注质量差的图。我在这个数据集上跑的时候默认参数到 100 轮左右 box_loss 会收敛到 0.02 附近val mAP 能到 0.9 以上属正常水平。注意前几次训练别开--cache参数。这个参数会把图片预加载到内存能提速但也可能直接把内存吃满机器当场卡死。先裸跑通一次流程再决定要不要缓存。5. 常见问题排查标注、路径与显存相关的五个高频坑5.1 现象训练启动后立刻报错 “class index out of range”原因标签 txt 里出现了大于等于 nc 的类别索引。比如 data.yaml 里写了 nc3索引 0、1、2但某个 txt 里写的是 3 或 4。多半是 VOC 转 YOLO 时类别的 id 从 1 开始计数转完忘了减一或者混入了别的数据集的标签。解决写一个扫描脚本遍历所有 txt把每一行的第一个数字最大值打印出来和 nc 比对。我习惯直接awk {print $1} labels/*.txt | sort -n | tail -1看一眼最大值大于等于 nc 就把对应文件揪出来手动修。5.2 现象训练过程中刷屏 Warning “label file missing”但不报错原因训练器找不到标签文件它默认按“图片路径同级目录下的 labels 文件夹”去找同名 txt。多数情况是目录结构没对齐比如图片在 train/images标签却放在 dataset/labels 而不是 train/labels。这种情况训练器不会崩它会直接跳过所有找不到标签的图片结果就是模型啥也没学到mAP 一直为 0。解决先核对目录结构确认图片和标签的目录层级完全符合 YOLO 约定再用 find 命令统计两边文件数量是否一致find train/images -name *.jpg | wc -l和find train/labels -name *.txt | wc -l数量对不上就是搬丢了。5.3 现象训练一两轮后显存溢出报 CUDA out of memory原因batch-size 或 imgsz 超出显卡容量或者是--cache把显存和内存同时吃爆。血细胞数据集虽然只有 1000 张但 16 batch、640 分辨率在 6G 显存的卡上已经接近极限。解决batch-size 从 16 降到 8imgsz 保持 640 不动两个参数二选一降即可。还有个更省显存的办法是开--noval训练过程中不做每轮验证只在最后验证一次能省出不少显存给训练本身。5.4 现象训练正常结束但 val mAP 打印出来一直是 0原因验证集里的图片和训练集高度重合或者验证集标签全部为空。重合的情况多半是划分脚本的随机种子没生效导致训练和验证数据重叠标签为空则是划分时只搬了图片或者这张图本来就是背景图没有目标。解决先跑一遍划分脚本并固定 seed确认 train 和 val 的图片文件名没有任何交集再检查 val/labels 下的 txt 是否有非空内容一条find val/labels -size 0 -name *.txt就能把所有空标签列出来。背景图如果占比小直接从数据里删掉最省事。5.5 现象Windows 下图片路径带中文或空格训练报错路径不存在原因Windows 的路径分隔符和中文字符容易在 YOLO 的路径解析里出问题尤其数据集放在C:\用户\张三\数据集\这种路径下时txt 标签里如果也写了中文路径解析时大概率翻车。解决数据集目录统一用英文小写命名比如D:/blood_dataset/并且强烈建议把整份数据放在盘符根目录下一层避免中间夹带中文目录。这是 Windows 下跑 YOLO 最常见的血泪坑教程里一般也会特别注明。Linux 下则要注意不要用用户名里带中文的路径比如/home/张三/同样会出类似问题。6. 推理验证与模型导出让训练结果真正落地的一个完整动作训练跑完只是第一步权重能不能用最终要看推理。先用测试图片跑一遍 detect确认三类目标都能被圈出来再考虑导出部署格式。python detect.py --weights runs/train/exp/weights/best.pt --source ./test_images --conf-thres 0.5这条命令把训练产出的 best.pt 对 test_images 目录里的图片做推理conf-thres 0.5是置信度阈值低于 0.5 的框不会画出来。第一次跑建议把阈值放低到 0.25先把所有可能的目标都画出来看看确认标注框基本贴合细胞轮廓再调回 0.5 做正式验证。如果发现某一类目标几乎检测不到回查训练日志里该类别的 cls_loss 是不是一直没降下来。接下来是导出 ONNX。很多人以为训练完就结束了实际上随手导出一次 ONNX 是性价比极高的验证手段——它能暴露模型结构与推理框架不匹配的问题也为后续用 TensorRT、OpenVINO 加速部署铺路。YOLOv5 的导出命令很短python export.py --weights runs/train/exp/weights/best.pt --include onnx --imgsz 640导出成功后目录会多一个 best.onnx。用onnxruntime加载它跑一次推理如果结果和 PyTorch 推理差值在可接受范围说明整个链路是通的。从那以后我每次拿到新数据集都强制走一遍“格式校验 → 划分 → 训练 → 推理复测 → ONNX 导出”这五步缺一步都不敢放心用。这份数据集的好处是前三步它已经帮你搭好了剩下两步入门教程里也写了怎么改自己的数据。希望帮到你。本文还有配套的精品资源点击获取