Skip to content

Commit 5dacca3

Browse files
authored
Add 4 retinal vessel segmentation benchmark (open-mmlab#315)
* add 4 retinal vessel segmentation configs of UNet * fix flip augmentation * add unet benchmark on 4 medical datasets * fix hrf bug
1 parent 94e12e8 commit 5dacca3

10 files changed

+334
-0
lines changed

configs/_base_/datasets/chase_db1.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# dataset settings
2+
dataset_type = 'ChaseDB1Dataset'
3+
data_root = 'data/CHASE_DB1'
4+
img_norm_cfg = dict(
5+
mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)
6+
img_scale = (960, 999)
7+
crop_size = (128, 128)
8+
train_pipeline = [
9+
dict(type='LoadImageFromFile'),
10+
dict(type='LoadAnnotations'),
11+
dict(type='Resize', img_scale=img_scale, ratio_range=(0.5, 2.0)),
12+
dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75),
13+
dict(type='RandomFlip', prob=0.5),
14+
dict(type='PhotoMetricDistortion'),
15+
dict(type='Normalize', **img_norm_cfg),
16+
dict(type='Pad', size=crop_size, pad_val=0, seg_pad_val=255),
17+
dict(type='DefaultFormatBundle'),
18+
dict(type='Collect', keys=['img', 'gt_semantic_seg'])
19+
]
20+
test_pipeline = [
21+
dict(type='LoadImageFromFile'),
22+
dict(
23+
type='MultiScaleFlipAug',
24+
img_scale=img_scale,
25+
# img_ratios=[0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0],
26+
flip=False,
27+
transforms=[
28+
dict(type='Resize', keep_ratio=True),
29+
dict(type='RandomFlip'),
30+
dict(type='Normalize', **img_norm_cfg),
31+
dict(type='ImageToTensor', keys=['img']),
32+
dict(type='Collect', keys=['img'])
33+
])
34+
]
35+
36+
data = dict(
37+
samples_per_gpu=4,
38+
workers_per_gpu=4,
39+
train=dict(
40+
type='RepeatDataset',
41+
times=40000,
42+
dataset=dict(
43+
type=dataset_type,
44+
data_root=data_root,
45+
img_dir='images/training',
46+
ann_dir='annotations/training',
47+
pipeline=train_pipeline)),
48+
val=dict(
49+
type=dataset_type,
50+
data_root=data_root,
51+
img_dir='images/validation',
52+
ann_dir='annotations/validation',
53+
pipeline=test_pipeline),
54+
test=dict(
55+
type=dataset_type,
56+
data_root=data_root,
57+
img_dir='images/validation',
58+
ann_dir='annotations/validation',
59+
pipeline=test_pipeline))

configs/_base_/datasets/drive.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# dataset settings
2+
dataset_type = 'DRIVEDataset'
3+
data_root = 'data/DRIVE'
4+
img_norm_cfg = dict(
5+
mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)
6+
img_scale = (584, 565)
7+
crop_size = (64, 64)
8+
train_pipeline = [
9+
dict(type='LoadImageFromFile'),
10+
dict(type='LoadAnnotations'),
11+
dict(type='Resize', img_scale=img_scale, ratio_range=(0.5, 2.0)),
12+
dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75),
13+
dict(type='RandomFlip', prob=0.5),
14+
dict(type='PhotoMetricDistortion'),
15+
dict(type='Normalize', **img_norm_cfg),
16+
dict(type='Pad', size=crop_size, pad_val=0, seg_pad_val=255),
17+
dict(type='DefaultFormatBundle'),
18+
dict(type='Collect', keys=['img', 'gt_semantic_seg'])
19+
]
20+
test_pipeline = [
21+
dict(type='LoadImageFromFile'),
22+
dict(
23+
type='MultiScaleFlipAug',
24+
img_scale=img_scale,
25+
# img_ratios=[0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0],
26+
flip=False,
27+
transforms=[
28+
dict(type='Resize', keep_ratio=True),
29+
dict(type='RandomFlip'),
30+
dict(type='Normalize', **img_norm_cfg),
31+
dict(type='ImageToTensor', keys=['img']),
32+
dict(type='Collect', keys=['img'])
33+
])
34+
]
35+
36+
data = dict(
37+
samples_per_gpu=4,
38+
workers_per_gpu=4,
39+
train=dict(
40+
type='RepeatDataset',
41+
times=40000,
42+
dataset=dict(
43+
type=dataset_type,
44+
data_root=data_root,
45+
img_dir='images/training',
46+
ann_dir='annotations/training',
47+
pipeline=train_pipeline)),
48+
val=dict(
49+
type=dataset_type,
50+
data_root=data_root,
51+
img_dir='images/validation',
52+
ann_dir='annotations/validation',
53+
pipeline=test_pipeline),
54+
test=dict(
55+
type=dataset_type,
56+
data_root=data_root,
57+
img_dir='images/validation',
58+
ann_dir='annotations/validation',
59+
pipeline=test_pipeline))

