Ask Your Question
0

OpenCV solvePnPRansac() function

asked 2020-07-03 01:13:57 -0600

Sara Ahmed gravatar image

I am working on a 3D model reconstruction form multiple images project.

I have the camera matrix as well as 2D-3D point correspondence. I want to compute the projection matrix. I used cv.solvePnPRansac()function to get the projection matrix as follow:

retval, rvec, tvec, inliers = cv.solvePnPRansac(np.ascontiguousarray(np.squeeze(np.array(selectedpts3D)) [:,:-1]).reshape(len(selectedpts3D),1,3), np.ascontiguousarray(np.array(pts)[:,:-1]).reshape(len(pts),1,2), np.array(K_global), np.array([]), flags = cv.SOLVEPNP_ITERATIVE) 

rvec_matrix = cv.Rodrigues(rvec)[0]

proj_matrix = np.hstack((rvec_matrix, tvec))

Then I factorize the output projection matrix to get camera matrix, rotation matrix and translation matrix as follow:

def factorize_proj_matrix(P):
    """ Factorize the camera matrix into K,R,t as P = K[R|t]. """
    # factor first 3*3 part
    K1,R = linalg.rq(P[:,:3])
    # make diagonal of K positive
    T = np.diag(np.sign(np.diag(K1)))
       if np.linalg.det(T) < 0:
         T[1,1] *= -1
   K1 = np.dot(K1,T)
   R = np.dot(T,R) # T is its own inverse
   t = np.dot(np.linalg.inv(K1),P[:,3])
    return K1, R, t.reshape(3,1)

but the resulted camera matrix "K" has different values than the passed camera matrix to solvePnPRansac() function.

passed camera matrix to function is:

  [[1.5204e+03 0.0000e+00 3.0232e+02]
   [0.0000e+00 1.5259e+03 2.4687e+02]
   [0.0000e+00 0.0000e+00 1.0000e+00]]

output camera matrix is:

  array([[ 2.43791400e-03, -7.07610743e-21,  3.23838460e-22],
            [ 0.00000000e+00,  2.43791400e-03, -2.88994138e-22],
            [ 0.00000000e+00,  0.00000000e+00,  2.43791400e-03]])

My question is does cv.solvePnPRansac() function changes the cameraMatrix. if yes how to enforce it not to change the camera matrix?

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
0

answered 2020-10-08 10:44:33 -0600

RashidLadj gravatar image

updated 2020-10-09 02:45:32 -0600

Code:

Rotation_matrix_T = cv.Rodrigues(rvec)[0]
Rotation_matrix = Rotation_matrix_T.T
Translate_vector = - np.dot(Rotation_matrix , tvec)

Transformation_matrix = np.eye(4)
Transformation_matrix[:3, :3] = Rotation_matrix
Transformation_matrix[:3,  3] = Translate_vector

## method 1 ##
proj_matrix = np.hstack((Rotation_matrix_T, - np.dot(Rotation_matrix_T, Translate_vector)))

## method 2 ##
proj_matrix = np.zeros(3, 4)
Transformation_matrix_inv = np.linalg.inv(Transformation_matrix)
proj_matrix = Transformation_matrix_inv[:3, :4]

# # # # # # # # # # # # # # # # # #
# #     R | s*t                 # # 
# # T = -------                 # # 
# #     0 0 0 1                 # #     
# #                             # #
# #           R.T | -R.T*s*t    # # 
# # inv(T) =  --------------    # # 
# #            0  0  0  1       # # 
# #                             # #
# # P = R.T| -R.T*s*t           # # 
# # P = inv(T)[:3, :4]          # # 
# # # # # # # # # # # # # # # # # #
# s = Scale You don't need it now #
# # # # # # # # # # # # # # # # # #

This projection Matrix don't contain Camera Matrix

proj_matrix_Final_Camera1 = np.dot(cameraMatrix, np.eye(4)[:3, :4])
proj_matrix_Final_Camera2 = np.dot(cameraMatrix, proj_matrix)

To answer your question: The rvec and tvec returned by solvepnp don't include the values of the camera matrix. The rotation and translation are recovered in this way

Rotation = cv.rodriges (rvec) [0] .T
Traslation = - np.dot (Rotation.T, tvec)
edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2020-07-03 01:13:57 -0600

Seen: 1,750 times

Last updated: Oct 09 '20