Using solvePnP with fixed center of rotation

We're using solvePnP to determine the attitude of an object with its center of rotation fixed relative to the camera (object has some aruco markers on it). And I know for a fact that coordinates of the center of the object are constant. Those coordinates are in tvec returned from solvePnP. I just need the object's rotation rvec, but solvePnP doesn't seem to provide a way to tell it that there's no need to optimize tvec because I already know it. The optimization process would have been easier, faster and most importantly more accurate if we had a way to do that, but judging by the code of cvFindExtrinsicCameraParams2 function it's not the case. At least not for SOLVEPNP_ITERATIVE algorithm that we're using.

So is there a way to use solvePnP to only optimize rotation if I already know tvec? I know that I can provide it as initial guess, but I want to exclude it from optimization altogether.

Thanks!

edit retag close merge delete

Sort by » oldest newest most voted

No, there is no way to use solvePnP() for your specific use case.

You can do it yourself. I see two possibilities.

In both cases you would have to reimplement the non-linear minimization process for the pose estimation refinement. You can use as a reference the solvePnPRefineLM() and modify it for your needs.

The first solution is to truncate the Jacobian matrix that is of size 2N x 6 (with N the number of points and 6 the number of parameters: angle-axis + translation) to 2N x 3. Then you update only the rotation part.

The other solution I see is to keep the Jacobian matrix of size 2N x 6 and just update the rotation part. But I am not sure if is valid or not.

Or maybe use something like a selection matrix to discard the translation part?

See: Gauss-Newton / Levenberg-Marquardt Optimization by Ethan Eade. The application is for pose estimation.

more

Thanks a lot! Actually I already did just that (first solution), but was wondering if it's necessary to modify OpenCV code. Thank you for clarification. Do you think an option like this is worth contributing to the official version?

( 2020-04-10 15:07:51 -0500 )edit

You can open a feature request issue here: https://github.com/opencv/opencv/issues

In my opinion, instead of just "freezing" the translation part, it should be better to have something like a 6x6 matrix to select the degree of freedom that should be considered. This way it is more generic.

Also, I would see this feature in this framework. This uses a class instead of the function. And there are solvePnPRefineLM() and solvePnPRefineVVS that could benefit of this feature.

So what you could do is to open a feature request and add the code you used. This could be useful to other user, and/or some people could check the mathematical validity. Later, this feature could be integrated in the mentioned "framework".

( 2020-04-11 07:44:43 -0500 )edit