MMSegmentation 医学影像分割实战:GAMMA 挑战赛 Task3 视盘与视杯分割项目(Gamma3)全解析
2026/9/16 16:21:48 网站建设 项目流程

MMSegmentation 医学影像分割实战:GAMMA 挑战赛 Task3 视盘与视杯分割项目(Gamma3)全解析

【免费下载链接】mmsegmentationOpenMMLab Semantic Segmentation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmsegmentation

导读

本篇文章以 MMSegmentation 开源仓库中的projects/medical/2d_image/fundus_photography/gamma3项目为主体,系统讲解如何在 OpenMMLab 生态下复现GAMMA 挑战赛(Glaucoma grAding from Multi-Modality imAges)Task3——青光眼视盘(optic disc)与视杯(optic cup)分割任务。读完本文,你将掌握:Gamma3 眼底彩照数据集的结构与类别分布、数据预处理与训练/验证集切分的完整流程、基于 UNet + FCN 头的端到端训练/测试配置解析,以及通过mim一条命令完成训练与评测的具体操作方法。

项目背景:GAMMA 挑战赛 Task3 是什么

该项目对应的英文全称为"Glaucoma grAding from Multi-Modality imAges Task3",是 GAMMA 挑战赛中的常规赛任务之一,其核心任务是基于眼底彩照(fundus photography)完成视盘(optic disc)与视杯(optic cup)的语义分割。视盘与视杯的形态比例(杯盘比,CDR)是临床诊断青光眼的关键量化指标,因此该分割任务对青光眼的自动化筛查具有直接意义。

数据集由位于中国广州的**中山大学中山眼科中心(Sun Yat-sen Ophthalmic Center, Sun Yat-sen University)**提供。官方训练集与测试集各包含100 对眼底彩照与其对应的分割标注,共 200 张眼底彩照。官方数据集可从 GAMMA 挑战赛官方网站(百度 AI Studio 竞赛页面)下载。

官方数据集统计信息

数据集名称解剖区域任务类型模态类别数训练/验证/测试图像训练/验证/测试标注发布时间许可
GammaTask3眼(eye)语义分割眼底彩照(fundus photography)3100 / - / 100有 / - / -2021CC-BY-NC 4.0

任务为3 分类语义分割,类别包括背景(background)、视盘(optic disc)与视杯(optic cup)。官方训练集的像素级类别分布如下:

类别名称训练集数量训练集像素占比(Pct)验证集数量测试集数量
background(背景)10099.02--
optic disc(视盘)1000.67--
optic cup(视杯)1000.31--

注:Pct表示该类像素占全部像素的百分比。从表中可以清晰看到,视盘与视杯在整幅眼底图像中仅占不足 1% 的像素,属于典型的小目标、类别极不均衡的医学分割问题,这也对分割模型的细节表征能力提出了较高要求。

环境依赖与项目前提

根据项目 README,复现该项目需要以下软件环境(以仓库记录为准):

  • Python v3.8
  • PyTorch v1.10.0
  • pillow(PIL)v9.3.0
  • scikit-learn(sklearn)v1.2.0(用于数据集切分)
  • MIM v0.3.4(OpenMMLab 模型管理工具)
  • MMCV v2.0.0rc4
  • MMEngine v0.2.0 或更高版本
  • MMSegmentation v1.0.0rc5

所有下述命令都依赖PYTHONPATH的正确配置,使其指向项目目录,以便 Python 能够定位到模块文件。在gamma3/根目录下执行以下命令,将当前目录加入PYTHONPATH

export PYTHONPATH=`pwd`:$PYTHONPATH

数据集准备:从官方原始数据到 MMSegmentation 标准目录

第一步:下载并解压官方数据

从 GAMMA 挑战赛官方页面下载数据集,并解压到data/目录。官方原始数据的内部目录结构为(对应 prepare_dataset.py 中的硬编码路径):

data/ └── task3_disc_cup_segmentation/ ├── training/ │ ├── fundus color images/ # 训练集眼底彩照(.jpg) │ └── Disc_Cup_Mask/ # 训练集视盘视杯掩膜(.png) └── testing/ └── fundus color images/ # 测试集眼底彩照(.jpg)

第二步:运行数据预处理脚本

gamma3目录下执行:

python tools/prepare_dataset.py

