"examples/community/latent_consistency_img2img.py" did not exist on "9b6385488617ee99188b60c0525cbe4ec7e8f2a0"
sunrgbd_data_utils.py 8.9 KB
Newer Older
dingchang's avatar
dingchang committed
1
# Copyright (c) OpenMMLab. All rights reserved.
zhangwenwei's avatar
zhangwenwei committed
2
3
from concurrent import futures as futures
from os import path as osp
4
5

import mmcv
6
import mmengine
7
import numpy as np
zhangwenwei's avatar
zhangwenwei committed
8
from scipy import io as sio
9
10


11
def random_sampling(points, num_points, replace=None, return_choices=False):
liyinhao's avatar
liyinhao committed
12
    """Random sampling.
liyinhao's avatar
liyinhao committed
13

14
    Sampling point cloud to a certain number of points.
liyinhao's avatar
liyinhao committed
15
16

    Args:
17
        points (ndarray): Point cloud.
18
        num_points (int): The number of samples.
liyinhao's avatar
liyinhao committed
19
20
21
22
        replace (bool): Whether the sample is with or without replacement.
        return_choices (bool): Whether to return choices.

    Returns:
23
        points (ndarray): Point cloud after sampling.
24
    """
liyinhao's avatar
liyinhao committed
25

26
    if replace is None:
27
28
        replace = (points.shape[0] < num_points)
    choices = np.random.choice(points.shape[0], num_points, replace=replace)
29
    if return_choices:
30
        return points[choices], choices
31
    else:
32
        return points[choices]
33
34


liyinhao's avatar
liyinhao committed
35
class SUNRGBDInstance(object):
36
37
38
39
40
41
42
43
44
45
46

    def __init__(self, line):
        data = line.split(' ')
        data[1:] = [float(x) for x in data[1:]]
        self.classname = data[0]
        self.xmin = data[1]
        self.ymin = data[2]
        self.xmax = data[1] + data[3]
        self.ymax = data[2] + data[4]
        self.box2d = np.array([self.xmin, self.ymin, self.xmax, self.ymax])
        self.centroid = np.array([data[5], data[6], data[7]])
47
48
49
50
51
        self.width = data[8]
        self.length = data[9]
        self.height = data[10]
        # data[9] is x_size (length), data[8] is y_size (width), data[10] is
        # z_size (height) in our depth coordinate system,
52
53
        # l corresponds to the size along the x axis
        self.size = np.array([data[9], data[8], data[10]]) * 2
54
55
56
        self.orientation = np.zeros((3, ))
        self.orientation[0] = data[11]
        self.orientation[1] = data[12]
57
58
59
60
        self.heading_angle = np.arctan2(self.orientation[1],
                                        self.orientation[0])
        self.box3d = np.concatenate(
            [self.centroid, self.size, self.heading_angle[None]])
61
62


liyinhao's avatar
liyinhao committed
63
class SUNRGBDData(object):
liyinhao's avatar
liyinhao committed
64
    """SUNRGBD data.
liyinhao's avatar
liyinhao committed
65

liyinhao's avatar
liyinhao committed
66
    Generate scannet infos for sunrgbd_converter.
liyinhao's avatar
liyinhao committed
67
68
69

    Args:
        root_path (str): Root path of the raw data.
70
71
        split (str, optional): Set split type of the data. Default: 'train'.
        use_v1 (bool, optional): Whether to use v1. Default: False.
liyinhao's avatar
liyinhao committed
72
    """
73
74
75
76

    def __init__(self, root_path, split='train', use_v1=False):
        self.root_dir = root_path
        self.split = split
liyinhao's avatar
liyinhao committed
77
        self.split_dir = osp.join(root_path, 'sunrgbd_trainval')
78
79
80
81
82
83
84
        self.classes = [
            'bed', 'table', 'sofa', 'chair', 'toilet', 'desk', 'dresser',
            'night_stand', 'bookshelf', 'bathtub'
        ]
        self.cat2label = {cat: self.classes.index(cat) for cat in self.classes}
        self.label2cat = {
            label: self.classes[label]
liyinhao's avatar
liyinhao committed
85
            for label in range(len(self.classes))
86
87
        }
        assert split in ['train', 'val', 'test']
liyinhao's avatar
liyinhao committed
88
        split_file = osp.join(self.split_dir, f'{split}_data_idx.txt')
89
90
        mmengine.check_file_exist(split_file)
        self.sample_id_list = map(int, mmengine.list_from_file(split_file))
liyinhao's avatar
liyinhao committed
91
92
93
        self.image_dir = osp.join(self.split_dir, 'image')
        self.calib_dir = osp.join(self.split_dir, 'calib')
        self.depth_dir = osp.join(self.split_dir, 'depth')
94
        if use_v1:
liyinhao's avatar
liyinhao committed
95
            self.label_dir = osp.join(self.split_dir, 'label_v1')
96
        else:
liyinhao's avatar
liyinhao committed
97
            self.label_dir = osp.join(self.split_dir, 'label')
98
99
100
101
102

    def __len__(self):
        return len(self.sample_id_list)

    def get_image(self, idx):
liyinhao's avatar
liyinhao committed
103
        img_filename = osp.join(self.image_dir, f'{idx:06d}.jpg')
liyinhao's avatar
liyinhao committed
104
        return mmcv.imread(img_filename)
105
106
107
108
109
110

    def get_image_shape(self, idx):
        image = self.get_image(idx)
        return np.array(image.shape[:2], dtype=np.int32)

    def get_depth(self, idx):
liyinhao's avatar
liyinhao committed
111
        depth_filename = osp.join(self.depth_dir, f'{idx:06d}.mat')
