def render_suncg_raw_house_walls(house_fn): from suncg import split_room_parts, Suncg with open(house_fn) as f: house = json.loads(f.read()) scaleToMeters = house['scaleToMeters'] assert scaleToMeters == 1 bboxes = defaultdict(list) bboxes['house'].append(Bbox3D.bbox_from_minmax(house['bbox'])) for level in house['levels']: if 'bbox' not in level: continue bboxes['level'].append(Bbox3D.bbox_from_minmax(level['bbox'])) nodes = level['nodes'] for node in nodes: node_type = node['type'] if node_type == 'Object': modelId = node['modelId'] category = Suncg.modelId_2_class[modelId] bboxes[category].append(Bbox3D.bbox_from_minmax(node['bbox'])) elif node_type == 'Room': if 'bbox' in node: bboxes['room'].append(Bbox3D.bbox_from_minmax( node['bbox'])) room_bboxes = split_room_parts(house_fn, node['modelId']) for c in room_bboxes: bboxes[c] += room_bboxes[c] else: if 'bbox' in node: bboxes[node_type].append( Bbox3D.bbox_from_minmax(node['bbox'])) centroid = (np.array(house['bbox']['min']) + np.array(house['bbox']['max'])) / 2.0 mesh_frame = open3d.create_mesh_coordinate_frame(size=0.6, origin=centroid) for obj in bboxes: bboxes[obj] = np.concatenate([b.reshape([1, 7]) for b in bboxes[obj]], 0) bboxes[obj] = cam2world_box(bboxes[obj]) walls = bboxes['wall'] print('\nThe raw SUNCG walls\n') #Bbox3D.draw_bboxes(walls, up_axis='Z', is_yx_zb=False) Bbox3D.draw_bboxes_mesh(walls, up_axis='Z', is_yx_zb=False)
def gen_bbox(house_fn): always_gen_bbox = Debug and 0 parsed_dir = get_pcl_path(house_fn) summary = read_summary(parsed_dir) box_intact = 'level_num' in summary and 'wall_num' in summary if box_intact and (not always_gen_bbox): print(f'skip gen_bbox, summary intact: {parsed_dir}') return with open(house_fn) as f: house = json.loads(f.read()) scaleToMeters = house['scaleToMeters'] assert scaleToMeters == 1 bboxes = defaultdict(list) bboxes['house'].append(Bbox3D.bbox_from_minmax(house['bbox'])) for level in house['levels']: if 'bbox' not in level: continue bboxes['level'].append(Bbox3D.bbox_from_minmax(level['bbox'])) nodes = level['nodes'] for node in nodes: node_type = node['type'] if node_type == 'Object': modelId = node['modelId'] category = Suncg.modelId_2_class[modelId] bboxes[category].append(Bbox3D.bbox_from_minmax(node['bbox'])) elif node_type == 'Room': if 'bbox' in node: bboxes['room'].append(Bbox3D.bbox_from_minmax( node['bbox'])) room_bboxes = split_room_parts(house_fn, node['modelId']) for c in room_bboxes: bboxes[c] += room_bboxes[c] else: if 'bbox' in node: bboxes[node_type].append( Bbox3D.bbox_from_minmax(node['bbox'])) centroid = (np.array(house['bbox']['min']) + np.array(house['bbox']['max'])) / 2.0 mesh_frame = open3d.create_mesh_coordinate_frame(size=0.6, origin=centroid) for obj in bboxes: if len(bboxes[obj]) > 0: bboxes[obj] = np.concatenate( [b.reshape([1, 7]) for b in bboxes[obj]], 0) else: bboxes[obj] = np.array(bboxes[obj]).reshape([-1, 7]) bboxes[obj] = cam2world_box(bboxes[obj]) for obj in DSET_METAS0.class_2_label: if obj == 'background': continue if obj not in bboxes: bboxes[obj] = np.array(bboxes[obj]).reshape([-1, 7]) level_num = len(house['levels']) if level_num == 1: bboxes['wall'] = preprocess_walls(bboxes['wall']) bboxes['window'] = preprocess_windows(bboxes['window'], bboxes['wall']) bboxes['door'] = preprocess_doors(bboxes['door'], bboxes['wall']) bboxes['ceiling_raw'] = bboxes['ceiling'].copy() bboxes['floor_raw'] = bboxes['floor'].copy() bboxes['ceiling'] = preprocess_cfr(bboxes['ceiling'], bboxes['wall'], 'ceiling') bboxes['floor'] = preprocess_cfr(bboxes['floor'], bboxes['wall'], 'floor') # save bbox in ply and txt object_bbox_dir = os.path.join(parsed_dir, 'object_bbox') if not os.path.exists(object_bbox_dir): os.makedirs(object_bbox_dir) bboxes_num = {} for category in bboxes.keys(): bboxes_num[category] = len(bboxes[category]) boxes_fn = os.path.join(object_bbox_dir, category + '.txt') boxes = np.array(bboxes[category]) np.savetxt(boxes_fn, boxes) ####################### print(f'parsed_dir: {parsed_dir}') write_summary(parsed_dir, 'level_num', level_num, 'a') for obj in ['room', 'wall', 'window', 'door', 'floor', 'ceiling']: write_summary(parsed_dir, f'{obj}_num', bboxes_num[obj], 'a') ####################### save_ply = False if save_ply: for category in bboxes.keys(): for i, bbox in enumerate(bboxes[category]): box_dir = os.path.join(object_bbox_dir, '{}'.format(category)) if not os.path.exists(box_dir): os.makedirs(box_dir) box_fn = os.path.join(box_dir, '%d.ply' % (i)) bbox_cam = world2cam_box(bbox.reshape([1, 7]))[0] Bbox3D.draw_bbox_open3d(bbox_cam, 'Y', plyfn=box_fn)
def get_part_bbox(vertices, triangle, triangle_norms, name=''): ''' bbox: [xc, yc, zc, x_size, y_size, z_size, yaw] ''' #show_mesh(vertices, triangle) class_name = name.split('#')[0] box_min = np.min(vertices, 0) box_max = np.max(vertices, 0) centroid = (box_min + box_max) / 2.0 y_size = box_max[1] - box_min[1] ## Find the 8 outside corners distances = np.linalg.norm(vertices - np.expand_dims(centroid, 0), axis=1) max_dis = max(distances) out_corner_mask = (abs(distances - max_dis) < 1e-5) n0 = vertices.shape[0] #print([i for i in range(n0) if out_corner_mask[i]]) out_vertices = [ vertices[i:i + 1, :] for i in range(n0) if out_corner_mask[i] ] if len(out_vertices) == 0: import pdb pdb.set_trace() # XXX BREAKPOINT pass return None out_vertices = np.concatenate(out_vertices, 0) if out_vertices.shape[0] != 8: #Bbox3D.draw_points_open3d(out_vertices, show=True) #Bbox3D.draw_points_open3d(vertices, show=True) #show_mesh(vertices, triangle) if class_name not in ENABLE_NO_RECTANGLE: print( f'\nFailed to find bbox, not rectangle, {class_name} \n {out_vertices.shape[0]} vertices\n' ) assert False import pdb pdb.set_trace() # XXX BREAKPOINT pass return None else: print( f'\nNot rectangle, use no yaw box, {class_name} \n {out_vertices.shape[0]} vertices\n' ) min_max = {'min': box_min, 'max': box_max} bbox_noyaw = Bbox3D.bbox_from_minmax(min_max) #Bbox3D.draw_points_bboxes(vertices, bbox_noyaw, 'Y', is_yx_zb=False) return bbox_noyaw ## Find the 4 corners on one side x_right_mask = out_vertices[:, 0] - centroid[0] > 0 x_right_corners = np.concatenate( [out_vertices[i:i + 1, :] for i in range(8) if x_right_mask[i]], 0) assert x_right_corners.shape[0] == 4 x_right_cen = np.mean(x_right_corners, 0) ## get length x_size = np.linalg.norm(x_right_cen - centroid) * 2 if not abs(x_right_cen[1] - centroid[1]) < 1e-7: print("y should be same, pitch and rool should be 0") ## the angle between x_right_cen and x axis x_direc = x_right_cen - centroid x_direc = (x_direc) / np.linalg.norm(x_direc) x_axis = np.array([1, 0, 0]) # [-90, 90] yaw = np.arccos(np.sum(x_direc * x_axis)) if abs(yaw) < 0.01: yaw = 0 else: assert x_direc[0] > 0 assert x_direc[1] == 0 yaw *= np.sign(x_direc[2]) ## Find the 2 corners at top within x_right_corners top_mask = x_right_corners[:, 1] - centroid[1] > 0 x_right_top_corners = np.concatenate( [x_right_corners[i:i + 1, :] for i in range(4) if top_mask[i]], 0) assert x_right_top_corners.shape[0] == 2 # get z_size z_size = np.linalg.norm(x_right_top_corners[0] - x_right_top_corners[1]) ### got the bbox xc, yc, zc = centroid bbox = np.array([xc, yc, zc, x_size, y_size, z_size, yaw]) ### Check if yaw != 0 and False: Bbox3D.draw_bboxes(bbox, 'Y', False) if False: min_max = {'min': box_min, 'max': box_max} bbox_noyaw = Bbox3D.bbox_from_minmax(min_max) bboxes_show = np.concatenate( [bbox.reshape([1, 7]), bbox_noyaw.reshape([1, 7])], 0) Bbox3D.draw_points_bboxes(vertices, bboxes_show, 'Y', is_yx_zb=False) return bbox