该脚本完成两类核心工作:

  1. 格式统一:将训练/测试眼底彩照从.jpg统一转换为.png,并分别归档到data/images/train/data/images/test/;将训练掩膜复制到data/masks/train/
  2. 标签重映射:官方掩膜中使用的原始灰度值为[0, 128, 255],分别对应['optic cup', 'optic disc', 'background'];脚本通过convert_dict = {0: 2, 128: 1, 255: 0}将其转换为 MMSegmentation 约定的连续类别编号[0, 1, 2],分别对应['background', 'optic disc', 'optic cup']

对应源码片段(prepare_dataset.py):

def convert_label_pics_into_pngs(src_dir, tgt_dir, suffix, convert_dict={ 0: 2, 128: 1, 255: 0 }): ... # original: [0, 128, 255] for ['optic cup', 'optic disc', 'background'] # converted: [0, 1, 2] for ['background', 'optic disc', 'optic cup']

第三步:切分数据集并生成标注文件

python ../../tools/split_seg_dataset.py

注意,该切分脚本并不位于gamma3目录内,而是位于医学影像项目共用的 projects/medical/2d_image/tools/split_seg_dataset.py。脚本逻辑如下:

  • 若存在data/masks/valdata/masks/test,则直接基于官方划分生成对应的val.txt/test.txt
  • 若官方验证集与测试集的标注无法获取(本项目即属此情形,官方仅公开训练集标注),脚本会调用sklearn.model_selection.train_test_split,以test_size=0.2random_state=0从训练集中随机切分出 80% 作为训练集、20% 作为验证集,并分别生成train.txtval.txt

切分完成后,目录结构如下:

mmsegmentation ├── mmseg ├── projects │ ├── medical │ │ ├── 2d_image │ │ │ ├── fundus_photography │ │ │ │ ├── gamma3 │ │ │ │ │ ├── configs │ │ │ │ │ ├── datasets │ │ │ │ │ ├── tools │ │ │ │ │ ├── data │ │ │ │ │ │ ├── train.txt │ │ │ │ │ │ ├── val.txt │ │ │ │ │ │ ├── images │ │ │ │ │ │ │ ├── train │ │ │ │ │ │ │ │ ├── xxx.png │ │ │ │ │ │ │ │ ├── ... │ │ │ │ │ │ │ │ └── xxx.png │ │ │ │ │ │ │ ├── test │ │ │ │ │ │ │ │ ├── yyy.png │ │ │ │ │ │ │ │ ├── ... │ │ │ │ │ │ │ │ └── yyy.png │ │ │ │ │ │ ├── masks │ │ │ │ │ │ │ ├── train │ │ │ │ │ │ │ │ ├── xxx.png │ │ │ │ │ │ │ │ ├── ... │ │ │ │ │ │ │ │ └── xxx.png

自切分后的数据集统计

由于官方验证集/测试集标注不可用,本项目自行从训练集随机切分,切分后的分布如下:

类别名称训练集数量训练集像素占比(Pct)验证集数量验证集像素占比(Pct)测试集数量
background(背景)8099.012099.07-
optic disc(视盘)800.68200.63-
optic cup(视杯)800.32200.31-

可以看到,自切分后训练/验证集的类别占比与官方训练集基本一致,保持了类别不均衡的原始特性。

数据集类实现:Gamma3Dataset

本项目通过 MMSegmentation 的注册机制实现了自定义数据集类 Gamma3Dataset,核心源码如下:

from mmseg.datasets import BaseSegDataset from mmseg.registry import DATASETS @DATASETS.register_module() class Gamma3Dataset(BaseSegDataset): """Gamma3Dataset dataset. In segmentation map annotation for Gamma3Dataset, ``reduce_zero_label`` is fixed to False. The ``img_suffix`` is fixed to '.png' and ``seg_map_suffix`` is fixed to '.png'. """ METAINFO = dict(classes=('background', 'disc', 'cup')) def __init__(self, img_suffix='.png', seg_map_suffix='.png', reduce_zero_label=False, **kwargs) -> None: super().__init__( img_suffix=img_suffix, seg_map_suffix=seg_map_suffix, reduce_zero_label=reduce_zero_label, **kwargs)