configs/_base_/datasets/hrf.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# dataset settings
2+
dataset_type = 'HRFDataset'
3+
data_root = 'data/HRF'
4+
img_norm_cfg = dict(
5+
mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)
6+
img_scale = (2336, 3504)
7+
crop_size = (256, 256)
8+
train_pipeline = [
9+
dict(type='LoadImageFromFile'),
10+
dict(type='LoadAnnotations'),
11+
dict(type='Resize', img_scale=img_scale, ratio_range=(0.5, 2.0)),
12+
dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75),
13+
dict(type='RandomFlip', prob=0.5),
14+
dict(type='PhotoMetricDistortion'),
15+
dict(type='Normalize', **img_norm_cfg),
16+
dict(type='Pad', size=crop_size, pad_val=0, seg_pad_val=255),
17+
dict(type='DefaultFormatBundle'),
18+
dict(type='Collect', keys=['img', 'gt_semantic_seg'])
19+
]
20+
test_pipeline = [
21+
dict(type='LoadImageFromFile'),
22+
dict(
23+
type='MultiScaleFlipAug',
24+
img_scale=img_scale,
25+
# img_ratios=[0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0],
26+
flip=False,
27+
transforms=[
28+
dict(type='Resize', keep_ratio=True),
29+
dict(type='RandomFlip'),
30+
dict(type='Normalize', **img_norm_cfg),
31+
dict(type='ImageToTensor', keys=['img']),
32+
dict(type='Collect', keys=['img'])
33+
])
34+
]
35+
36+
data = dict(
37+
samples_per_gpu=4,
38+
workers_per_gpu=4,
39+
train=dict(
40+
type='RepeatDataset',
41+
times=40000,
42+
dataset=dict(
43+
type=dataset_type,
44+
data_root=data_root,
45+
img_dir='images/training',
46+
ann_dir='annotations/training',
47+
pipeline=train_pipeline)),
48+
val=dict(
49+
type=dataset_type,
50+
data_root=data_root,
51+
img_dir='images/validation',
52+
ann_dir='annotations/validation',
53+
pipeline=test_pipeline),
54+
test=dict(
55+
type=dataset_type,
56+
data_root=data_root,
57+
img_dir='images/validation',
58+
ann_dir='annotations/validation',
59+
pipeline=test_pipeline))

