browse_dataset.py 5.22 KB
Newer Older
dingchang's avatar
dingchang committed
1
# Copyright (c) OpenMMLab. All rights reserved.
2
3
4
import argparse
from os import path as osp

ChaimZhu's avatar
ChaimZhu committed
5
from mmengine.config import Config, DictAction
6
from mmengine.registry import init_default_scope
ChaimZhu's avatar
ChaimZhu committed
7
from mmengine.utils import ProgressBar, mkdir_or_exist
8

ChaimZhu's avatar
ChaimZhu committed
9
from mmdet3d.registry import DATASETS, VISUALIZERS
10
from mmdet3d.utils import replace_ceph_backend
11
12
13
14
15
16
17
18
19
20


def parse_args():
    parser = argparse.ArgumentParser(description='Browse a dataset')
    parser.add_argument('config', help='train config file path')
    parser.add_argument(
        '--output-dir',
        default=None,
        type=str,
        help='If there is no display interface, you can save it')
ChaimZhu's avatar
ChaimZhu committed
21
22
23
24
25
26
    parser.add_argument('--not-show', default=False, action='store_true')
    parser.add_argument(
        '--show-interval',
        type=float,
        default=2,
        help='the interval of show (s)')
27
    parser.add_argument(
28
29
        '--task',
        type=str,
30
31
32
33
        choices=[
            'mono_det', 'multi-view_det', 'lidar_det', 'lidar_seg',
            'multi-modality_det'
        ],
34
        help='Determine the visualization method depending on the task.')
35
36
37
38
    parser.add_argument(
        '--aug',
        action='store_true',
        help='Whether to visualize augmented datasets or original dataset.')
39
    parser.add_argument(
ChaimZhu's avatar
ChaimZhu committed
40
        '--ceph', action='store_true', help='Use ceph as data storage backend')
41
42
43
44
45
46
47
48
49
50
51
52
53
54
    parser.add_argument(
        '--cfg-options',
        nargs='+',
        action=DictAction,
        help='override some settings in the used config, the key-value pair '
        'in xxx=yyy format will be merged into config file. If the value to '
        'be overwritten is a list, it should be like key="[a,b]" or key=a,b '
        'It also allows nested list/tuple values, e.g. key="[(a,b),(c,d)]" '
        'Note that the quotation marks are necessary and that no white space '
        'is allowed.')
    args = parser.parse_args()
    return args


ChaimZhu's avatar
ChaimZhu committed
55
def build_data_cfg(config_path, aug, cfg_options):
56
    """Build data config for loading visualization data."""
57

58
59
60
    cfg = Config.fromfile(config_path)
    if cfg_options is not None:
        cfg.merge_from_dict(cfg_options)
ChaimZhu's avatar
ChaimZhu committed
61
62
63
64
65
66

    # extract inner dataset of `RepeatDataset` as
    # `cfg.train_dataloader.dataset` so we don't
    # need to worry about it later
    if cfg.train_dataloader.dataset['type'] == 'RepeatDataset':
        cfg.train_dataloader.dataset = cfg.train_dataloader.dataset.dataset
67
    # use only first dataset for `ConcatDataset`
ChaimZhu's avatar
ChaimZhu committed
68
69
    if cfg.train_dataloader.dataset['type'] == 'ConcatDataset':
        cfg.train_dataloader.dataset = cfg.train_dataloader.dataset.datasets[0]
70
71
72
    if cfg.train_dataloader.dataset['type'] == 'CBGSDataset':
        cfg.train_dataloader.dataset = cfg.train_dataloader.dataset.dataset

ChaimZhu's avatar
ChaimZhu committed
73
    train_data_cfg = cfg.train_dataloader.dataset
74
75
76
77

    if aug:
        show_pipeline = cfg.train_pipeline
    else:
78
        show_pipeline = cfg.test_pipeline
79
80
81
        for i in range(len(cfg.train_pipeline)):
            if cfg.train_pipeline[i]['type'] == 'LoadAnnotations3D':
                show_pipeline.insert(i, cfg.train_pipeline[i])
ChaimZhu's avatar
ChaimZhu committed
82
83
84
            # Collect data as well as labels
            if cfg.train_pipeline[i]['type'] == 'Pack3DDetInputs':
                if show_pipeline[-1]['type'] == 'Pack3DDetInputs':
85
86
87
                    show_pipeline[-1] = cfg.train_pipeline[i]
                else:
                    show_pipeline.append(cfg.train_pipeline[i])
88

ChaimZhu's avatar
ChaimZhu committed
89
    train_data_cfg['pipeline'] = show_pipeline
90
91
92
93
94
95
96
97
98
99

    return cfg


def main():
    args = parse_args()

    if args.output_dir is not None:
        mkdir_or_exist(args.output_dir)

ChaimZhu's avatar
ChaimZhu committed
100
101
102
103
104
    cfg = build_data_cfg(args.config, args.aug, args.cfg_options)

    # TODO: We will unify the ceph support approach with other OpenMMLab repos
    if args.ceph:
        cfg = replace_ceph_backend(cfg)
ZCMax's avatar
ZCMax committed
105

106
    init_default_scope(cfg.get('default_scope', 'mmdet3d'))
ZCMax's avatar
ZCMax committed
107

108
    try:
ChaimZhu's avatar
ChaimZhu committed
109
        dataset = DATASETS.build(
ZCMax's avatar
ZCMax committed
110
111
            cfg.train_dataloader.dataset,
            default_args=dict(filter_empty_gt=False))
112
    except TypeError:  # seg dataset doesn't have `filter_empty_gt` key
ChaimZhu's avatar
ChaimZhu committed
113
        dataset = DATASETS.build(cfg.train_dataloader.dataset)
114
115

    # configure visualization mode
116
    vis_task = args.task
ZCMax's avatar
ZCMax committed
117
118
119
120

    visualizer = VISUALIZERS.build(cfg.visualizer)
    visualizer.dataset_meta = dataset.metainfo

ChaimZhu's avatar
ChaimZhu committed
121
    progress_bar = ProgressBar(len(dataset))
122

123
    for i, item in enumerate(dataset):
ZCMax's avatar
ZCMax committed
124
125
        # the 3D Boxes in input could be in any of three coordinates
        data_input = item['inputs']
126
        data_sample = item['data_samples'].numpy()
ZCMax's avatar
ZCMax committed
127
128

        out_file = osp.join(
129
130
131
132
133
134
135
136
            args.output_dir,
            f'{i}.jpg') if args.output_dir is not None else None

        # o3d_save_path is valid when args.not_show is False
        o3d_save_path = osp.join(args.output_dir, f'pc_{i}.png') if (
            args.output_dir is not None
            and vis_task in ['lidar_det', 'lidar_seg', 'multi-modality_det']
            and not args.not_show) else None
ZCMax's avatar
ZCMax committed
137
138
139
140

        visualizer.add_datasample(
            '3d visualzier',
            data_input,
ChaimZhu's avatar
ChaimZhu committed
141
            data_sample=data_sample,
ZCMax's avatar
ZCMax committed
142
143
144
            show=not args.not_show,
            wait_time=args.show_interval,
            out_file=out_file,
145
            o3d_save_path=o3d_save_path,
ZCMax's avatar
ZCMax committed
146
147
            vis_task=vis_task)

148
        progress_bar.update()
149
150
151
152


if __name__ == '__main__':
    main()