Rotating target changes distances computed with solvePnP
I've been working on finding the distance to a target (of known real-world dimensions). The distance seems consistent enough when viewed from a forward-facing angle, but when I rotate the target (without translating it) the distance changes:
Here is the relevant code:
vector<Point3f> objectPoints;
objectPoints.push_back(Point3f(-1, -1, 0));
objectPoints.push_back(Point3f(-1, 1, 0));
objectPoints.push_back(Point3f(1, 1, 0));
objectPoints.push_back(Point3f(1, -1, 0));
Mat objectPointsMat(objectPoints);
Mat rvec;
Mat tvec;
solvePnP(objectPointsMat, inputContour, cameraMatrix, distortionCoeffs, rvec, tvec);
double tx = tvec.at<double>(0, 0);
double ty = tvec.at<double>(1, 0);
double tz = tvec.at<double>(2, 0);
double dist = std::sqrt(tx*tx + ty*ty + tz*tz);
char *str;
asprintf(&str, "DIST = %7.3f", dist);
putText(original, str, Point(0, original.size().height), CV_FONT_HERSHEY_PLAIN,
3, Scalar(255, 255, 255), 3);
EDIT: As Eduardo suggested, I have drawn the computed prose. I have also changed the objects points to match the width/height ratio of the actual target using:
objectPoints.push_back(Point3f(-1, -0.7, 0));
objectPoints.push_back(Point3f(-1, 0.7, 0));
objectPoints.push_back(Point3f(1, 0.7, 0));
objectPoints.push_back(Point3f(1, -0.7, 0));
The issue is that while yawing seems to work now, rolling makes the distance jump:
Maybe you could try to display the object frame to see where the computed pose is reprojected in the image. An example of how to do this here and here.
You could also check if the correspondences 3D object points and 2D image points are correct, check if the cameraMatrix and the distortion coefficients are correct.
What units are you using? The width of the rect is 2 but it's not meters. How did you specify the distance of the features during the intrinsic calibration? Could you also show the reprojection error? (Just apply cv::projectPoints to the 3d points and compare them to the features you found in the image)
Looking at the rotation vector you rendered in the second image it appears to shift the normal from toward the screen to straight up. I am also working on the same problem (although in python) and noticing the same issue even when describing the whole U shape rather than the bounding corners.
I can't find a way to send a private message, but can I pick your code on how you were able to detect this rectangle? I'm trying to do something similar with a hexagon shape, but I'm having problems.