示例#1
0
文件: tf_utils.py 项目: psodhi/logo
def tf2d_compose(pose1, pose12):
    """
    Composing pose1 with pose12, i.e. T2 = T1*T12
    :param pose1: n x 3 tensor [x,y,yaw]
    :param pose12: n x 3 tensor [x,y,yaw]
    :return: pose2 n x 3 tensor [x,y,yaw]
    """

    num_data = pose1.shape[0]

    rot1 = torch.cat([torch.zeros(num_data, 1), torch.zeros(
        num_data, 1), pose1[:, 2][:, None]], 1)
    rot12 = torch.cat([torch.zeros(num_data, 1), torch.zeros(
        num_data, 1), pose12[:, 2][:, None]], 1)
    t1 = torch.cat([pose1[:, 0][:, None], pose1[:, 1]
                    [:, None], torch.zeros(num_data, 1)], 1)
    t12 = torch.cat([pose12[:, 0][:, None], pose12[:, 1]
                    [:, None], torch.zeros(num_data, 1)], 1)

    R1 = p3d_t.euler_angles_to_matrix(rot1, "XYZ")
    R12 = p3d_t.euler_angles_to_matrix(rot12, "XYZ")

    R2 = torch.matmul(R1, R12)
    rot2 = p3d_t.matrix_to_euler_angles(R2, "XYZ")
    t2 = torch.matmul(R1, t12[:, :, None]) + t1[:, :, None]
    t2 = t2[:, :, 0]

    tx = t2[:, 0][:, None]
    ty = t2[:, 1][:, None]
    yaw = rot2[:, 2][:, None]
    pose2 = torch.cat([tx, ty, yaw], 1)

    return pose2
示例#2
0
文件: tf_utils.py 项目: psodhi/logo
def tf2d_between(pose1, pose2, device=None, requires_grad=None):
    """
    Relative transform of pose2 in pose1 frame, i.e. T12 = T1^{1}*T2
    :param pose1: n x 3 tensor [x,y,yaw]
    :param pose2: n x 3 tensor [x,y,yaw]
    :return: pose12 n x 3 tensor [x,y,yaw]
    """

    num_data = pose1.shape[0]

    rot1 = torch.cat([torch.zeros(num_data, 1, device=device, requires_grad=requires_grad), torch.zeros(
        num_data, 1, device=device, requires_grad=requires_grad), pose1[:, 2][:, None]], 1)
    rot2 = torch.cat([torch.zeros(num_data, 1, device=device, requires_grad=requires_grad), torch.zeros(
        num_data, 1, device=device, requires_grad=requires_grad), pose2[:, 2][:, None]], 1)
    t1 = torch.cat([pose1[:, 0][:, None], pose1[:, 1]
                    [:, None], torch.zeros(num_data, 1, device=device, requires_grad=requires_grad)], 1)
    t2 = torch.cat([pose2[:, 0][:, None], pose2[:, 1]
                    [:, None], torch.zeros(num_data, 1, device=device, requires_grad=requires_grad)], 1)

    R1 = p3d_t.euler_angles_to_matrix(rot1, "XYZ")
    R2 = p3d_t.euler_angles_to_matrix(rot2, "XYZ")
    R1t = torch.inverse(R1)

    R12 = torch.matmul(R1t, R2)
    rot12 = p3d_t.matrix_to_euler_angles(R12, "XYZ")
    t12 = torch.matmul(R1t, (t2-t1)[:, :, None])
    t12 = t12[:, :, 0]

    tx = t12[:, 0][:, None]
    ty = t12[:, 1][:, None]
    yaw = rot12[:, 2][:, None]
    pose12 = torch.cat([tx, ty, yaw], 1)

    return pose12
示例#3
0
def random_rotation(pc, theta=45., euler_order='XYZ', dev=default_dev):
    '''
        Apply random rotation to point cloud and return both
        Output: Angles - radian, Rot - (3, 3) matrix, PC - Point cloud
    '''
    angles = torch.rand(size=(3, ), device=dev) * np.radians(theta)
    rot = transforms.euler_angles_to_matrix(angles, euler_order)
    return angles, rot, pc @ rot.T  # x.T * R.T <=> R * x
示例#4
0
def get_extrinsic_matrix(pose):
    """
    Returns the rotation matrix representation of the
    rotations and translations from pose.
    """
    batch_size, _ = pose.shape
    rot = pose[:,:3]
    trans = pose[:,3:]

    rot = transforms.euler_angles_to_matrix(rot,convention="XYZ")
    pose = torch.cat((rot,trans.view(batch_size, 3, 1)), -1)

    return pose
