Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Update a stereo projection matrix using rvec and tvec?

I am setting up Projection Matrices in a stereo camera rig, using the intrinsic matrix. Like so:

// Camera 1 Projection Matrix K[I|0]
    cv::Mat P1(3, 4, cv::DataType<float>::type);
    K.copyTo(P1.rowRange(0, 3).colRange(0, 3));  //K is the camera matrix


//stereo 
       float tx = 0.12; //Stereo baseline
    float ty = 0;
    float tz = 0;

    //rotation ( images are rectified, so this is zero)
    float rots[9] = { 1,0,0,0,1,0,0,0,1 };
    cv::Mat R = cv::Mat(3, 3, CV_32F, rots);


    //translation. (stereo camera, rectified images, 12 cm baseline)
    float trans[3] = { tx,ty,tz };
    cv::Mat t = cv::Mat(3, 1, CV_32F, trans);


    // Camera 2 Projection Matrix K[R|t]
        cv::Mat P2(3, 4, CV_32F);
        R.copyTo(P2.rowRange(0, 3).colRange(0, 3));
        t.copyTo(P2.rowRange(0, 3).col(3));
        P2 = K*P2;

This give me:

matrix P1
[333.02081, 0, 318.51651, 0;
 0, 333.02081, 171.93558, 0;
 0, 0, 1, 0]
matrix P2
[333.02081, 0, 318.51651, 39.962498;
 0, 333.02081, 171.93558, 0;
 0, 0, 1, 0]

which seems to work well.

Now, I need to update these matrices using the current camera pose (rvec and tvec).

I am doing this with:

//camera pose
    cv::Mat R(3, 3, cv::DataType<float>::type);
    cv::Rodrigues(rvec, R); // R is 3x3
    R = R.t();  // rotation of inverse
    cv::Mat tvecInv = -R * tvec; // translation of inverse

    //translation. (stereo camera, rectified images, 12 cm baseline)
    float trans[3] = { tx,ty,tz };
    cv::Mat t2 = cv::Mat(3, 1, CV_32F, trans);

    //add the baseline to cam2
    t2.at<float>(0) = tvecInv.at<float>(0) + tx;
    t2.at<float>(1) = tvecInv.at<float>(1);
    t2.at<float>(2) = tvecInv.at<float>(2);

    // Camera 1 Projection Matrix K[I|0]
    cv::Mat P1(3, 4, CV_32F, cv::Scalar(0));
    R.copyTo(P1.rowRange(0, 3).colRange(0, 3));
    tvecInv.copyTo(P1.rowRange(0, 3).col(3));
    P1 = K*P1;

    // Camera 2 Projection Matrix K[R|t]
    cv::Mat P2(3, 4, CV_32F);
    R.copyTo(P2.rowRange(0, 3).colRange(0, 3));
    t2.copyTo(P2.rowRange(0, 3).col(3));
    P2 = K*P2;

Which gives me:

update P1
[-362.74387, -131.39442, 252.00798, -272.50296;
 -9.197648, -374.57056, 8.7753143, -74.796822;
 -0.098709576, -0.4356361, 0.89469415, -0.89352131]
update P2
[-362.74387, -131.39442, 252.00798, 37.901237;
 -9.197648, -374.57056, 8.7753143, 421.92899;
 -0.098709576, -0.4356361, 0.89469415, -0.0064714332]

This is very wrong. What is the correct way to update stereo projection matrices using rvec and tvec values?

thank you.

Update Create a stereo projection matrix using rvec and tvec?

I am setting up Projection Matrices in a stereo camera rig, using the intrinsic matrix. Like so:

// Camera 1 Projection Matrix K[I|0]
    cv::Mat P1(3, 4, cv::DataType<float>::type);
    K.copyTo(P1.rowRange(0, 3).colRange(0, 3));  //K is the camera matrix


//stereo 
       float tx = 0.12; //Stereo baseline
    float ty = 0;
    float tz = 0;

    //rotation ( images are rectified, so this is zero)
    float rots[9] = { 1,0,0,0,1,0,0,0,1 };
    cv::Mat R = cv::Mat(3, 3, CV_32F, rots);


    //translation. (stereo camera, rectified images, 12 cm baseline)
    float trans[3] = { tx,ty,tz };
    cv::Mat t = cv::Mat(3, 1, CV_32F, trans);


    // Camera 2 Projection Matrix K[R|t]
        cv::Mat P2(3, 4, CV_32F);
        R.copyTo(P2.rowRange(0, 3).colRange(0, 3));
        t.copyTo(P2.rowRange(0, 3).col(3));
        P2 = K*P2;

This give me:

matrix P1
[333.02081, 0, 318.51651, 0;
 0, 333.02081, 171.93558, 0;
 0, 0, 1, 0]
matrix P2
[333.02081, 0, 318.51651, 39.962498;
 0, 333.02081, 171.93558, 0;
 0, 0, 1, 0]

which seems to work well.

Now, I need to update these matrices using the current camera pose (rvec and tvec).

I am doing this with:

//camera pose
    cv::Mat R(3, 3, cv::DataType<float>::type);
    cv::Rodrigues(rvec, R); // R is 3x3
    R = R.t();  // rotation of inverse
    cv::Mat tvecInv = -R * tvec; // translation of inverse

    //translation. (stereo camera, rectified images, 12 cm baseline)
    float trans[3] = { tx,ty,tz };
    cv::Mat t2 = cv::Mat(3, 1, CV_32F, trans);

    //add the baseline to cam2
    t2.at<float>(0) = tvecInv.at<float>(0) + tx;
    t2.at<float>(1) = tvecInv.at<float>(1);
    t2.at<float>(2) = tvecInv.at<float>(2);

    // Camera 1 Projection Matrix K[I|0]
    cv::Mat P1(3, 4, CV_32F, cv::Scalar(0));
    R.copyTo(P1.rowRange(0, 3).colRange(0, 3));
    tvecInv.copyTo(P1.rowRange(0, 3).col(3));
    P1 = K*P1;

    // Camera 2 Projection Matrix K[R|t]
    cv::Mat P2(3, 4, CV_32F);
    R.copyTo(P2.rowRange(0, 3).colRange(0, 3));
    t2.copyTo(P2.rowRange(0, 3).col(3));
    P2 = K*P2;

Which gives me:

update P1
[-362.74387, -131.39442, 252.00798, -272.50296;
 -9.197648, -374.57056, 8.7753143, -74.796822;
 -0.098709576, -0.4356361, 0.89469415, -0.89352131]
update P2
[-362.74387, -131.39442, 252.00798, 37.901237;
 -9.197648, -374.57056, 8.7753143, 421.92899;
 -0.098709576, -0.4356361, 0.89469415, -0.0064714332]

This is very wrong. What is the correct way to update stereo projection matrices using rvec and tvec values?

thank you.