人脑肿瘤检测数据集:5000张CT图三格式标注与YOLO11训练实战

📅 发布时间:2026/9/29 11:12:37
人脑肿瘤检测数据集:5000张CT图三格式标注与YOLO11训练实战
简介这份资源面向医学影像分析与目标检测方向的开发者、研究生及算法工程师提供真实CT场景下的人脑肿瘤检测数据集可用于肿瘤检测项目训练也可作为通用人脑检测数据的补充。数据集共5000张高质量图片采用labelimg标注同时提供VOCxml、COCOjson、YOLOtxt三种主流格式标签可直接接入YOLO等检测算法。资源包为1个PDF文件大小约2.26MB因原始数据体量较大PDF内附数据集基本情况介绍与百度网盘获取方式。随附YOLO11一键训练脚本覆盖GPU、CPU及MacM芯片三平台方案并给出博主训练结果日志供参考便于快速复现与调参。目前已有401人学习适合希望低成本获取医学影像标注数据、快速验证检测模型的中高级读者。1. 人脑肿瘤检测数据集5000 张 CT 图配齐 VOC/COCO/YOLO 三格式值不值得下做医学影像目标检测的同行大概都有过这种体验模型结构调了半天loss 曲线也好看一到自己标注的数据上就翻车——不是框歪了就是漏检回头一查标注规范不统一、格式转换丢坐标。所以当我看到这份「人脑肿瘤检测数据集」时第一反应不是看它有多少张图而是看它的标注链路是否干净。这份资源给的是 5000 张真实 CT 场景图片用 labelimg 标注同时提供 VOC(xml)、COCO(json)、YOLO(txt) 三种格式标签还附了数据集划分脚本和 YOLO11 一键训练脚本覆盖 GPU、CPU、Mac(M 芯片) 三平台。它解决的核心问题很明确让你跳过「找数据—标注—转格式—写训练脚本」这条最耗时的前置链路直接把精力放在模型和调参上。适合做医学影像检测的算法工程师、赶毕设的学生以及想拿真实 CT 数据验证 YOLO 系列改进效果的人。下面我按「这份资源是什么—怎么跑起来—坑在哪」的顺序拆一遍。2. 三种标签格式的差异与选型为什么同一批图要存三份拿到数据集先别急着训练得搞清楚 VOC、COCO、YOLO 三种格式到底差在哪否则后面转换和评估环节会莫名其妙报错。这三种格式本质上是同一批标注框的三种「方言」坐标表达和文件组织方式不同选错了轻则训练脚本读不进去重则框位置整体偏移。2.1 坐标表达绝对像素 vs 归一化VOC 的 xml 里bndbox存的是xmin/ymin/xmax/ymax四个绝对像素值原点在左上角。COCO 的 json 里bbox存的是[x, y, width, height]同样是绝对像素但注意它是左上角坐标加宽高不是右下角。YOLO 的 txt 则是归一化的class x_center y_center width height全部除以图片宽高取值 0~1。这个差异直接决定了你换格式时要不要重算。常见做法是训练 YOLO 系列用 txt做 COCO 评估比如 pycocotools 算 mAP用 json而很多老的可视化脚本和标注工具只认 xml。这份资源三种都给省去了自己写转换脚本的麻烦但你要清楚每种格式对应哪个环节。格式坐标类型单文件组织典型用途VOC绝对像素 xmin/ymin/xmax/ymax每图一个 xmllabelimg 原生、可视化脚本COCO绝对像素 x/y/w/h全量一个 jsonpycocotools 评估、多任务YOLO归一化中心点宽高每图一个 txtYOLO 系列训练2.2 类别映射别让 class id 对不上VOC 的 xml 里类别是字符串名字COCO 的 json 里categories是 id 加 name 的映射YOLO 的 txt 里直接是数字 class id。三者之间最容易出问题的就是类别顺序。比如你训练时data.yaml里写的names: [tumor]但转换出来的 txt 里肿瘤被标成了 1背景被当成 0模型就会学歪。我一般会先跑一段脚本把三种格式的类别统计出来对齐确认没有错位再开训。这份资源标注质量高但你自己接手的项目里类别映射这一步永远要手动核一遍这是血泪经验。2.3 划分脚本train/val/test 不能随手切数据集划分脚本是这份资源里容易被忽略但很关键的一环。医学影像数据如果按随机切分可能出现同一病人的切片同时出现在训练集和验证集里导致验证指标虚高。常见做法是按病人 ID 或扫描批次做分组划分保证验证集和训练集不共享同一来源。资源里附带的划分脚本我建议你先看它是不是按文件名前缀分组。如果是纯随机自己改成按前缀分组更稳妥。划分比例一般 7:2:1 或 8:1:1小数据集可以 8:2但 test 集最好留出来别拿验证集当测试集用。import os import random from collections import defaultdict # 按文件名前缀分组避免同一来源切片跨集 def split_dataset(img_dir, out_txt, ratios(0.7, 0.2, 0.1)): groups defaultdict(list) for f in os.listdir(img_dir): if f.lower().endswith((.jpg, .png, .jpeg)): # 假设文件名前缀是病人/批次标识按实际规则调整 prefix f.split(_)[0] groups[prefix].append(f) keys list(groups.keys()) random.shuffle(keys) n len(keys) n_train int(n * ratios[0]) n_val int(n * ratios[1]) train_keys keys[:n_train] val_keys keys[n_train:n_train n_val] test_keys keys[n_train n_val:] with open(out_txt, w) as fw: for k in train_keys: for img in groups[k]: fw.write(ftrain/{img}\n) for k in val_keys: for img in groups[k]: fw.write(fval/{img}\n) for k in test_keys: for img in groups[k]: fw.write(ftest/{img}\n) split_dataset(./images, ./split.txt)这段脚本的逻辑是先按前缀把图片分组再对组做随机打乱和切分最后把每个组内的图片整体分配到 train/val/test。参数ratios控制三集比例prefix的切法要根据你实际文件名规则改。跑完检查一下split.txt里三集数量是否符合预期别出现某一集为空的情况。3. YOLO11 一键训练脚本落地三平台参数怎么设资源附的是 YOLO11 一键训练脚本支持 GPU、CPU、Mac(M 芯片) 三平台。这一章把脚本拆开讲清楚每个参数的含义以及不同平台下该怎么改避免你直接python train.py一把梭然后卡在环境或显存上。3.1 环境准备与依赖安装YOLO11 一般走 ultralytics 这个库。GPU 平台先确认 CUDA 和 PyTorch 版本匹配Mac 平台走 MPS 后端CPU 平台就是纯 torch CPU 版。常见做法是建独立虚拟环境别在 base 环境里装否则版本冲突排查起来很痛苦。# 创建虚拟环境 python -m venv yolo11_env source yolo11_env/bin/activate # Windows 用 yolo11_env\Scripts\activate # 安装 PyTorch按平台选 # GPU (CUDA 12.1 示例) pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121 # Mac M 芯片 pip install torch torchvision # CPU pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu # 安装 ultralytics pip install ultralytics安装完跑一句python -c import torch; print(torch.cuda.is_available())验证 GPU 是否可用。Mac 平台看torch.backends.mps.is_available()。这一步没过后面训练全是白搭。3.2 data.yaml 配置路径和类别名YOLO 训练靠data.yaml告诉它数据在哪、有几类。这份资源三种格式都有训练时用 YOLO 格式的 txt 标签data.yaml里指向对应的 images 和 labels 目录。# data.yaml path: ./brain_tumor_dataset # 数据集根目录 train: images/train # 训练集图片相对路径 val: images/val test: images/test nc: 1 # 类别数按实际标注调整 names: [tumor] # 类别名顺序必须和 txt 里的 class id 一致nc和names是最容易出错的地方。如果你拿到的 txt 里 class id 有 0 和 1 两个值但nc写了 1训练会直接报索引越界。先统计一遍所有 txt 里的最大 class id再决定nc。3.3 训练命令与关键参数一键脚本的核心就是一行 ultralytics 的 train 调用但参数怎么设决定了你能不能跑完、跑得好。from ultralytics import YOLO # 加载预训练权重没有就写 yolo11n.yaml 从零训 model YOLO(yolo11n.pt) results model.train( datadata.yaml, epochs100, # 医学数据一般 100~300看收敛情况 imgsz640, # CT 图分辨率高可试 1024但显存吃紧 batch16, # GPU 显存小就降到 8 或 4 device0, # GPU 填 0CPU 填 cpuMac 填 mps workers4, # 数据加载线程Windows 下建议 0 避免卡死 patience20, # 20 轮无提升就早停 projectruns/train, namebrain_tumor )参数说明epochs是训练轮数医学影像数据量不大时容易过拟合配合patience早停更稳。imgsz是输入尺寸CT 图细节多640 可能丢小肿瘤显存够就上 1024。batch和device是平台差异最大的两个GPU 显存 8G 以下建议 batch 8Mac M 芯片走mps但速度比 GPU 慢不少CPU 训练只适合小规模验证。workers在 Windows 上设 0 能避免多进程数据加载卡死这是踩过的坑。3.4 训练日志怎么看资源里附了博主的训练结果日志参考价值在于看 loss 曲线和 mAP 走势是否正常。重点看三个指标box_loss是否稳定下降、mAP50是否在涨、cls_loss有没有震荡。如果 box_loss 降但 mAP 不涨多半是标注框和类别有问题如果 loss 直接 NaN检查学习率或数据里有没有空标签文件。4. 从 VOC/COCO 转 YOLO转换脚本与坐标校验虽然资源三种格式都给了但实际项目里你经常需要自己转——比如拿到一批只有 xml 的补充数据或者要把 COCO 的 json 拆成 YOLO 的 txt。这一章给一套可复用的转换脚本并讲清楚转换后怎么校验避免框整体偏移这种玄学问题。4.1 VOC xml 转 YOLO txtVOC 转 YOLO 的核心是把绝对像素的 xmin/ymin/xmax/ymax 转成归一化的中心点和宽高。注意 xml 里图片宽高要从size节点读不能想当然用固定值。import os import xml.etree.ElementTree as ET def voc_to_yolo(xml_dir, out_dir, classes): os.makedirs(out_dir, exist_okTrue) for xml_file in os.listdir(xml_dir): if not xml_file.endswith(.xml): continue tree ET.parse(os.path.join(xml_dir, xml_file)) root tree.getroot() size root.find(size) w int(size.find(width).text) h int(size.find(height).text) lines [] for obj in root.iter(object): cls obj.find(name).text if cls not in classes: continue cls_id classes.index(cls) 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) # 归一化中心点和宽高 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}) out_path os.path.join(out_dir, xml_file.replace(.xml, .txt)) with open(out_path, w) as f: f.write(\n.join(lines)) voc_to_yolo(./annotations, ./labels, [tumor])逻辑说明遍历 xml读图片宽高对每个 object 算归一化坐标。classes列表的顺序决定 class id必须和data.yaml里的names一致。坐标保留 6 位小数足够YOLO 读取时会自己解析。转换完一定要抽查几张用可视化脚本把框画回原图上看是否对齐。4.2 COCO json 转 YOLO txtCOCO 的 json 是单文件全量标注转换时要先建 image_id 到文件名的映射再按 image_id 分组写 txt。import json import os def coco_to_yolo(json_path, out_dir, classes): os.makedirs(out_dir, exist_okTrue) with open(json_path, r) as f: data json.load(f) # image_id - (file_name, width, height) img_info {img[id]: img for img in data[images]} # 按 image_id 收集标注 anns {} for ann in data[annotations]: anns.setdefault(ann[image_id], []).append(ann) for img_id, img in img_info.items(): w, h img[width], img[height] lines [] for ann in anns.get(img_id, []): cls_id ann[category_id] - 1 # COCO 类别从 1 开始YOLO 从 0 x, y, bw, bh ann[bbox] x_center (x bw / 2) / w y_center (y bh / 2) / h lines.append(f{cls_id} {x_center:.6f} {y_center:.6f} {bw/w:.6f} {bh/h:.6f}) name os.path.splitext(img[file_name])[0] .txt with open(os.path.join(out_dir, name), w) as f: f.write(\n.join(lines)) coco_to_yolo(./annotations.json, ./labels, [tumor])关键点在category_id - 1COCO 的类别 id 通常从 1 开始YOLO 从 0 开始不减这一下类别全错位。另外 COCO 的 bbox 是左上角加宽高算中心点要加半个宽高别直接拿 x 当中心。4.3 转换后的校验方法转换脚本跑完不代表万事大吉。我一般做两步校验一是统计每个 txt 的框数量和对应 xml/json 是否一致二是随机抽 10 张用可视化脚本画框。框偏移最常见的原因是图片宽高读错比如 xml 里 size 写的是缩放后尺寸但实际图片是原图这种只能靠可视化发现。5. 避坑与排查训练不收敛、显存爆、Mac 报错的真实记录这一章集中写我在跑这类医学检测数据集时踩过的坑每条按现象、原因、解决来你对照自己的报错看。5.1 训练 loss 不降mAP 一直是 0现象训练跑起来了box_loss 在动但 mAP50 始终为 0验证集预测全是背景。原因最常见的是data.yaml里names顺序和 txt 里 class id 对不上或者 txt 文件路径没被正确索引到模型读到的全是空标签。解决先跑一遍统计脚本确认每个 txt 非空且 class id 在nc范围内再检查data.yaml的train路径是相对path还是绝对路径ultralytics 对路径拼接比较敏感建议直接写绝对路径试一次。5.2 GPU 显存爆batch 降到 1 还 OOM现象CUDA out of memory把 batch 降到 1 依然报错。原因多半是imgsz设太大或者workers开太多导致数据加载占用显存也可能是没加载预训练权重从零训梯度占用更高。解决先把imgsz从 1024 降到 640workers设 2 或 0确认model YOLO(yolo11n.pt)用的是预训练权重而不是 yaml。还不行就换更小的模型变体n 换 s 再换 m别硬上大模型。5.3 Mac M 芯片跑 mps 报错或速度极慢现象devicemps报算子不支持或者能跑但一个 epoch 要几十分钟。原因MPS 后端对部分算子的支持还不完整YOLO11 某些层会回退到 CPU速度骤降。解决先升级 torch 到较新版本MPS 支持在持续完善如果还报错把device改成cpu跑小规模验证正式训练换 GPU 机器。Mac 适合调试流程不适合大规模训练这是硬件边界别跟它较劲。5.4 验证集指标虚高测试集一塌糊涂现象val 的 mAP 很高换 test 集掉一大截。原因划分时同一病人的切片跨了 train 和 val模型见过相似图像。解决回到第 2 章的划分脚本按病人或批次前缀分组切分保证 val/test 和 train 不共享来源。医学影像里这个坑特别隐蔽因为切片之间肉眼看着不一样但模型能学到泄漏特征。5.5 标注框有负坐标或超出图片范围现象转换后的 txt 里出现负数或大于 1 的坐标训练时报 assert 错误。原因原始 xml 里标注框画到了图片边界外或者图片宽高读的是缩放尺寸。解决转换脚本里加一层 clamp把坐标限制在 0~1同时打印出被裁剪的框数量数量多说明标注或尺寸读取有问题要回头查源数据。6. 进阶技巧用混淆矩阵和 PR 曲线定位漏检把 mAP 再抬一档训练跑通只是起点真正决定这份数据集能不能用在项目里的是你能不能从评估结果里定位问题。YOLO11 训练完会在runs/train/下生成混淆矩阵和 PR 曲线这两个图比 mAP 一个数字信息量大得多。先看混淆矩阵。医学肿瘤检测通常只有一类矩阵是 2x2背景 肿瘤。如果背景被大量预测成肿瘤说明假阳性高可能是标注里把正常组织也框进去了或者模型对纹理敏感如果肿瘤被预测成背景就是漏检常见于小目标得考虑提高imgsz或加数据增强。我一般会把混淆矩阵和验证集的预测可视化对照看找出具体是哪几张图在错。再看 PR 曲线。曲线下的面积就是 mAP但曲线形状告诉你更多如果曲线在高召回区急剧下降说明模型为了多召回牺牲了大量精度这时候调低置信度阈值没用得从数据或模型容量入手如果曲线整体偏低但平缓可能是类别定义模糊标注一致性不够。一个具体技巧是把验证集里置信度在 0.25~0.5 之间的预测单独导出人工看一遍。这批「模棱两可」的框往往暴露了标注边界问题——比如肿瘤边缘到底框到哪不同标注员标准不一致。把这些问题框修正后重训mAP 通常能涨几个点比调参来得实在。from ultralytics import YOLO model YOLO(runs/train/brain_tumor/weights/best.pt) # 导出验证集预测conf 设低一点捞回模糊框 results model.predict( source./images/val, conf0.25, save_txtTrue, save_confTrue, projectruns/predict, nameval_check )这段预测脚本把验证集每张图的预测框和置信度存成 txtconf0.25是故意放低阈值把模型不确定的框也捞出来。跑完对照原图看那些低置信框判断是标注漏了还是模型误报。这个习惯我从做第一个检测项目保持到现在每次训完新数据都强制走一遍比盯着 mAP 数字干着急有用得多。医学影像检测和通用目标检测最大的区别在于容错率低一个漏检可能意味着实际场景里的误判。所以别只追求 mAP 好看把混淆矩阵、PR 曲线和低置信预测三样结合起来看才能知道模型到底学到了什么。这份数据集标注质量不错三种格式也省了转换的麻烦但最终效果还是取决于你怎么用它。希望帮到你。本文还有配套的精品资源点击获取