batch_load_scannet_data.py 4.46 KB
Newer Older
liyinhao's avatar
liyinhao committed
1
2
3
4
5
6
7
8
9
# Copyright (c) Facebook, Inc. and its affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
""" Batch mode in loading Scannet scenes with vertices and ground truth labels
for semantic and instance segmentations

Usage example: python ./batch_load_scannet_data.py
"""
10
import argparse
liyinhao's avatar
liyinhao committed
11
12
13
14
15
16
17
18
19
20
21
22
import datetime
import os

import numpy as np
from load_scannet_data import export

SCANNET_DIR = 'scans'
DONOTCARE_CLASS_IDS = np.array([])
OBJ_CLASS_IDS = np.array(
    [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 24, 28, 33, 34, 36, 39])


23
24
25
def export_one_scan(scan_name, output_filename_prefix, max_num_point,
                    label_map_file, scannet_dir):
    mesh_file = os.path.join(scannet_dir, scan_name,
liyinhao's avatar
liyinhao committed
26
                             scan_name + '_vh_clean_2.ply')
27
    agg_file = os.path.join(scannet_dir, scan_name,
liyinhao's avatar
liyinhao committed
28
                            scan_name + '.aggregation.json')
29
    seg_file = os.path.join(scannet_dir, scan_name,
liyinhao's avatar
liyinhao committed
30
31
                            scan_name + '_vh_clean_2.0.010000.segs.json')
    meta_file = os.path.join(
32
        scannet_dir, scan_name, scan_name +
liyinhao's avatar
liyinhao committed
33
34
35
        '.txt')  # includes axisAlignment info for the train set scans.
    mesh_vertices, semantic_labels, instance_labels, instance_bboxes, \
        instance2semantic = export(mesh_file, agg_file, seg_file,
36
                                   meta_file, label_map_file, None)
liyinhao's avatar
liyinhao committed
37
38
39
40
41
42
43
44
45
46
47
48
49
50

    mask = np.logical_not(np.in1d(semantic_labels, DONOTCARE_CLASS_IDS))
    mesh_vertices = mesh_vertices[mask, :]
    semantic_labels = semantic_labels[mask]
    instance_labels = instance_labels[mask]

    num_instances = len(np.unique(instance_labels))
    print('Num of instances: ', num_instances)

    bbox_mask = np.in1d(instance_bboxes[:, -1], OBJ_CLASS_IDS)
    instance_bboxes = instance_bboxes[bbox_mask, :]
    print('Num of care instances: ', instance_bboxes.shape[0])

    N = mesh_vertices.shape[0]
51
52
    if N > max_num_point:
        choices = np.random.choice(N, max_num_point, replace=False)
liyinhao's avatar
liyinhao committed
53
54
55
56
57
58
59
60
61
62
        mesh_vertices = mesh_vertices[choices, :]
        semantic_labels = semantic_labels[choices]
        instance_labels = instance_labels[choices]

    np.save(output_filename_prefix + '_vert.npy', mesh_vertices)
    np.save(output_filename_prefix + '_sem_label.npy', semantic_labels)
    np.save(output_filename_prefix + '_ins_label.npy', instance_labels)
    np.save(output_filename_prefix + '_bbox.npy', instance_bboxes)


63
64
65
66
67
def batch_export(max_num_point, output_folder, train_scan_names_file,
                 label_map_file, scannet_dir):
    if not os.path.exists(output_folder):
        print('Creating new data folder: {}'.format(output_folder))
        os.mkdir(output_folder)
liyinhao's avatar
liyinhao committed
68

69
70
    train_scan_names = [line.rstrip() for line in open(train_scan_names_file)]
    for scan_name in train_scan_names:
liyinhao's avatar
liyinhao committed
71
72
73
        print('-' * 20 + 'begin')
        print(datetime.datetime.now())
        print(scan_name)
74
        output_filename_prefix = os.path.join(output_folder, scan_name)
liyinhao's avatar
liyinhao committed
75
76
77
78
79
        if os.path.isfile(output_filename_prefix + '_vert.npy'):
            print('File already exists. skipping.')
            print('-' * 20 + 'done')
            continue
        try:
80
81
            export_one_scan(scan_name, output_filename_prefix, max_num_point,
                            label_map_file, scannet_dir)
liyinhao's avatar
liyinhao committed
82
83
84
85
86
        except Exception:
            print('Failed export scan: %s' % (scan_name))
        print('-' * 20 + 'done')


87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '--max_num_point',
        required=True,
        default=50000,
        help='The maximum number of the points.')
    parser.add_argument(
        '--output_folder',
        required=True,
        default='./scannet_train_instance_data',
        help='output folder of the result.')
    parser.add_argument(
        '--scannet_dir',
        required=True,
        default='scans',
        help='scannet data directory.')
    parser.add_argument(
        '--label_map_file',
        required=True,
        default='meta_data/scannetv2-labels.combined.tsv',
        help='The path of label map file.')
    parser.add_argument(
        '--train_scan_names_file',
        required=True,
        default='meta_data/scannet_train.txt',
        help='The path of the file that stores the scan names.')
    args = parser.parse_args()
    batch_export(args.max_num_point, args.output_folder,
                 args.train_scan_names_file, args.label_map_file,
                 args.scannet_dir)


liyinhao's avatar
liyinhao committed
120
if __name__ == '__main__':
121
    main()