I have an asymmetric circular dot pattern similar to this.
I use opencv solvePnP function to estimate the pose of the pattern based on a) known 3D pattern point; b) detected pattern points in 2D image
I found that in some cases (when the pattern frontally face to the camera and tilted a bit), the estimated pose returned by the solvePnP function is unstable. There are two results for almost same pattern pose (no moving). I guess it is due to ambiguous planar poses have same 2D projection.
Is there any solution to it except the temporal filtering as suggested here: Similar issue
Update:
I tried to apply this paper which solve the ambiguous case but it didn't work.
The code I used is from here.
I could get almost same result as the cv::solvePNP by using the algorithm, but the unstable case still exist.
You can set to true the setting useExtrinsicGuess of solvePnP function; with this parameter, solvePnP uses the last computed pose in the first iteration of the solver inside solvePnP, see https://en.wikipedia.org/wiki/Levenberg–Marquardt_algorithm. For example:
void getPose(cv::Mat& t_vec, cv::Mat& r_vec)
{
static cv::Mat raux, taux;
static bool useExtrinsicGuess = false
cv::Mat objPoints (4, 3, CV_32FC1); // Your 3d points
cv::Mat imagePoints(4, 2, CV_32FC1); // Your 2d points
cv::solvePnP (objPoints,
imagePoints,
camera.getCameraMatrix(), // Camera matrix
camera.getDistorsion(), // Camera distorsion
raux, taux, useExtrinsicGuess, CV_ITERATIVE);
if (!useExtrinsicGuess) {
useExtrinsicGuess = true;
}
raux.convertTo(r_vec, CV_32F);
taux.convertTo(t_vec, CV_32F);
}
Also you could use more points, in different planes.
As has been already suggested, use findHomography, then decompose the result. See Zengyou Zhang's paper here. See, in particular, equations 2.18 for the concept, and 2.26 for the solution - the case you want is the one with one image only.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With