|
""" |
|
@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 |
|
|
|
|
|
|
|
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] |
|
|
|
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 = np.array([(pano['ceiling_height'] - pano['camera_height']) / pano['camera_height']], dtype=np.float32) |
|
|
|
|
|
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): |
|
|
|
|
|
|
|
|
|
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 |
|
|