示例#5
0
    def __init__(self, num_hypotheses=8, device="cuda", **kwargs):
        """

        :param num_hypotheses: number of camera poses which should be predicted.
        :param kwargs: arguments which are passed through to the single camera predictors
        """
        super(MultiCameraPredictor, self).__init__()
        _encoder = get_encoder(trainable=False)

        self.num_hypotheses = num_hypotheses

        self.cam_preds = nn.ModuleList([
            CameraPredictor(encoder=_encoder, **kwargs)
            for _ in range(num_hypotheses)
        ])

        # taken from the original repo
        base_rotation = matrix_to_quaternion(
            euler_angles_to_matrix(
                torch.FloatTensor([0.5, 0, 0]) * np.pi,
                "XYZ")).unsqueeze(0)  # rotation by PI/2 around the x-axis
        base_bias = matrix_to_quaternion(
            euler_angles_to_matrix(
                torch.FloatTensor([0, 0.25, 0]) * np.pi,
                "XYZ")).unsqueeze(0)  # rotation by PI/4 around the y-axis

        # base_rotation = torch.FloatTensor(
        #     [0.9239, 0, 0.3827, 0]).unsqueeze(0).unsqueeze(0)  # pi/4 (45° )
        # # base_rotation = torch.FloatTensor([ 0.7071,  0 , 0.7071,   0]).unsqueeze(0).unsqueeze(0) ## pi/2
        # base_bias = torch.FloatTensor(
        #     [0.7071, 0.7071, 0, 0]).unsqueeze(0).unsqueeze(0)  # 90° by x-axis

        # taken from the original repo
        self.cam_biases = [base_bias]
        for i in range(1, self.num_hypotheses):
            self.cam_biases.append(
                quaternion_multiply(base_rotation, self.cam_biases[i - 1]))

        self.cam_biases = torch.stack(self.cam_biases).squeeze().to(device)
示例#6
0
def infer_and_save_pose(input_file_refs, input_file, model_wrapper,
                        image_shape, half, save):
    """
    Process a single input file to produce and save visualization

    Parameters
    ----------
    input_file_refs : list(str)
        Reference image file paths
    input_file : str
        Image file for pose estimation
    model_wrapper : nn.Module
        Model wrapper used for inference
    image_shape : Image shape
        Input image shape
    half: bool
        use half precision (fp16)
    save: str
        Save format (npz or png)
    """
    base_name = os.path.basename(input_file)

    # change to half precision for evaluation if requested
    dtype = torch.float16 if half else None

    # Load image
    def process_image(filename):
        image = load_image(filename)
        # Resize and to tensor
        image = resize_image(image, image_shape)
        image = to_tensor(image).unsqueeze(0)

        # Send image to GPU if available
        if torch.cuda.is_available():
            image = image.to('cuda:{}'.format(rank()), dtype=dtype)
        return image

    image_ref = [
        process_image(input_file_ref) for input_file_ref in input_file_refs
    ]
    image = process_image(input_file)

    # Depth inference (returns predicted inverse depth)
    pose_tensor = model_wrapper.pose(
        image, image_ref)[0][0]  # take the pose from 1st to 2nd image

    rot_matrix = transforms.euler_angles_to_matrix(pose_tensor[3:],
                                                   convention="ZYX")
    translation = pose_tensor[:3]

    poses[base_name] = (rot_matrix, translation)
示例#7
0
def transpose_rotation(rotation: Rotation) -> Rotation:
    """ As for ortho6d and euler, we will first convert to matrix, then transpose.
    As others, we will use 
    """
    # 1. TRANSPOSE ORTHO6D
    matrix = compute_rotation_matrix_from_ortho6d(rotation.ortho6d).transpose(
        2, 1)
    ortho6d = compute_ortho6d_from_rotation_matrix(matrix)

    # 2. TRANSPOSE EULER
    matrix = euler_angles_to_matrix(rotation.euler,
                                    convention="XYZ").transpose(2, 1)
    euler = matrix_to_euler_angles(matrix, convention="XYZ")

    # 3. TRANSPOSE QUAT
    quat = quaternion_invert(rotation.quat)

    # 4. TRANSPOSE MATRIX
    matrix = rotation.matrix.transpose(2, 1)

    return Rotation(ortho6d=ortho6d, quat=quat, matrix=matrix, euler=euler)
def matrix_from_angles(rot):
    """Create a rotation matrix from a triplet of rotation angles.
    Args:
    rot: a torch.Tensor of shape [..., 3], where the last dimension is the rotation
        angles, along x, y, and z.
    Returns:
    A torch.tensor of shape [..., 3, 3], where the last two dimensions are the
    rotation matrix.
    This function mimics _euler2mat from struct2depth/project.py, for backward
    compatibility, but wraps tensorflow_graphics instead of reimplementing it.
    The negation and transposition are needed to bridge the differences between
    the two.
    """
    rank = rot.dim()
    # Swap the two last dimensions
    perm = torch.cat([
        torch.arange(0, rank - 1, dtype=torch.long),
        torch.tensor([rank]),
        torch.tensor([rank - 1])
    ],
                     dim=0)
    return euler_angles_to_matrix(-rot, convention="XYZ").permute(*perm)
示例#9
0
def build_rotation(rotation, format="matrix") -> Rotation:
    """ Convert roation (with format) into Rotation.
    format: matrix, ortho6d, quat, euler
    """
    # 1. CONVERT SPECIFIED FORMAT TO MATRIX FIRST
    if format == "matrix":
        matrix = rotation
    elif format == "ortho6d":
        matrix = compute_rotation_matrix_from_ortho6d(rotation)
    elif format == "euler":
        matrix = euler_angles_to_matrix(rotation, convention="XYZ")
    elif format == "quat":
        matrix = quaternion_to_matrix(rotation)
    else:
        raise TypeError

    # 2. BUILD ROTATION
    return Rotation(
        ortho6d=rotation if format == "ortho6d" else
        compute_ortho6d_from_rotation_matrix(matrix),
        quat=rotation if format == "quat" else matrix_to_quaternion(matrix),
        matrix=rotation if format == "matrix" else matrix,
        euler=rotation if format == "euler" else matrix_to_euler_angles(
            matrix, convention="XYZ"))