File size: 5,193 Bytes
55e58d1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import open3d as o3d
import numpy as np
import os
import cv2
from evaluation.constants import MATTERPORT_LABELS, MATTERPORT_IDS

class MatterportDataset:
    def __init__(self, seq_name) -> None:
        self.seq_name = seq_name
        self.root = f'./data/matterport3d/scans/{seq_name}/{seq_name}'
        self.rgb_dir = f'{self.root}/undistorted_color_images'
        self.depth_dir = f'{self.root}/undistorted_depth_images'
        self.cam_param_dir = f'{self.root}/undistorted_camera_parameters/{seq_name}.conf'
        self.point_cloud_path = f'{self.root}/house_segmentations/{seq_name}.ply'
        self.mesh_path = self.point_cloud_path
        self.rgb_names, self.depth_names, self.intrinsics, self.extrinsics = \
            self._obtain_intr_extr()
        
        # output
        self.segmentation_dir = f'{self.root}/output/mask/'
        self.object_dict_dir = f'{self.root}/output/object'

        self.depth_scale = 4000.0 # (0.25mm per unit) 1u = 1/4000 m
        self.image_size = (1280, 1024)

    
    def get_frame_list(self, step):
        image_list = [os.path.join(self.rgb_dir, rgb_name) for rgb_name in self.rgb_names]

        end = len(image_list)
        frame_id_list = np.arange(0, end, step)
        return list(frame_id_list)
    

    def _obtain_intr_extr(self):
        '''Obtain the intrinsic and extrinsic parameters of Matterport3D.'''
       
        with open(self.cam_param_dir, 'r') as file:
            lines = file.readlines()

        def remove_items(test_list, item):
            return [i for i in test_list if i != item]

        intrinsics = []
        extrinsics = []
        img_names = []
        depth_names = []
        for i, line in enumerate(lines):
            line = line.strip()
            if 'intrinsics_matrix' in line:
                line = line.replace('intrinsics_matrix ', '')
                line = line.split(' ')
                line = remove_items(line, '')
                if len(line) !=9:
                    print('[WARN] something wrong at {}'.format(i))
                intrinsic = np.asarray(line).astype(float).reshape(3, 3)
                intrinsics.extend([intrinsic, intrinsic, intrinsic, intrinsic, intrinsic, intrinsic])
            elif 'scan' in line:
                line = line.split(' ')
                img_names.append(line[2])
                depth_names.append(line[1])

                line = remove_items(line, '')[3:]
                if len(line) != 16:
                    print('[WARN] something wrong at {}'.format(i))
                extrinsic = np.asarray(line).astype(float).reshape(4, 4)  
                extrinsic[:3, 1] *= -1.0 # gl2cv
                extrinsic[:3, 2] *= -1.0
                extrinsics.append(extrinsic)

        intrinsics = np.stack(intrinsics, axis=0)
        extrinsics = np.stack(extrinsics, axis=0)
        img_names = np.asarray(img_names)

        return img_names, depth_names, intrinsics, extrinsics


    def get_intrinsics(self, frame_id):
        K = self.intrinsics[frame_id]
        intrinisc_cam_parameters = o3d.camera.PinholeCameraIntrinsic()
        intrinisc_cam_parameters.set_intrinsics(self.image_size[0], self.image_size[1], K[0, 0], K[1, 1], K[0, 2], K[1, 2])
        return intrinisc_cam_parameters
    

    def get_extrinsic(self, frame_id):
        return self.extrinsics[frame_id] 
    

    def get_depth(self, frame_id):
        depth_path = os.path.join(self.depth_dir, self.depth_names[frame_id])
        depth = cv2.imread(depth_path, -1).astype(np.uint16)
        depth = depth / self.depth_scale
        depth = depth.astype(np.float32)
        return depth


    def get_rgb(self, frame_id, change_color=True):
        rgb = cv2.imread(os.path.join(self.rgb_dir, self.rgb_names[frame_id]))
        if change_color:
            rgb = cv2.cvtColor(rgb, cv2.COLOR_BGR2RGB)
        return rgb    


    def get_segmentation(self, frame_id, align_with_depth=False):
        frame_name = self.rgb_names[frame_id][:-4]
        segmentation_path = os.path.join(self.segmentation_dir, f'{frame_name}.png')
        if not os.path.exists(segmentation_path):
            assert False, f"Segmentation not found: {segmentation_path}"
        segmentation = cv2.imread(segmentation_path, cv2.IMREAD_UNCHANGED)
        return segmentation


    def get_frame_path(self, frame_id):
        rgb_path = os.path.join(self.rgb_dir, self.rgb_names[frame_id])
        frame_name = self.rgb_names[frame_id][:-4]
        segmentation_path = os.path.join(self.segmentation_dir, f'{frame_name}.png')
        return rgb_path, segmentation_path


    def get_label_features(self):
        label_features_dict = np.load(f'data/text_features/matterport3d.npy', allow_pickle=True).item()
        return label_features_dict


    def get_scene_points(self):
        mesh = o3d.io.read_point_cloud(self.point_cloud_path)
        vertices = np.asarray(mesh.points)
        return vertices


    def get_label_id(self):
        self.label2id = {}
        self.id2label = {}
        for label, id in zip(MATTERPORT_LABELS, MATTERPORT_IDS):
            self.label2id[label] = id
            self.id2label[id] = label
        return self.label2id, self.id2label