关键实现细节:

  • METAINFO声明了 3 个类别('background', 'disc', 'cup'),与预处理脚本转换后的标签编号一一对应;
  • img_suffixseg_map_suffix均固定为.png,即输入图像与分割掩膜统一使用 PNG 格式;
  • reduce_zero_label=False,即标签 0(背景)作为正常类别参与训练与评估,不会被剔除。这一设置在医学分割场景下通常是合理的,因为背景像素占比虽高,但仍是语义类别的一部分。

在配置文件中,通过custom_imports = dict(imports='datasets.gamma3_dataset')引入该自定义数据集模块,并在dataset_type = 'Gamma3Dataset'中直接引用。

配置文件逐项解析

数据集与数据流水线配置:gamma3_512x512.py

该文件是 Gamma3 任务的数据与评测公共配置,要点如下:

dataset_type = 'Gamma3Dataset' data_root = 'data/' img_scale = (512, 512)

训练数据流水线(train_pipeline)

变换参数作用
LoadImageFromFile-读取眼底彩照
LoadAnnotations-读取分割掩膜
Resizescale=(512, 512), keep_ratio=False强制缩放到 512×512,不保持宽高比
RandomFlipprob=0.550% 概率水平随机翻转,进行数据增强
PhotoMetricDistortion-亮度/对比度/饱和度/色调等光度扰动增强
PackSegInputs-将图像与标注打包为模型输入格式

测试数据流水线(test_pipeline)仅包含LoadImageFromFileResizeLoadAnnotationsPackSegInputs,不包含任何随机增强,保证评测结果可复现。

Dataloader 与评测器配置

  • 训练:batch_size=16num_workers=4InfiniteSampler(shuffle=True)(配合 20k 迭代式训练);
  • 验证/测试:batch_size=1DefaultSampler(shuffle=False)
  • 评测指标:IoUMetric,同时计算mIoUmDice两个指标,兼顾像素级交并比与区域重叠度的评估。

模型骨架:UNet + FCN 解码头

三个训练配置均继承自基础模型配置 fcn_unet_s5-d16.py,其结构为:

  • 骨干网络UNet:输入通道 3(RGB 眼底彩照),base_channels=64,5 个编码阶段(num_stages=5),每阶段 2 个卷积,下采样 4 次(downsamples=(True, True, True, True)),上采样使用InterpConv
  • 解码头FCNHeadin_channels=64in_index=4,输出通道数默认为 2(在 Gamma3 配置中被覆盖为 3),损失函数为CrossEntropyLoss
  • 默认的测试模式为slide(滑窗,crop_size=256、stride=170),在 Gamma3 配置中被覆盖为whole(整图推理)。

三个训练配置:学习率消融实验

configs目录下提供了三个仅学习率不同的训练配置,构成了一个直观的学习率消融实验:

配置文件优化器学习率
fcn-unet-s5-d16_unet_1xb16-0.0001-20k_gamma3-512x512.py0.0001
fcn-unet-s5-d16_unet_1xb16-0.001-20k_gamma3-512x512.py0.001
fcn-unet-s5-d16_unet_1xb16-0.01-20k_gamma3-512x512.py0.01

以学习率为 0.001 的配置为例,完整配置如下(fcn-unet-s5-d16_unet_1xb16-0.001-20k_gamma3-512x512.py):

_base_ = [ 'mmseg::_base_/models/fcn_unet_s5-d16.py', './gamma3_512x512.py', 'mmseg::_base_/default_runtime.py', 'mmseg::_base_/schedules/schedule_20k.py' ] custom_imports = dict(imports='datasets.gamma3_dataset') img_scale = (512, 512) data_preprocessor = dict(size=img_scale) optimizer = dict(lr=0.001) optim_wrapper = dict(optimizer=optimizer) model = dict( data_preprocessor=data_preprocessor, decode_head=dict(num_classes=3), auxiliary_head=None, test_cfg=dict(mode='whole', _delete_=True)) vis_backends = None visualizer = dict(vis_backends=vis_backends)

