def pose_estimate_nls(K, Twcg, Ipts, Wpts):
    """
    Estimate camera pose from 2D-3D correspondences via NLS.

    The function performs a nonlinear least squares optimization procedure 
    to determine the best estimate of the camera pose in the calibration
    target frame, given 2D-3D point correspondences.

    Parameters:
    -----------
    Twcg  - 4x4 homogenous pose matrix, initial guess for camera pose.
    Ipts  - 2xn array of cross-junction points (with subpixel accuracy).
    Wpts  - 3xn array of world points (one-to-one correspondence with Ipts).

    Returns:
    --------
    Twc  - 4x4 np.array, homogenous pose matrix, camera pose in target frame.
    """
    maxIters = 250  # Set maximum iterations.

    tp = Ipts.shape[1]  # Num points.
    ps = np.reshape(Ipts, (2 * tp, 1), 'F')  # Stacked vector of observations.

    dY = np.zeros((2 * tp, 1))  # Residuals.
    J = np.zeros((2 * tp, 6))  # Jacobian.

    #--- FILL ME IN ---
    E_pose = epose_from_hpose(Twcg)

    for i in range(maxIters):
        H_pose = hpose_from_epose(E_pose)

        # Constructing A and b matrices to house Jacobian:
        A = np.zeros([6, 6])
        b = np.zeros([6, 1])
        for j in range(Ipts.shape[1]):
            J = find_jacobian(K, H_pose, Wpts[:, j].reshape([3, 1]))

            # Adding J^TJ to A:
            A += J.T.dot(J)

            # Converting to H, finding error E, and adding J^TE to b:
            H_pose_Wpt = np.linalg.inv(H_pose).dot(
                np.vstack((Wpts[:, j].reshape([3, 1]), 1)))
            HK = K.dot(H_pose_Wpt[:-1])
            f = HK / HK[-1]
            E = Ipts[:, j].reshape([2, 1]) - f[:-1]
            b += J.T.dot(E)
        E_pose += np.linalg.inv(A).dot(b)
    #------------------

    return hpose_from_epose(E_pose)
Exemple #2
0
def pose_estimate_nls(K, Twcg, Ipts, Wpts):
    """
    Estimate camera pose from 2D-3D correspondences via NLS.

    The function performs a nonlinear least squares optimization procedure 
    to determine the best estimate of the camera pose in the calibration
    target frame, given 2D-3D point correspondences.

    Parameters:
    -----------
    Twcg  - 4x4 homogenous pose matrix, initial guess for camera pose.
    Ipts  - 2xn array of cross-junction points (with subpixel accuracy).
    Wpts  - 3xn array of world points (one-to-one correspondence with Ipts).

    Returns:
    --------
    Twc  - 4x4 np.array, homogenous pose matrix, camera pose in target frame.
    """
    maxIters = 250  # Set maximum iterations.

    tp = Ipts.shape[1]  # Num points.
    ps = np.reshape(Ipts, (2 * tp, 1), 'F')  # Stacked vector of observations.

    dY = np.zeros((2 * tp, 1))  # Residuals.
    J = np.zeros((2 * tp, 6))  # Jacobian.

    # Run for maxIters
    for iter in range(maxIters):
        # Calculate residuals
        for i in range(tp):
            dY[2 * i:2 * i +
               2, :] = img_pt_from_world_pt(K, Twcg, Wpts[:, i].reshape(
                   (3, 1))) - Ipts[:, i].reshape(2, 1)

        # Calculate jacobian
        for i in range(tp):
            J[2 * i:2 * i + 2, :] = find_jacobian(K, Twcg, Wpts[:, i].reshape(
                (3, 1)))

        # Get update step
        step = np.linalg.inv(J.T @ J) @ J.T @ dY

        # Update parameters
        curr_E = epose_from_hpose(Twcg)
        updated_E = curr_E - step
        Twcg = hpose_from_epose(updated_E)

    Twc = Twcg
    return Twc
Exemple #3
0
def main():
    # Set up test case - fixed parameters.
    K = np.array([[564.9, 0, 337.3], [0, 564.3, 226.5], [0, 0, 1]])
    Wpt = np.array([[0.0635, 0, 0]]).T

    # Camera pose (rotation matrix, translation vector).
    C_cam = np.array(
        [[0.960656116714365, -0.249483426036932, 0.122056730876061],
         [-0.251971275568189, -0.967721063070012, 0.005140075795822],
         [0.116834505638601, -0.035692635424156, -0.992509815603182]])
    t_cam = np.array(
        [[0.201090356081375, 0.114474051344464, 1.193821106321156]]).T

    Twc = np.hstack((C_cam, t_cam))
    Twc = np.vstack((Twc, np.array([[0, 0, 0, 1]])))
    J = find_jacobian(K, Twc, Wpt)
    print(J)