112
113
114
115
        depth = sio.loadmat(depth_filename)['instance']
        return depth

    def get_calibration(self, idx):
liyinhao's avatar
liyinhao committed
116
        calib_filepath = osp.join(self.calib_dir, f'{idx:06d}.txt')
117
118
        lines = [line.rstrip() for line in open(calib_filepath)]
        Rt = np.array([float(x) for x in lines[0].split(' ')])
119
        Rt = np.reshape(Rt, (3, 3), order='F').astype(np.float32)
120
        K = np.array([float(x) for x in lines[1].split(' ')])
121
        K = np.reshape(K, (3, 3), order='F').astype(np.float32)
122
123
124
        return K, Rt

    def get_label_objects(self, idx):
liyinhao's avatar
liyinhao committed
125
        label_filename = osp.join(self.label_dir, f'{idx:06d}.txt')
126
        lines = [line.rstrip() for line in open(label_filename)]
liyinhao's avatar
liyinhao committed
127
        objects = [SUNRGBDInstance(line) for line in lines]
128
129
        return objects

liyinhao's avatar
liyinhao committed
130
    def get_infos(self, num_workers=4, has_label=True, sample_id_list=None):
liyinhao's avatar
liyinhao committed
131
        """Get data infos.
liyinhao's avatar
liyinhao committed
132
133
134
135

        This method gets information from the raw data.

        Args:
136
137
138
139
140
            num_workers (int, optional): Number of threads to be used.
                Default: 4.
            has_label (bool, optional): Whether the data has label.
                Default: True.
            sample_id_list (list[int], optional): Index list of the sample.
liyinhao's avatar
liyinhao committed
141
                Default: None.
liyinhao's avatar
liyinhao committed
142
143

        Returns:
liyinhao's avatar
liyinhao committed
144
            infos (list[dict]): Information of the raw data.
liyinhao's avatar
liyinhao committed
145
        """
146
147

        def process_single_scene(sample_idx):
liyinhao's avatar
liyinhao committed
148
            print(f'{self.split} sample_idx: {sample_idx}')
149
            # convert depth to points
liyinhao's avatar
liyinhao committed
150
            SAMPLE_NUM = 50000
151
152
            # TODO: Check whether can move the point
            #  sampling process during training.
153
154
155
156
157
158
159
            pc_upright_depth = self.get_depth(sample_idx)
            pc_upright_depth_subsampled = random_sampling(
                pc_upright_depth, SAMPLE_NUM)

            info = dict()
            pc_info = {'num_features': 6, 'lidar_idx': sample_idx}
            info['point_cloud'] = pc_info
liyinhao's avatar
liyinhao committed
160

161
            mmengine.mkdir_or_exist(osp.join(self.root_dir, 'points'))
liyinhao's avatar
liyinhao committed
162
163
164
165
            pc_upright_depth_subsampled.tofile(
                osp.join(self.root_dir, 'points', f'{sample_idx:06d}.bin'))

            info['pts_path'] = osp.join('points', f'{sample_idx:06d}.bin')
166
            img_path = osp.join('image', f'{sample_idx:06d}.jpg')
167
168
            image_info = {
                'image_idx': sample_idx,
169
170
                'image_shape': self.get_image_shape(sample_idx),
                'image_path': img_path
171
172
173
174
175
176
177
178
179
180
181
182
            }
            info['image'] = image_info

            K, Rt = self.get_calibration(sample_idx)
            calib_info = {'K': K, 'Rt': Rt}
            info['calib'] = calib_info

            if has_label:
                obj_list = self.get_label_objects(sample_idx)
                annotations = {}
                annotations['gt_num'] = len([
                    obj.classname for obj in obj_list
183
                    if obj.classname in self.cat2label.keys()
184
185
186
187
                ])
                if annotations['gt_num'] != 0:
                    annotations['name'] = np.array([
                        obj.classname for obj in obj_list
188
                        if obj.classname in self.cat2label.keys()
189
190
191
                    ])
                    annotations['bbox'] = np.concatenate([
                        obj.box2d.reshape(1, 4) for obj in obj_list
192
                        if obj.classname in self.cat2label.keys()
193
194
195
196
                    ],
                                                         axis=0)
                    annotations['location'] = np.concatenate([
                        obj.centroid.reshape(1, 3) for obj in obj_list
197
                        if obj.classname in self.cat2label.keys()
198
199
200
                    ],
                                                             axis=0)
                    annotations['dimensions'] = 2 * np.array([
201
                        [obj.length, obj.width, obj.height] for obj in obj_list
202
                        if obj.classname in self.cat2label.keys()
Yezhen Cong's avatar
Yezhen Cong committed
203
                    ])  # lwh (depth) format
204
205
                    annotations['rotation_y'] = np.array([
                        obj.heading_angle for obj in obj_list
206
                        if obj.classname in self.cat2label.keys()
207
208
209
210
                    ])
                    annotations['index'] = np.arange(
                        len(obj_list), dtype=np.int32)
                    annotations['class'] = np.array([
211
212
                        self.cat2label[obj.classname] for obj in obj_list
                        if obj.classname in self.cat2label.keys()
213
214
215
216
                    ])
                    annotations['gt_boxes_upright_depth'] = np.stack(
                        [
                            obj.box3d for obj in obj_list
217
                            if obj.classname in self.cat2label.keys()
218
219
220
221
222
223
224
225
226
227
                        ],
                        axis=0)  # (K,8)
                info['annos'] = annotations
            return info

        sample_id_list = sample_id_list if \
            sample_id_list is not None else self.sample_id_list
        with futures.ThreadPoolExecutor(num_workers) as executor:
            infos = executor.map(process_single_scene, sample_id_list)
        return list(infos)