Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Support ACDC dataset #3470

Open
wants to merge 5 commits into
base: dev-1.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -264,6 +264,7 @@ Results and models are available in the [model zoo](docs/en/model_zoo.md).
- [x] [LEVIR-CD](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/en/user_guides/2_dataset_prepare.md#levir-cd)
- [x] [BDD100K](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/en/user_guides/2_dataset_prepare.md#bdd100K)
- [x] [NYU](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/en/user_guides/2_dataset_prepare.md#nyu)
- [x] [ACDC](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/en/user_guides/2_dataset_prepare.md#acdc)

</details>

Expand Down
1 change: 1 addition & 0 deletions README_zh-CN.md
Expand Up @@ -253,6 +253,7 @@ MMSegmentation v1.x 在 0.x 版本的基础上有了显著的提升,提供了
- [x] [LEVIR-CD](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/zh_cn/user_guides/2_dataset_prepare.md#levir-cd)
- [x] [BDD100K](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/zh_cn/user_guides/2_dataset_prepare.md#bdd100K)
- [x] [NYU](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/en/user_guides/2_dataset_prepare.md#nyu)
- [x] [ACDC](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/zh_cn/user_guides/2_dataset_prepare.md#acdc)

</details>

Expand Down
65 changes: 65 additions & 0 deletions configs/_base_/datasets/acdc.py
@@ -0,0 +1,65 @@
# dataset settings
dataset_type = 'ACDCDataset'
data_root = 'data/acdc/'
crop_size = (512, 1024)
train_pipeline = [
dict(type='LoadImageFromFile'),
dict(type='LoadAnnotations'),
dict(
type='RandomResize',
scale=(2048, 1024),
ratio_range=(0.5, 2.0),
keep_ratio=True),
dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75),
dict(type='RandomFlip', prob=0.5),
dict(type='PhotoMetricDistortion'),
dict(type='PackSegInputs')
]
test_pipeline = [
dict(type='LoadImageFromFile'),
dict(type='Resize', scale=(2048, 1024), keep_ratio=True),
# add loading annotation after ``Resize`` because ground truth
# does not need to do resize data transform
dict(type='LoadAnnotations'),
dict(type='PackSegInputs')
]
img_ratios = [0.5, 0.75, 1.0, 1.25, 1.5, 1.75]
tta_pipeline = [
dict(type='LoadImageFromFile', backend_args=None),
dict(
type='TestTimeAug',
transforms=[
[
dict(type='Resize', scale_factor=r, keep_ratio=True)
for r in img_ratios
],
[
dict(type='RandomFlip', prob=0., direction='horizontal'),
dict(type='RandomFlip', prob=1., direction='horizontal')
], [dict(type='LoadAnnotations')], [dict(type='PackSegInputs')]
])
]
train_dataloader = dict(
batch_size=2,
num_workers=2,
persistent_workers=True,
sampler=dict(type='InfiniteSampler', shuffle=True),
dataset=dict(
type=dataset_type,
data_root=data_root,
data_prefix=dict(img_path='rgb_anno/train', seg_map_path='gt/train'),
pipeline=train_pipeline))
val_dataloader = dict(
batch_size=1,
num_workers=4,
persistent_workers=True,
sampler=dict(type='DefaultSampler', shuffle=False),
dataset=dict(
type=dataset_type,
data_root=data_root,
data_prefix=dict(img_path='rgb_anno/test', seg_map_path='gt/test'),
pipeline=test_pipeline))
test_dataloader = val_dataloader

val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU'])
test_evaluator = val_evaluator
7 changes: 7 additions & 0 deletions configs/pspnet/pspnet_r50-d8_4xb2-40k_acdc-512x1024.py
@@ -0,0 +1,7 @@
_base_ = [
'../_base_/models/pspnet_r50-d8.py', '../_base_/datasets/acdc.py',
'../_base_/default_runtime.py', '../_base_/schedules/schedule_40k.py'
]
crop_size = (512, 1024)
data_preprocessor = dict(size=crop_size)
model = dict(data_preprocessor=data_preprocessor)
34 changes: 34 additions & 0 deletions docs/en/user_guides/2_dataset_prepare.md
Expand Up @@ -205,6 +205,13 @@ mmsegmentation
│ │ ├── annotations
│ │ │ ├── train
│ │ │ ├── test
│ ├── acdc
│ │ ├── gt
│ │ │ ├── test
│ │ │ ├── train
│ │ ├── rgb_anno
│ │ │ ├── test
│ │ │ ├── train
```

## Download dataset via MIM
Expand Down Expand Up @@ -752,3 +759,30 @@ mmsegmentation
```bash
python tools/dataset_converters/nyu.py nyu.zip
```

## ACDC Dataset

The data could be found [here](https://acdc.vision.ee.ethz.ch/download).

Download and unzip the data into `$ACDC`, it should have the following structure:

```
$ACDC
├── gt
│ ├── fog
│ ├── night
│ ├── rain
│ ├── snow
├── rgb_anon
│ ├── fog
│ ├── night
│ ├── rain
│ ├── snow
```

We provided a script to process the ACDC dataset into mmsegmentation accepted format.

```shell
# --split means the weather split, available options [fog, night, rain, snow, all]
python tools/dataset_converters/acdc.py $ACDC --split $split
```
27 changes: 27 additions & 0 deletions docs/zh_cn/user_guides/2_dataset_prepare.md
Expand Up @@ -748,3 +748,30 @@ mmsegmentation
```bash
python tools/dataset_converters/nyu.py nyu.zip
```

## ACDC

您可以从 [这个链接](https://acdc.vision.ee.ethz.ch/download) 下载 ACDC 数据集。

下载完成后请将数据集解压缩到 `$ACDC`, 得到以下结构:

```
$ACDC
├── gt
│ ├── fog
│ ├── night
│ ├── rain
│ ├── snow
├── rgb_anon
│ ├── fog
│ ├── night
│ ├── rain
│ ├── snow
```

请运行以下命令转换 ACDC 数据集:

```shell
# --split 是天气选项, 可以从 [fog, night, rain, snow, all] 中选择
python tools/dataset_converters/acdc.py $ACDC --split $split
```
3 changes: 2 additions & 1 deletion mmseg/datasets/__init__.py
@@ -1,5 +1,6 @@
# Copyright (c) OpenMMLab. All rights reserved.
# yapf: disable
from .acdc import ACDCDataset
from .ade import ADE20KDataset
from .basesegdataset import BaseCDDataset, BaseSegDataset
from .bdd100k import BDD100KDataset
Expand Down Expand Up @@ -60,5 +61,5 @@
'MapillaryDataset_v2', 'Albu', 'LEVIRCDDataset',
'LoadMultipleRSImageFromFile', 'LoadSingleRSImageFromFile',
'ConcatCDInput', 'BaseCDDataset', 'DSDLSegDataset', 'BDD100KDataset',
'NYUDataset'
'NYUDataset', 'ACDCDataset'
]
15 changes: 15 additions & 0 deletions mmseg/datasets/acdc.py
@@ -0,0 +1,15 @@
# Copyright (c) OpenMMLab. All rights reserved.
from mmseg.registry import DATASETS
from .cityscapes import CityscapesDataset


@DATASETS.register_module()
class ACDCDataset(CityscapesDataset):
"""ACDCDataset dataset."""

def __init__(self,
img_suffix='_rgb_anon.png',
seg_map_suffix='_gt_labelTrainIds.png',
**kwargs) -> None:
super().__init__(
img_suffix=img_suffix, seg_map_suffix=seg_map_suffix, **kwargs)
72 changes: 72 additions & 0 deletions tools/dataset_converters/acdc.py
@@ -0,0 +1,72 @@
# Copyright (c) OpenMMLab. All rights reserved.
import argparse
import os
import os.path as osp
import shutil

from mmengine.utils import mkdir_or_exist


def parse_args():
parser = argparse.ArgumentParser(
description='Convert ACDC dataset to mmsegmentation format')
parser.add_argument('raw_data', help='the path of raw data')
parser.add_argument(
'-o', '--out_dir', help='output path', default='./data/acdc')
parser.add_argument(
'--split',
choices=['fog', 'night', 'rain', 'snow', 'all'],
default='night')
args = parser.parse_args()
return args


def main():
args = parse_args()

print('Making directories...')
mkdir_or_exist(args.out_dir)
for subdir in ['gt/test', 'rgb_anno/test', 'gt/train', 'rgb_anno/train']:
mkdir_or_exist(osp.join(args.out_dir, subdir))

print('Moving images and annotations...')

if args.split == 'all':
anno_str_test = '/val/'
gt_str_test = '/val/'
anno_str_train = '/train/'
gt_str_train = '/train/'
else:
anno_str_test = f'rgb_anon/{args.split}/val/'
gt_str_test = f'gt/{args.split}/val/'
anno_str_train = f'rgb_anon/{args.split}/train/'
gt_str_train = f'gt/{args.split}/train/'

for dirpath, _, filenames in os.walk(args.raw_data):
for filename in filenames:
full_path = os.path.join(dirpath, filename)

if anno_str_test in full_path:
if full_path.endswith('_rgb_anon.png'):
new_path = os.path.join(args.out_dir, 'rgb_anno/test',
filename)
shutil.copy(full_path, new_path)
elif gt_str_test in full_path:
if full_path.endswith('_gt_labelTrainIds.png'):
new_path = os.path.join(args.out_dir, 'gt/test', filename)
shutil.copy(full_path, new_path)
if anno_str_train in full_path:
if full_path.endswith('_rgb_anon.png'):
new_path = os.path.join(args.out_dir, 'rgb_anno/train',
filename)
shutil.copy(full_path, new_path)
elif gt_str_train in full_path:
if full_path.endswith('_gt_labelTrainIds.png'):
new_path = os.path.join(args.out_dir, 'gt/train', filename)
shutil.copy(full_path, new_path)

print('Done!')


if __name__ == '__main__':
main()