configs/_base_/datasets/stare.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# dataset settings
2+
dataset_type = 'STAREDataset'
3+
data_root = 'data/STARE'
4+
img_norm_cfg = dict(
5+
mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)
6+
img_scale = (605, 700)
7+
crop_size = (128, 128)
8+
train_pipeline = [
9+
dict(type='LoadImageFromFile'),
10+
dict(type='LoadAnnotations'),
11+
dict(type='Resize', img_scale=img_scale, ratio_range=(0.5, 2.0)),
12+
dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75),
13+
dict(type='RandomFlip', prob=0.5),
14+
dict(type='PhotoMetricDistortion'),
15+
dict(type='Normalize', **img_norm_cfg),
16+
dict(type='Pad', size=crop_size, pad_val=0, seg_pad_val=255),
17+
dict(type='DefaultFormatBundle'),
18+
dict(type='Collect', keys=['img', 'gt_semantic_seg'])
19+
]
20+
test_pipeline = [
21+
dict(type='LoadImageFromFile'),
22+
dict(
23+
type='MultiScaleFlipAug',
24+
img_scale=img_scale,
25+
# img_ratios=[0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0],
26+
flip=False,
27+
transforms=[
28+
dict(type='Resize', keep_ratio=True),
29+
dict(type='RandomFlip'),
30+
dict(type='Normalize', **img_norm_cfg),
31+
dict(type='ImageToTensor', keys=['img']),
32+
dict(type='Collect', keys=['img'])
33+
])
34+
]
35+
36+
data = dict(
37+
samples_per_gpu=4,
38+
workers_per_gpu=4,
39+
train=dict(
40+
type='RepeatDataset',
41+
times=40000,
42+
dataset=dict(
43+
type=dataset_type,
44+
data_root=data_root,
45+
img_dir='images/training',
46+
ann_dir='annotations/training',
47+
pipeline=train_pipeline)),
48+
val=dict(
49+
type=dataset_type,
50+
data_root=data_root,
51+
img_dir='images/validation',
52+
ann_dir='annotations/validation',
53+
pipeline=test_pipeline),
54+
test=dict(
55+
type=dataset_type,
56+
data_root=data_root,
57+
img_dir='images/validation',
58+
ann_dir='annotations/validation',
59+
pipeline=test_pipeline))

configs/_base_/models/unet_s5-d16.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# model settings
2+
norm_cfg = dict(type='SyncBN', requires_grad=True)
3+
model = dict(
4+
type='EncoderDecoder',
5+
pretrained=None,
6+
backbone=dict(
7+
type='UNet',
8+
in_channels=3,
9+
base_channels=64,
10+
num_stages=5,
11+
strides=(1, 1, 1, 1, 1),
12+
enc_num_convs=(2, 2, 2, 2, 2),
13+
dec_num_convs=(2, 2, 2, 2),
14+
downsamples=(True, True, True, True),
15+
enc_dilations=(1, 1, 1, 1, 1),
16+
dec_dilations=(1, 1, 1, 1),
17+
with_cp=False,
18+
conv_cfg=None,
19+
norm_cfg=norm_cfg,
20+
act_cfg=dict(type='ReLU'),
21+
upsample_cfg=dict(type='InterpConv'),
22+
norm_eval=False),
23+
decode_head=dict(
24+
type='FCNHead',
25+
in_channels=64,
26+
in_index=4,
27+
channels=64,
28+
num_convs=1,
29+
concat_input=False,
30+
dropout_ratio=0.1,
31+
num_classes=2,
32+
norm_cfg=norm_cfg,
33+
align_corners=False,
34+
loss_decode=dict(
35+
type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)),
36+
auxiliary_head=dict(
37+
type='FCNHead',
38+
in_channels=128,
39+
in_index=3,
40+
channels=64,
41+
num_convs=1,
42+
concat_input=False,
43+
dropout_ratio=0.1,
44+
num_classes=2,
45+
norm_cfg=norm_cfg,
46+
align_corners=False,
47+
loss_decode=dict(
48+
type='CrossEntropyLoss', use_sigmoid=False, loss_weight=0.4)))
49+
# model training and testing settings
50+
train_cfg = dict()
51+
test_cfg = dict(mode='slide', crop_size=256, stride=170)

