def split_by_seg_label(points, labels):
    """split the point cloud into semantic segments
    

    Args:
        points [N, 3]
        labels [N_top, 2] only top lidar points are labeled,
                          channels are [instance, segment]

    Returns:
        three segments in shape [N_i, 3]:
            road: segment class {18 (road), 19 (lane marker)}
            sidewalk: segment class {17 (curb), 20 (other ground),
                             21 (walkable), 22 (sidewalk)}
            other_obj: any segment class except road and walkable

        labels [N_other_obj, 2]
    """
    
    # drop points from other lidar sensor (no seg label)
    points = points[:labels.shape[0]]

    seg_labels = labels[:, 1]
    
    road_mask = seg_labels == 10
    sidewalk_mask = seg_labels == 11
    other_obj_mask = (road_mask == False) & (sidewalk_mask == False)
    
    road = points[road_mask, :3]
    sidewalk = points[sidewalk_mask, :3]
    other_obj = points[other_obj_mask, :3]
    labels = labels[other_obj_mask, :]
    
    return road, sidewalk, other_obj, labels