OpenCV Q&A Forum - RSS feedhttp://answers.opencv.org/questions/OpenCV answersenCopyright <a href="http://www.opencv.org">OpenCV foundation</a>, 2012-2018.Sat, 11 Apr 2020 07:44:43 -0500Using solvePnP with fixed center of rotationhttp://answers.opencv.org/question/228736/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!Wed, 08 Apr 2020 14:50:39 -0500http://answers.opencv.org/question/228736/using-solvepnp-with-fixed-center-of-rotation/Answer by Eduardo for <p>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 <code>tvec</code> returned from solvePnP. I just need the object's rotation <code>rvec</code>, but solvePnP doesn't seem to provide a way to tell it that there's no need to optimize <code>tvec</code> because I already know it. The optimization process would have been easier, faster and most importantly <em>more accurate</em> if we had a way to do that, but judging by the code of <code>cvFindExtrinsicCameraParams2</code> function it's not the case. At least not for <code>SOLVEPNP_ITERATIVE</code> algorithm that we're using.</p>
<p>So is there a way to use solvePnP to only optimize rotation if I already know <code>tvec</code>? I know that I can provide it as initial guess, but I want to exclude it from optimization altogether.</p>
<p>Thanks!</p>
http://answers.opencv.org/question/228736/using-solvepnp-with-fixed-center-of-rotation/?answer=228774#post-id-228774No, 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](http://ethaneade.com/optimization.pdf). The application is for pose estimation.Thu, 09 Apr 2020 11:42:37 -0500http://answers.opencv.org/question/228736/using-solvepnp-with-fixed-center-of-rotation/?answer=228774#post-id-228774Comment by Eduardo for <p>No, there is no way to use <code>solvePnP()</code> for your specific use case.</p>
<hr>
<p>You can do it yourself. I see two possibilities.</p>
<p>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 <code>solvePnPRefineLM()</code> and modify it for your needs.</p>
<p>The first solution is to truncate the Jacobian matrix that is of size <code>2N x 6</code> (with <code>N</code> the number of points and <code>6</code> the number of parameters: angle-axis + translation) to <code>2N x 3</code>. Then you update only the rotation part.</p>
<p>The other solution I see is to keep the Jacobian matrix of size <code>2N x 6</code> and just update the rotation part. But I am not sure if is valid or not.</p>
<p>Or maybe use something like a selection matrix to discard the translation part?</p>
<hr>
<p>See: <a href="http://ethaneade.com/optimization.pdf">Gauss-Newton / Levenberg-Marquardt Optimization by Ethan Eade</a>. The application is for pose estimation.</p>
http://answers.opencv.org/question/228736/using-solvepnp-with-fixed-center-of-rotation/?comment=228878#post-id-228878You 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](https://github.com/opencv/opencv/pull/15650). 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".Sat, 11 Apr 2020 07:44:43 -0500http://answers.opencv.org/question/228736/using-solvepnp-with-fixed-center-of-rotation/?comment=228878#post-id-228878Comment by Anton Gromov for <p>No, there is no way to use <code>solvePnP()</code> for your specific use case.</p>
<hr>
<p>You can do it yourself. I see two possibilities.</p>
<p>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 <code>solvePnPRefineLM()</code> and modify it for your needs.</p>
<p>The first solution is to truncate the Jacobian matrix that is of size <code>2N x 6</code> (with <code>N</code> the number of points and <code>6</code> the number of parameters: angle-axis + translation) to <code>2N x 3</code>. Then you update only the rotation part.</p>
<p>The other solution I see is to keep the Jacobian matrix of size <code>2N x 6</code> and just update the rotation part. But I am not sure if is valid or not.</p>
<p>Or maybe use something like a selection matrix to discard the translation part?</p>
<hr>
<p>See: <a href="http://ethaneade.com/optimization.pdf">Gauss-Newton / Levenberg-Marquardt Optimization by Ethan Eade</a>. The application is for pose estimation.</p>
http://answers.opencv.org/question/228736/using-solvepnp-with-fixed-center-of-rotation/?comment=228819#post-id-228819Thanks 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?Fri, 10 Apr 2020 15:07:51 -0500http://answers.opencv.org/question/228736/using-solvepnp-with-fixed-center-of-rotation/?comment=228819#post-id-228819