browse_dataset.py 4.57 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

5
6
import mmengine
from mmengine import Config, DictAction, mkdir_or_exist
7

8
from mmdet3d.datasets import build_dataset
ZCMax's avatar
ZCMax committed
9
10
from mmdet3d.registry import VISUALIZERS
from mmdet3d.utils import register_all_modules
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26


def parse_args():
    parser = argparse.ArgumentParser(description='Browse a dataset')
    parser.add_argument('config', help='train config file path')
    parser.add_argument(
        '--skip-type',
        type=str,
        nargs='+',
        default=['Normalize'],
        help='skip some useless pipeline')
    parser.add_argument(
        '--output-dir',
        default=None,
        type=str,
        help='If there is no display interface, you can save it')
27
    parser.add_argument(
28
29
30
31
        '--task',
        type=str,
        choices=['det', 'seg', 'multi_modality-det', 'mono-det'],
        help='Determine the visualization method depending on the task.')
32
33
34
35
    parser.add_argument(
        '--aug',
        action='store_true',
        help='Whether to visualize augmented datasets or original dataset.')
36
37
38
39
40
    parser.add_argument(
        '--online',
        action='store_true',
        help='Whether to perform online visualization. Note that you often '
        'need a monitor to do so.')
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


55
def build_data_cfg(config_path, skip_type, 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)
61
62
    # extract inner dataset of `RepeatDataset` as `cfg.data.train`
    # so we don't need to worry about it later
63
    if cfg.data.train['type'] == 'RepeatDataset':
64
        cfg.data.train = cfg.data.train.dataset
65
66
67
    # use only first dataset for `ConcatDataset`
    if cfg.data.train['type'] == 'ConcatDataset':
        cfg.data.train = cfg.data.train.datasets[0]
68
    train_data_cfg = cfg.data.train
69
70
71
72
73
74
75
76

    if aug:
        show_pipeline = cfg.train_pipeline
    else:
        show_pipeline = cfg.eval_pipeline
        for i in range(len(cfg.train_pipeline)):
            if cfg.train_pipeline[i]['type'] == 'LoadAnnotations3D':
                show_pipeline.insert(i, cfg.train_pipeline[i])
77
            # Collect points as well as labels
ZCMax's avatar
ZCMax committed
78
79
            if cfg.train_pipeline[i]['type'] == 'Pack3DInputs':
                if show_pipeline[-1]['type'] == 'Pack3DInputs':
80
81
82
                    show_pipeline[-1] = cfg.train_pipeline[i]
                else:
                    show_pipeline.append(cfg.train_pipeline[i])
83

84
    train_data_cfg['pipeline'] = [
85
        x for x in show_pipeline if x['type'] not in skip_type
86
87
88
89
90
91
92
93
94
95
96
    ]

    return cfg


def main():
    args = parse_args()

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

97
98
    cfg = build_data_cfg(args.config, args.skip_type, args.aug,
                         args.cfg_options)
ZCMax's avatar
ZCMax committed
99
100
101
102

    # register all modules in mmdet3d into the registries
    register_all_modules()

103
104
    try:
        dataset = build_dataset(
ZCMax's avatar
ZCMax committed
105
106
            cfg.train_dataloader.dataset,
            default_args=dict(filter_empty_gt=False))
107
    except TypeError:  # seg dataset doesn't have `filter_empty_gt` key
ZCMax's avatar
ZCMax committed
108
        dataset = build_dataset(cfg.train_dataloader.dataset)
109
110

    # configure visualization mode
111
    vis_task = args.task  # 'det', 'seg', 'multi_modality-det', 'mono-det'
ZCMax's avatar
ZCMax committed
112
113
114
115

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

116
    progress_bar = mmengine.ProgressBar(len(dataset))
117

ZCMax's avatar
ZCMax committed
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
    for item in dataset:
        # the 3D Boxes in input could be in any of three coordinates
        data_input = item['inputs']
        data_sample = item['data_sample'].numpy()

        out_file = osp.join(
            args.output_dir) if args.output_dir is not None else None

        visualizer.add_datasample(
            '3d visualzier',
            data_input,
            data_sample,
            show=not args.not_show,
            wait_time=args.show_interval,
            out_file=out_file,
            vis_task=vis_task)

135
        progress_bar.update()
136
137
138
139


if __name__ == '__main__':
    main()