Ask Your Question

Revision history [back]

solvePnP and problems with perspective

I feed 8 corners of the cube, but after reprojection sometimes (not for all images) the nearest point becomes the farthest and vice versa.

image description

Can anybody explain the reason and how to cope with it?

solvePnP and problems with perspective

I feed 8 corners of the cube, but after reprojection sometimes (not for all images) the nearest point becomes the farthest and vice versa.

image description

Can anybody explain the reason and how to cope with it?

An example of correct case:

image description

The code:

        float box_side_x = 6; //Centimetres
        float box_side_y = 6;
        float box_side_z = 6;
        vector<Point3f> boxPoints;

//Fill the array of corners in object coordinates. x to right(view from camera), y down, z from camera.

        vector<Vec3d> boxCorners(8);
        Vec3d boxCorner;
        float x, y, z;
        for (int h = 0; h < 2; ++h) {
            for (int j = 0; j < 2; ++j) {
                for (int i = 0; i < 2; ++i) {
                    x = box_side_x * i;
                    y = box_side_y * j;
                    z = box_side_z * h;
                    boxPoints.push_back(Point3f(x, y, z)); //For solvePnP()
                    boxCorners[i + 2 * j + 4 * h] = {x, y, z}; //For calculating output
                }
            }
        }

        solvePnP(boxPoints, pointBuf, cameraMatrix, distCoeffs, rvec, tvec, false);
        Mat rmat;
        Rodrigues(rvec, rmat);

        Mat Result;
        float S = 1;
        for (int h = 0; h < 2; ++h) {
            for (int j = 0; j < 2; ++j) {
                for (int i = 0; i < 2; ++i) {
                    boxCorner = boxCorners[i+2*j+4*h]; //In centimetres
                    Result = S * (rmat * Mat(boxCorner) + tvec);
                    ObjPoints[i + 2 * j + 4 * h] = (Vec3f)Result; //In centimetres
                }
            }
        }

In different file ObjPoints -> BoxCorners

    vector<float> X(8), Y(8), Z(8);
    for (int i = 0; i < 8; i++) {
        BoxCorner = BoxCorners[i]; //In centimetres
        X[i] = K * (BoxCorner[0] + Lx);
        Y[i] = K * (BoxCorner[1] + Ly);
        Z[i] = K * (BoxCorner[2] + Lz);
    }
    Scalar color = CV_RGB(0, 0, 200), back_color = CV_RGB(0, 0, 100);
    int thickness = 2;

    namedWindow("Projection", WINDOW_AUTOSIZE);
    Point pt1 = Point(0, 0), pt2 = Point(0, 0);
        pt1 = Point(X[7], Y[7]), pt2 = Point(X[6], Y[6]);
        line(drawing, pt1, pt2, back_color, thickness);
        pt1 = Point(X[7], Y[7]); pt2 = Point(X[5], Y[5]);
        line(drawing, pt1, pt2, back_color, thickness);
        pt1 = Point(X[7], Y[7]); pt2 = Point(X[3], Y[3]);
        line(drawing, pt1, pt2, back_color, thickness);

        pt1 = Point(X[0], Y[0]), pt2 = Point(X[1], Y[1]);
        line(drawing, pt1, pt2, color, thickness);
        pt1 = Point(X[0], Y[0]); pt2 = Point(X[2], Y[2]);
        line(drawing, pt1, pt2, color, thickness);
        pt1 = Point(X[0], Y[0]), pt2 = Point(X[4], Y[4]);
        line(drawing, pt1, pt2, color, thickness);

        pt1 = Point(X[1], Y[1]); pt2 = Point(X[3], Y[3]);
        line(drawing, pt1, pt2, color, thickness);
        pt1 = Point(X[3], Y[3]); pt2 = Point(X[2], Y[2]);
        line(drawing, pt1, pt2, color, thickness);
        pt1 = Point(X[2], Y[2]); pt2 = Point(X[6], Y[6]);
        line(drawing, pt1, pt2, color, thickness);
        pt1 = Point(X[6], Y[6]); pt2 = Point(X[4], Y[4]);
        line(drawing, pt1, pt2, color, thickness);
        pt1 = Point(X[4], Y[4]); pt2 = Point(X[5], Y[5]);
        line(drawing, pt1, pt2, color, thickness);
        pt1 = Point(X[5], Y[5]); pt2 = Point(X[1], Y[1]);
        line(drawing, pt1, pt2, color, thickness);
imshow("Projection", drawing);