Exemple #4
0
def pose_estimate_nls(K, Twcg, Ipts, Wpts):
    """
    Estimate camera pose from 2D-3D correspondences via NLS.

    The function performs a nonlinear least squares optimization procedure 
    to determine the best estimate of the camera pose in the calibration
    target frame, given 2D-3D point correspondences.

    Parameters:
    -----------
    Twcg  - 4x4 homogenous pose matrix, initial guess for camera pose.
    Ipts  - 2xn array of cross-junction points (with subpixel accuracy).
    Wpts  - 3xn array of world points (one-to-one correspondence with Ipts).

    Returns:
    --------
    Twc  - 4x4 np.array, homogenous pose matrix, camera pose in target frame.
    """
    maxIters = 250  # Set maximum iterations.

    tp = Ipts.shape[1]  # Num points.
    ps = np.reshape(Ipts, (2 * tp, 1), 'F')  # Stacked vector of observations.

    dY = np.zeros((2 * tp, 1))  # Residuals.
    J = np.zeros((2 * tp, 6))  # Jacobian.

    #--- FILL ME IN ---

    #error threshold
    eps = 0.0000001
    #get the original parameters
    X = epose_from_hpose(Twcg)
    #get the H matrix from the original parameters
    Twc = hpose_from_epose(X)
    #Do iterative solver
    for iter in range(0, maxIters):
        #Pre initialize jacobian
        J = np.zeros((2 * tp, 6))
        #Pre initialize projection error
        dY = np.zeros((2 * tp, 1))
        #set the error sum to 0
        res_sum = 0
        #calculate jacobian and error for all the points
        for index, row in enumerate(Wpts.T):
            J[index * 2:(index + 1) * 2, :] = find_jacobian(
                K, Twc, row.reshape(3, 1))
            dY[index * 2:(index + 1) *
               2, :] = (Ipts[:, index] -
                        Wpts_to_Ipts(K, Twc, Wpts)[:, index]).reshape(2, 1)
            #add the error to the error sum
            res_sum += np.sum(dY[index * 2:(index + 1) * 2, :])
        #in case the matrix became singular through multiple iterations
        try:
            #calculate the increment to the X vector (parameter vector)
            dx = np.dot(np.dot(inv(np.dot(J.T, J)), J.T), dY)
        except:
            return Twc
        #move in the direction of the jacobian and update the parameter vector
        X = X + dx
        #get the H matrix
        Twc = hpose_from_epose(X)
        #check if we are below the threshold to return as well
        if (np.abs(res_sum) < eps):
            break

    #------------------
    return Twc
Exemple #5
0
import numpy as np
from find_jacobian import find_jacobian

# Set up test case - fixed parameters.
K = np.array([[564.9, 0, 337.3], [0, 564.3, 226.5], [0, 0, 1]])
Wpt = np.array([[0.0635, 0, 0]]).T

# Camera pose (rotation matrix, translation vector).
C_cam = np.array([[0.960656116714365, -0.249483426036932, 0.122056730876061],
                  [-0.251971275568189, -0.967721063070012, 0.005140075795822],
                  [0.116834505638601, -0.035692635424156, -0.992509815603182]])
t_cam = np.array([[0.201090356081375, 0.114474051344464, 1.193821106321156]]).T

Twc = np.hstack((C_cam, t_cam))
Twc = np.vstack((Twc, np.array([[0, 0, 0, 1]])))
J = find_jacobian(K, Twc, Wpt)
print(J)

# J =
# -477.1016  121.4005   43.3460  -18.8900  592.2179  -71.3193
#  130.0713  468.1394  -59.8803  578.8882  -14.6399  -49.5217
Exemple #6
0
def pose_estimate_nls(K, Twcg, Ipts, Wpts):
    """
    Estimate camera pose from 2D-3D correspondences via NLS.

    The function performs a nonlinear least squares optimization procedure 
    to determine the best estimate of the camera pose in the calibration
    target frame, given 2D-3D point correspondences.

    Parameters:
    -----------
    Twcg  - 4x4 homogenous pose matrix, initial guess for camera pose.
    Ipts  - 2xn array of cross-junction points (with subpixel accuracy).
    Wpts  - 3xn array of world points (one-to-one correspondence with Ipts).

    Returns:
    --------
    Twc  - 4x4 np.array, homogenous pose matrix, camera pose in target frame.
    """
    maxIters = 250                          # Set maximum iterations.

    tp = Ipts.shape[1]                      # Num points.
    ps = np.reshape(Ipts, (2*tp, 1), 'F')   # Stacked vector of observations.

    dY = np.zeros((2*tp, 1))                # Residuals.
    J  = np.zeros((2*tp, 6))                # Jacobian.

    #--- FILL ME IN ---

    E = epose_from_hpose(np.linalg.inv(Twcg))
    for iter in range(maxIters):
        Twc = np.linalg.inv(hpose_from_epose(E))

        sum1 = np.reshape(np.zeros(36),(6,6))
        sum2 = np.reshape(np.zeros(6),(6,1))
        for i in range(tp):
            Wpt = np.vstack((np.array([Wpts[0][i]]), np.array([Wpts[1][i]]), np.array([Wpts[2][i]])))
            Wpt_til = np.vstack((np.array([Wpts[0][i]]), np.array([Wpts[1][i]]), np.array([Wpts[2][i]]), np.array([1])))
            Ipt = np.vstack((np.array([Ipts[0][i]]), np.array([Ipts[1][i]])))
            J = find_jacobian(K, Twc, Wpt)

            #find error
            K_til = np.hstack((K,np.array([[0],[0],[0]])))
            K_til = np.vstack((K_til,np.array([0,0,0,1])))
            x_til = K_til@(np.linalg.inv(Twc))@Wpt_til
            x = x_til[0:2]/x_til[2]
            e = x-Ipt

            sum1 += J.T@J
            sum2 += J.T@e
        update = np.linalg.inv(sum1)@sum2

        E = epose_from_hpose(np.linalg.inv(Twc))

        E[0][0] += update[0][0]
        E[1][0] += update[1][0]
        E[2][0] += update[2][0]
        E[3][0] += update[3][0]
        E[4][0] += update[4][0]
        E[5][0] += update[5][0]

    Twc = np.linalg.inv(hpose_from_epose(E))
    #------------------
    
    #return Twc
    return Twc