逐项说明:

  • _base_继承链mmseg::_base_/models/fcn_unet_s5-d16.py(UNet 模型)、./gamma3_512x512.py(Gamma3 数据与评测配置)、mmseg::_base_/default_runtime.py(默认运行环境)、mmseg::_base_/schedules/schedule_20k.py(20k 迭代训练调度)。其中mmseg::前缀表示从 MMSegmentation 包的configs目录解析基础配置;
  • custom_imports:显式导入datasets.gamma3_dataset模块,完成自定义数据集的注册;
  • decode_head=dict(num_classes=3):将 FCN 解码头输出类别数由默认的 2 覆盖为 3(背景/视盘/视杯);
  • auxiliary_head=None:关闭 UNet 的辅助解码头,仅使用主解码头输出;
  • test_cfg=dict(mode='whole', _delete_=True):将测试推理模式由基础配置的slide(滑窗)切换为whole(整图),并删除被覆盖的旧字段;对于 512×512 的医学图像,整图推理在保证精度的同时更为高效;
  • vis_backends = None:关闭可视化后端,降低训练过程中的额外开销(可根据需要开启 Tensorboard 等后端)。

训练与测试命令

训练

在单机单卡(默认)环境下训练模型:

mim train mmseg ./configs/${CONFIG_PATH}

其中${CONFIG_PATH}替换为上述三个配置文件名之一,例如:

mim train mmseg ./configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_gamma3-512x512.py

mim会自动解析配置中的依赖(如 MMCV、MMEngine、MMSegmentation),并拉起训练流程;训练迭代数为 20k,批大小为 16(对应配置名中的1xb16)。

测试

使用训练产出的权重对模型进行评测:

mim test mmseg ./configs/${CONFIG_PATH} --checkpoint ${CHECKPOINT_PATH}

例如:

mim test mmseg ./configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_gamma3-512x512.py --checkpoint /path/to/checkpoint.pth

测试阶段将依据 gamma3_512x512.py 中的test_evaluator输出mIoUmDice两项指标,用于量化模型在背景、视盘、视杯三个类别上的分割质量。

项目质量状态(Checklist)解读

项目 README 末尾附带了一份 OpenMMLabprojects/目录的标准质量清单,当前状态为:

  • 已完成:代码编写、基础 docstring 与文献引用、完整 README;
  • 待完成:测试时正确性验证、训练时正确性验证、类型注解与单元测试、代码润色、metafile.yml元数据文件,以及将模块迁移/重构进核心包等后续里程碑。

这意味着该项目当前定位为可供复现与二次开发的社区实验项目(位于projects/而非核心mmseg/models),使用前建议自行验证训练与测试的正确性,并根据实际 GPU 环境调整批大小等超参数。

相关文献引用

若在学术工作中使用该数据集或本项目,建议引用以下文献(来自项目 README 的 BibTeX):

@article{fu2018joint, title={Joint optic disc and cup segmentation based on multi-label deep network and polar transformation}, author={Fu, Huazhu and Cheng, Jun and Xu, Yanwu and Wong, Damon Wing Kee and Liu, Jiang and Cao, Xiaochun}, journal={IEEE transactions on medical imaging}, volume={37}, number={7}, pages={1597--1605}, year={2018}, publisher={IEEE} } @article{sevastopolsky2017optic, title={Optic disc and cup segmentation methods for glaucoma detection with modification of U-Net convolutional neural network}, author={Sevastopolsky, Artem}, journal={Pattern Recognition and Image Analysis}, volume={27}, pages={618--624}, year={2017}, publisher={Springer} }

总结与实践建议

Gamma3 项目完整展示了在 MMSegmentation 中落地一个医学影像分割任务的标准工作流:自定义数据集类注册 → 原始数据格式统一与标签重映射 → 训练/验证集切分与标注文件生成 → 数据流水线与评测指标配置 → 基于 UNet 的模型训练与测试。项目中同时提供了三档学习率(1e-4 / 1e-3 / 1e-2)的对比配置,便于研究者快速开展超参数实验。

实践层面有三点值得注意:其一,视盘/视杯在图像中占比极小(合计不足 1%),训练时可关注类别不均衡对 mIoU/mDice 的影响;其二,官方仅公开训练集标注,本项目采用train_test_split(test_size=0.2, random_state=0)的自切分策略,复现时需保持相同的随机种子以保证结果可比;其三,若需进一步提升分割精度,可在projects/medical/2d_image/tools/split_seg_dataset.pyprepare_dataset.py的基础上按需改造,或参考mmseg核心包中的其他医学影像模型进行迁移实验。

【免费下载链接】mmsegmentationOpenMMLab Semantic Segmentation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmsegmentation

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询