configs/unet/README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# U-Net: Convolutional Networks for Biomedical Image Segmentation
2+
3+
## Introduction
4+
5+
```latex
6+
@inproceedings{ronneberger2015u,
7+
title={U-net: Convolutional networks for biomedical image segmentation},
8+
author={Ronneberger, Olaf and Fischer, Philipp and Brox, Thomas},
9+
booktitle={International Conference on Medical image computing and computer-assisted intervention},
10+
pages={234--241},
11+
year={2015},
12+
organization={Springer}
13+
}
14+
```
15+
16+
## Results and models
17+
18+
| Backbone | Head | Dataset | Image Size | Crop Size | Stride | Lr schd | Mem (GB) | Inf time (fps) | Dice | download |
19+
|--------|----------|----------|----------|-----------|--------:|----------|----------------|------:|--------------:|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
20+
| UNet-S5-D16 | FCN | DRIVE | 584x565 | 64x64 | 42x42 | 40000 | 0.680 | - | 78.67 | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/unet_s5-d16_64x64_40k_drive/unet_s5-d16_64x64_40k_drive_20201223_191051-9cd163b8.pth) | [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/unet_s5-d16_64x64_40k_drive/unet_s5-d16_64x64_40k_drive-20201223_191051.log.json) |
21+
| UNet-S5-D16 | FCN | STARE | 605x700 | 128x128 | 85x85 | 40000 | 0.968 | - | 81.02 | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/unet_s5-d16_128x128_40k_stare/unet_s5-d16_128x128_40k_stare_20201223_191051-e5439846.pth) | [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/unet_s5-d16_128x128_40k_stare/unet_s5-d16_128x128_40k_stare-20201223_191051.log.json) |
22+
| UNet-S5-D16 | FCN | CHASE_DB1 | 960x999 | 128x128 | 85x85 | 40000 | 0.968 | - | 80.24 | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/unet_s5-d16_128x128_40k_chase_db1/unet_s5-d16_128x128_40k_chase_db1_20201223_191051-8b16ca0b.pth) | [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/unet_s5-d16_128x128_40k_chase_db1/unet_s5-d16_128x128_40k_chase_db1-20201223_191051.log.json) |
23+
| UNet-S5-D16 | FCN | HRF | 2336x3504 | 256x256 | 170x170 | 40000 | 2.525 | - | 79.45 | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/unet_s5-d16_256x256_40k_hrf/unet_s5-d16_256x256_40k_hrf_20201223_173724-d89cf1ed.pth) | [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/unet_s5-d16_256x256_40k_hrf/unet_s5-d16_256x256_40k_hrf-20201223_173724.log.json) |
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
_base_ = [
2+
'../_base_/models/unet_s5-d16.py', '../_base_/datasets/chase_db1.py',
3+
'../_base_/default_runtime.py', '../_base_/schedules/schedule_40k.py'
4+
]
5+
test_cfg = dict(crop_size=(128, 128), stride=(85, 85))
6+
evaluation = dict(metric='mDice')
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
_base_ = [
2+
'../_base_/models/unet_s5-d16.py', '../_base_/datasets/stare.py',
3+
'../_base_/default_runtime.py', '../_base_/schedules/schedule_40k.py'
4+
]
5+
test_cfg = dict(crop_size=(128, 128), stride=(85, 85))
6+
evaluation = dict(metric='mDice')
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
_base_ = [
2+
'../_base_/models/unet_s5-d16.py', '../_base_/datasets/hrf.py',
3+
'../_base_/default_runtime.py', '../_base_/schedules/schedule_40k.py'
4+
]
5+
test_cfg = dict(crop_size=(256, 256), stride=(170, 170))
6+
evaluation = dict(metric='mDice')
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
_base_ = [
2+
'../_base_/models/unet_s5-d16.py', '../_base_/datasets/drive.py',
3+
'../_base_/default_runtime.py', '../_base_/schedules/schedule_40k.py'
4+
]
5+
test_cfg = dict(crop_size=(64, 64), stride=(42, 42))
6+
evaluation = dict(metric='mDice')

0 commit comments

Comments
 (0)