示例#1
0
    def __init__(self,
                 root_dataset,
                 ocam_dict,
                 pose_dict,
                 level,
                 reduction=2,
                 transform=None,
                 border_value=[256 // 2, 256 // 2, 256 // 2]):
        self.root_dataset = root_dataset
        self.ocam_dict = ocam_dict
        self.pose_dict = pose_dict
        self.level = level
        self.transform = transform

        # fisheye to ico
        self.vertices, self.faces = get_icosahedron(level)
        self.fisheye_mapxy_pad = {}
        for key in self.ocam_dict:
            self.fisheye_mapxy_pad[key] = mapxy_fisheye_to_ico(
                self.ocam_dict[key], self.pose_dict[key], self.level)

        # idepth to ico
        self.idepth_level = level - reduction
        self.idepth_mapxy_pad = self._mapxy_idepth_to_ico(self.idepth_level)
        self.idepth_coord = get_unfold_imgcoord(self.idepth_level,
                                                drop_NE=False)

        # out of fov value
        self.border_value = border_value
示例#2
0
def calculate_weight(level=0):
    """ calculate weight alpha
    """
    img_coord = get_unfold_imgcoord(level, False)
    vertices, _ = get_icosahedron(level)
    key = 0
    vi_idx = img_coord[key][1:, 1:]
    vn1_idx = img_coord[key][1:, :-1]
    vn6_idx = img_coord[key][:-1, 1:]
    vi = vertices[vi_idx]
    vn1 = vertices[vn1_idx]
    vn6 = vertices[vn6_idx]

    # vector from vi to north pole
    north_pole = np.array([0, -1, 0])
    to_north_pole = north_pole - vi

    # unit vector from vi to neighbor
    vn1vi = vn1 - vi
    vn1vi /= norm(vn1vi, axis=-1, keepdims=True)
    vn6vi = vn6 - vi
    vn6vi /= norm(vn6vi, axis=-1, keepdims=True)

    # face normal
    face_n = np.cross(vn1vi, vn6vi)
    face_n /= norm(face_n, axis=-1, keepdims=True)

    # to north pole on tangent plane
    proj_vec = np.sum(to_north_pole * face_n, axis=-1, keepdims=True) * face_n
    np_tangent_plane = to_north_pole - proj_vec
    np_tangent_plane /= norm(np_tangent_plane, axis=-1, keepdims=True)

    # calculate cost
    psi = np.arccos(np.sum(vn1vi * np_tangent_plane, axis=-1))
    tmp_vals = np.sum(vn6vi * np_tangent_plane, axis=-1)
    tmp_vals[0, 0] = np.clip(tmp_vals[0, 0], -1,
                             1)  # make sure value is between -1 and 1
    phi = np.arccos(tmp_vals)
    base_weight = phi / (psi + phi)

    weight = np.concatenate((np.flip(base_weight[-1:]), base_weight), axis=0)
    weight = np.concatenate((np.flip(weight[:, -1:]), weight), axis=1)

    # top_weight = base_weight[-1][::-1]
    # left_weight = base_weight[:, -1][::-1]
    # weight = np.zeros(img_coord[0].shape)
    # weight[0, 0] = 0.5 # index 0 weight
    # weight[1:, 1:] = base_weight
    # weight[0, 1:] = top_weight
    # weight[1:, 0] = left_weight

    # to row weight
    h, w = weight.shape
    weight_row = 1 - np.concatenate((weight[:w], weight[w - 1:, 1:]), axis=1)

    return weight, weight_row
示例#3
0
def ico_to_erp_idx_weight(level, h=300, w=600):
    xyz = uv2xyz(genuv(h, w))
    pts_c = xyz.reshape(-1, 3)

    v, f = get_icosahedron(level)
    kdtree = cKDTree(v)
    _, tmp_indices = kdtree.query(pts_c, k=4)
    (v0_idx, v1_idx, v2_idx), (weight_0, weight_1,
                               weight_2) = weight_for_triangle_interpolation(
                                   v, tmp_indices, pts_c)
    return (v0_idx, v1_idx, v2_idx), (weight_0, weight_1, weight_2)
示例#4
0
    def _mapxy_idepth_to_ico(self, level):
        v, f = get_icosahedron(level)
        mapy, mapx = uv2img_idx(xyz2uv(v), h=320, w=640)

        # reshape to prevent shrt_max error in remap
        # https://answers.opencv.org/question/203798/shrt_max-in-cv2remap/
        len_v = len(v)**0.5
        tmp_h = int(len_v) + 1
        pad_w = tmp_h * tmp_h - mapx.shape[0]
        mapx = np.pad(mapx, (0, pad_w), 'constant', constant_values=-1)
        mapy = np.pad(mapy, (0, pad_w), 'constant', constant_values=-1)
        mapx = mapx.reshape(tmp_h, tmp_h).astype(np.float32)
        mapy = mapy.reshape(tmp_h, tmp_h).astype(np.float32)
        return mapx, mapy, pad_w
示例#5
0
    def __init__(self,
                 dataset,
                 erp_shape,
                 level,
                 rotate=False,
                 transform=None,
                 debug=False):
        self.dataset = dataset
        self.transform = transform
        self.erp_shape = erp_shape
        self.level = level
        self.rotate = rotate

        self.vertices, self.faces = get_icosahedron(level)

        self.img_coord = get_unfold_imgcoord(level)

        self.debug = debug
示例#6
0
def icospherical_sweep_grid(Tcw_bytes, center_bytes, depth, level, fov=220, only_translation=False):
    # numpy array is not hashable so give array as array.tobytes()
    Tcw = np.frombuffer(Tcw_bytes).reshape(4, 4)
    center = np.frombuffer(center_bytes)

    # ------------------------------------
    # find projected points on sphere
    v, f = get_icosahedron(level)
    pts_w = depth * v + center

    # pt_c = T_cw*pt_w
    if only_translation:
        # dataloader deal with rotation
        Twc = np.linalg.inv(Tcw)
        pts_c = pts_w.T - Twc[:3, 3:4]
        cam_dir = Twc[:3, :3].dot([0, 0, 1])
    else:
        pts_c = Tcw[:3, :3].dot(pts_w.T) + Tcw[:3, 3:4]
        cam_dir = [0, 0, 1]
    pts_c = pts_c.T
    pts_c /= norm(pts_c, axis=1, keepdims=True)

    # ------------------------------------
    # extract inside fov
    fov_rad = np.deg2rad(fov / 2)
    cos_vals = pts_c.dot(cam_dir)
    is_inside = np.cos(fov_rad) < cos_vals
    # nearest neighbor search
    kdtree = get_KDTree(level)
    tmp_distances, tmp_indices = kdtree.query(pts_c[is_inside], k=4)
    #     tmp_distances, tmp_indices = kdtree.kneighbors(pts_c[is_inside])

    # ------------------------------------
    # calculate weight
    vertex_ids, (weight_0, weight_1, weight_2) = weight_for_triangle_interpolation(v, tmp_indices, pts_c[is_inside])
    # (v0_idx, v1_idx, v2_idx) = vertex_ids

    weight_0 = torch.from_numpy(weight_0).float()
    weight_1 = torch.from_numpy(weight_1).float()
    weight_2 = torch.from_numpy(weight_2).float()

    return vertex_ids, (weight_0, weight_1, weight_2), is_inside
示例#7
0
def mapxy_fisheye_to_ico(ocam, T_wc=np.eye(4), level=0):
    """Map to project a fisheye image to icosahedron surface

    Parameters
    ----------
    ocam : OCamCamera (https://github.com/matsuren/ocamcalib_undistort)
        OcamCalib camera class object
    level : int
        icosahedron resolution level

    Examples
    --------
    >>> mapx, mapy, pad_w = mapxy_fisheye_to_ico(ocam, level)
    >>> ico_img = cv2.remap(img, mapx, mapy,cv2.INTER_LINEAR)
    >>> ico_img = ico_img.reshape(-1, 3)[:-pad_w]
    """
    # get vertices
    v, f = get_icosahedron(level)
    # rotate vertices
    T_cw = np.linalg.inv(T_wc)
    rot_v = T_cw[:3, :3].dot(v.T)
    mapx, mapy = ocam.world2cam(rot_v)

    # reshape to prevent shrt_max error in remap
    # https://answers.opencv.org/question/203798/shrt_max-in-cv2remap/
    # from scipy.ndimage.interpolation import map_coordinates is slow
    # so I chose to use opencv remap
    len_v = len(v)**0.5
    tmp_h = int(len_v) + 1
    pad_w = tmp_h * tmp_h - mapx.shape[0]
    mapx = np.pad(mapx, (0, pad_w), 'constant', constant_values=-1)
    mapy = np.pad(mapy, (0, pad_w), 'constant', constant_values=-1)
    mapx = mapx.reshape(tmp_h, tmp_h)
    mapy = mapy.reshape(tmp_h, tmp_h)

    return mapx, mapy, pad_w
示例#8
0
def get_KDTree(level):
    v, f = get_icosahedron(level)
    return cKDTree(v)