Reputation: 13283
I have a problem when using solvePnPRansac to track coplanar markers. I recorded a video of the problem here:
In the video you see the pink cube drawn with OpenCV flipping about every 2-3 frames. You also see on top a stable coordinate system I render with OpenGL but you can ignore it, I don't apply the rotation values calculated by the tracker, that's why the flipping is not passed to the OpenGL scene.
I assume the problem lies in the solvePnPRansac of OpenCV since the inputs (the 2D and 3D points) are very similar on each frame but the calculated projection matrix differs a log as you can see in the video. The tracked points all look fine. In the video I also render the coordinate axes and you can see that the z-axis is flipped/inverted while the rest of the axes (Y-axis: green pointing down and X-axis: red point to the right) stay correct.
My used parameters for solvePnPRANSAC: I used cv::ITERATIVE on the solvePnPRANSAC with the standard reprojection error 8.0 (tried several times with different values but no luck) and I switched of the extrinsic guess to false.
Are there always 2 correct pnp solutions for coplanar markers and that's why it randomly flips between both? Can I avoid this behaviour. I searched for people having similar problems but all I could find about this are two old questions which sound like it could be the same problem: http://answers.opencv.org/question/6373/cv2solvepnp-axis-flip-with-rotation/# and http://answers.opencv.org/question/11915/solvepnp-similar-input-returns-very-different-output/
Upvotes: 2
Views: 1236
Reputation: 1169
This can happen when multiple solutions are similarly correct, so you will get one or the other randomly.
It is probably a good idea to keep using the values from the previous frame as a first guess to the current frame (useExtrinsicGuess = true), to ensure that you get temporal stability.
Also depending on your tracked points, it might even be better to use solvePnP instead. This gives you a more temporally stable result, especially when you use the previous values as initial guess.
Upvotes: 1