Spaces:
Build error
Build error
| """ | |
| @Date: 2021/07/28 | |
| @description: | |
| """ | |
| import os | |
| import numpy as np | |
| import cv2 | |
| import json | |
| from PIL import Image | |
| from utils.conversion import xyz2uv, pixel2uv | |
| from utils.height import calc_ceil_ratio | |
| def read_image(image_path, shape=None): | |
| if shape is None: | |
| shape = [512, 1024] | |
| img = np.array(Image.open(image_path)).astype(np.float32) / 255 | |
| if img.shape[0] != shape[0] or img.shape[1] != shape[1]: | |
| img = cv2.resize(img, dsize=tuple(shape[::-1]), interpolation=cv2.INTER_AREA) | |
| return np.array(img) | |
| def read_label(label_path, data_type='MP3D'): | |
| if data_type == 'MP3D': | |
| with open(label_path, 'r') as f: | |
| label = json.load(f) | |
| point_idx = [one['pointsIdx'][0] for one in label['layoutWalls']['walls']] | |
| camera_height = label['cameraHeight'] | |
| room_height = label['layoutHeight'] | |
| camera_ceiling_height = room_height - camera_height | |
| ratio = camera_ceiling_height / camera_height | |
| xyz = [one['xyz'] for one in label['layoutPoints']['points']] | |
| assert len(xyz) == len(point_idx), "len(xyz) != len(point_idx)" | |
| xyz = [xyz[i] for i in point_idx] | |
| xyz = np.asarray(xyz, dtype=np.float32) | |
| xyz[:, 2] *= -1 | |
| xyz[:, 1] = camera_height | |
| corners = xyz2uv(xyz) | |
| elif data_type == 'Pano_S2D3D': | |
| with open(label_path, 'r') as f: | |
| lines = [line for line in f.readlines() if | |
| len([c for c in line.split(' ') if c[0].isnumeric()]) > 1] | |
| corners_list = np.array([line.strip().split() for line in lines], np.float32) | |
| uv_list = pixel2uv(corners_list) | |
| ceil_uv = uv_list[::2] | |
| floor_uv = uv_list[1::2] | |
| ratio = calc_ceil_ratio([ceil_uv, floor_uv], mode='mean') | |
| corners = floor_uv | |
| else: | |
| return None | |
| output = { | |
| 'ratio': np.array([ratio], dtype=np.float32), | |
| 'corners': corners, | |
| 'id': os.path.basename(label_path).split('.')[0] | |
| } | |
| return output | |
| def move_not_simple_image(data_dir, simple_panos): | |
| import shutil | |
| for house_index in os.listdir(data_dir): | |
| house_path = os.path.join(data_dir, house_index) | |
| if not os.path.isdir(house_path) or house_index == 'visualization': | |
| continue | |
| floor_plan_path = os.path.join(house_path, 'floor_plans') | |
| if os.path.exists(floor_plan_path): | |
| print(f'move:{floor_plan_path}') | |
| dst_floor_plan_path = floor_plan_path.replace('zind', 'zind2') | |
| os.makedirs(dst_floor_plan_path, exist_ok=True) | |
| shutil.move(floor_plan_path, dst_floor_plan_path) | |
| panos_path = os.path.join(house_path, 'panos') | |
| for pano in os.listdir(panos_path): | |
| pano_path = os.path.join(panos_path, pano) | |
| pano_index = '_'.join(pano.split('.')[0].split('_')[-2:]) | |
| if f'{house_index}_{pano_index}' not in simple_panos and os.path.exists(pano_path): | |
| print(f'move:{pano_path}') | |
| dst_pano_path = pano_path.replace('zind', 'zind2') | |
| os.makedirs(os.path.dirname(dst_pano_path), exist_ok=True) | |
| shutil.move(pano_path, dst_pano_path) | |
| def read_zind(partition_path, simplicity_path, data_dir, mode, is_simple=True, | |
| layout_type='layout_raw', is_ceiling_flat=False, plan_y=1): | |
| with open(simplicity_path, 'r') as f: | |
| simple_tag = json.load(f) | |
| simple_panos = {} | |
| for k in simple_tag.keys(): | |
| if not simple_tag[k]: | |
| continue | |
| split = k.split('_') | |
| house_index = split[0] | |
| pano_index = '_'.join(split[-2:]) | |
| simple_panos[f'{house_index}_{pano_index}'] = True | |
| # move_not_simple_image(data_dir, simple_panos) | |
| pano_list = [] | |
| with open(partition_path, 'r') as f1: | |
| house_list = json.load(f1)[mode] | |
| for house_index in house_list: | |
| with open(os.path.join(data_dir, house_index, f"zind_data.json"), 'r') as f2: | |
| data = json.load(f2) | |
| panos = [] | |
| merger = data['merger'] | |
| for floor in merger.values(): | |
| for complete_room in floor.values(): | |
| for partial_room in complete_room.values(): | |
| for pano_index in partial_room: | |
| pano = partial_room[pano_index] | |
| pano['index'] = pano_index | |
| panos.append(pano) | |
| for pano in panos: | |
| if layout_type not in pano: | |
| continue | |
| pano_index = pano['index'] | |
| if is_simple and f'{house_index}_{pano_index}' not in simple_panos.keys(): | |
| continue | |
| if is_ceiling_flat and not pano['is_ceiling_flat']: | |
| continue | |
| layout = pano[layout_type] | |
| # corners | |
| corner_xz = np.array(layout['vertices']) | |
| corner_xz[..., 0] = -corner_xz[..., 0] | |
| corner_xyz = np.insert(corner_xz, 1, pano['camera_height'], axis=1) | |
| corners = xyz2uv(corner_xyz).astype(np.float32) | |
| # ratio | |
| ratio = np.array([(pano['ceiling_height'] - pano['camera_height']) / pano['camera_height']], dtype=np.float32) | |
| # Ours future work: detection window, door, opening | |
| objects = { | |
| 'windows': [], | |
| 'doors': [], | |
| 'openings': [], | |
| } | |
| for label_index, wdo_type in enumerate(["windows", "doors", "openings"]): | |
| if wdo_type not in layout: | |
| continue | |
| wdo_vertices = np.array(layout[wdo_type]) | |
| if len(wdo_vertices) == 0: | |
| continue | |
| assert len(wdo_vertices) % 3 == 0 | |
| for i in range(0, len(wdo_vertices), 3): | |
| # In the Zind dataset, the camera height is 1, and the default camera height in our code is also 1, | |
| # so the xyz coordinate here can be used directly | |
| # Since we're taking the opposite z-axis, we're changing the order of left and right | |
| left_bottom_xyz = np.array( | |
| [-wdo_vertices[i + 1][0], -wdo_vertices[i + 2][0], wdo_vertices[i + 1][1]]) | |
| right_bottom_xyz = np.array( | |
| [-wdo_vertices[i][0], -wdo_vertices[i + 2][0], wdo_vertices[i][1]]) | |
| center_bottom_xyz = (left_bottom_xyz + right_bottom_xyz) / 2 | |
| center_top_xyz = center_bottom_xyz.copy() | |
| center_top_xyz[1] = -wdo_vertices[i + 2][1] | |
| center_boundary_xyz = center_bottom_xyz.copy() | |
| center_boundary_xyz[1] = plan_y | |
| uv = xyz2uv(np.array([left_bottom_xyz, right_bottom_xyz, | |
| center_bottom_xyz, center_top_xyz, | |
| center_boundary_xyz])) | |
| left_bottom_uv = uv[0] | |
| right_bottom_uv = uv[1] | |
| width_u = abs(right_bottom_uv[0] - left_bottom_uv[0]) | |
| width_u = 1 - width_u if width_u > 0.5 else width_u | |
| assert width_u > 0, width_u | |
| center_bottom_uv = uv[2] | |
| center_top_uv = uv[3] | |
| height_v = center_bottom_uv[1] - center_top_uv[1] | |
| if height_v < 0: | |
| continue | |
| center_boundary_uv = uv[4] | |
| boundary_v = center_boundary_uv[1] - center_bottom_uv[1] if wdo_type == 'windows' else 0 | |
| boundary_v = 0 if boundary_v < 0 else boundary_v | |
| center_u = center_bottom_uv[0] | |
| objects[wdo_type].append({ | |
| 'width_u': width_u, | |
| 'height_v': height_v, | |
| 'boundary_v': boundary_v, | |
| 'center_u': center_u | |
| }) | |
| pano_list.append({ | |
| 'img_path': os.path.join(data_dir, house_index, pano['image_path']), | |
| 'corners': corners, | |
| 'objects': objects, | |
| 'ratio': ratio, | |
| 'id': f'{house_index}_{pano_index}', | |
| 'is_inside': pano['is_inside'] | |
| }) | |
| return pano_list | |