コード例 #1
0
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)
コード例 #2
0
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)
コード例 #3
0
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