校准矩阵中的图像中心

Dee*_*pak 10 camera calibration camera-calibration

我有一个camera和一个3D对象,我计算了camera matrix 在给定的这个.使用相机拍摄的图像有大小1600x1200.但是在相机矩阵中我没有centers正确获得图像的值.而不是800, 600我得到一些其他的价值观.可能的原因是什么?

  #include <iostream>
    #include "opencv2/imgproc/imgproc.hpp"
    #include "opencv2/highgui/highgui.hpp"
    #include <math.h> 
    using namespace std;
    using namespace cv;
    int main()
    {
      int numberofpoints=30;
      float p2d[30][2] =
  {{72, 169}, {72, 184}, {71, 264}, {96, 168}, {94, 261}, {94, 276}, {257, 133},
    {254, 322}, {254, 337}, {278, 132}, {278, 146}, {275, 321}, {439, 228},
    {439, 243}, {437, 328}, {435, 431}, {461, 226}, {459, 326}, {459, 342},
    {457, 427}, {457, 444}, {612, 196}, {609, 291}, {605, 392}, {605, 406},
    {634, 191}, {633, 206}, {630, 288}, {630, 303}, {627, 390}};



      float p3d[30][3] = 
{{0, 0, 98},  {0, 0, 94}, {0, 0, 75}, {4, 4, 98}, {4, 4, 75}, {4, 4, 71},
{0, 96, 75}, {0, 96, 25}, {0, 96, 21}, {4, 100, 75},
{4, 100, 71}, {4, 100, 25}, {96, 0, 98}, {96, 0, 94},
{96, 0, 75}, {96, 0, 50}, {100, 4, 98}, {100, 4, 75},
{100, 4, 71}, {100, 4, 50}, {100, 4, 46}, {96, 96, 75},
{96, 96, 50}, {96, 96, 25}, {96, 96, 21}, {100, 100, 75},
{100, 100, 71}, {100, 100, 50}, {100, 100, 46}, {100, 100, 25}};


      Mat Matrix2D= Mat(30, 2, CV_64FC1, &p2d);
      Mat Matrix3D= Mat(30, 3, CV_64FC1, &p3d);
      Mat X_3D=Matrix3D.col(0);
      Mat Y_3D=Matrix3D.col(1);
      Mat Z_3D=Matrix3D.col(2);
      Mat X_2D=Matrix2D.col(0);
      Mat Y_2D=Matrix2D.col(1);
      Mat z = Mat::zeros(numberofpoints,4, CV_64FC1);
      Mat o = Mat::ones(numberofpoints,1, CV_64FC1);
      Mat temp,temp1,C,D,AoddRows;
      hconcat( X_3D, Y_3D,temp); 
      hconcat(Z_3D ,o,temp1);
      hconcat(z, -X_2D.mul(X_3D),C);
      hconcat(-X_2D.mul(Y_3D),-X_2D.mul(Z_3D),D);
      hconcat(temp,temp1,AoddRows);
      hconcat(AoddRows,C,AoddRows);
      hconcat(AoddRows,D,AoddRows);
      hconcat(AoddRows,-X_2D,AoddRows);
      Mat A1,B1,C1,AevenRows;
      hconcat(z,Matrix3D,A1); 
      hconcat(o,-Y_2D.mul(X_3D) ,B1);
      hconcat(-Y_2D.mul(Y_3D),-Y_2D.mul(Z_3D),C1);
      hconcat(A1,B1,AevenRows);
      hconcat(AevenRows,C1,AevenRows);
      hconcat(AevenRows,-Y_2D,AevenRows);
      Mat A;                                      
      vconcat(AoddRows,AevenRows,A);              
      Mat  w, u, EigenVectors;
      SVD::compute(A, w, u, EigenVectors);
      Mat EigenVector_SmallestEigenvalue=EigenVectors.row(EigenVectors.rows-1);
      Mat P=Mat::zeros(3,4, CV_64FC1);
      int k=0;
      for(int i=0;i<P.rows;i++)
      {
        for(int j=0;j<P.cols;j++)
        {
          P.at<double>(i, j) = EigenVector_SmallestEigenvalue.at<double>(0,k);
          k++;
        }
      }
      double abs_lambda = sqrt(P.at<double>(2,0) * P.at<double>(2,0)  + P.at<double>(2,1) * P.at<double>(2,1) + P.at<double>(2,2) * P.at<double>(2,2));
      P = P / abs_lambda;
      Mat ProjectionMatrix = P;    
      Mat T= Mat::zeros(3,1, CV_64FC1);
      Mat R = Mat::zeros(3,3, CV_64FC1);
      Mat B = Mat::zeros(3,3, CV_64FC1);
      Mat b = Mat::zeros(3,1,CV_64FC1);
      P.row(0).colRange(0,3).copyTo(B.row(0));
      P.row(1).colRange(0,3).copyTo(B.row(1));
      P.row(2).colRange(0,3).copyTo(B.row(2));
      P.col(3).copyTo(b.col(0));
      Mat K=B*B.t();
      double Center_x = K.at<double>(0,2);
      double Center_y = K.at<double>(1,2);
      double beta = sqrt(K.at<double>(1,1)-Center_y*Center_y);
      double gemma = (K.at<double>(0,1)-Center_x*Center_y)/beta;
      double alpha = sqrt(K.at<double>(0,0)-Center_x*Center_x-gemma*gemma);

      Mat CameraMatrix=Mat::zeros(3,3, CV_64FC1);
      CameraMatrix.at<double>(0,0)=alpha;
      CameraMatrix.at<double>(0,1)=gemma;
      CameraMatrix.at<double>(0,2)=Center_x;
      CameraMatrix.at<double>(1,1)=beta;
      CameraMatrix.at<double>(1,2)=Center_y;
      CameraMatrix.at<double>(2,2)=1;
      R = CameraMatrix.inv()*B;
      T = CameraMatrix.inv()*b;
      Mat newMatrix2D=Mat::zeros(numberofpoints,2, CV_64FC1);
      for(int i=0;i<numberofpoints;i++)
      {
        double num_u =  P.at<double>(0,0) * Matrix3D.at<double>(i,0) 
          + P.at<double>(0,1) * Matrix3D.at<double>(i,1) 
          + P.at<double>(0,2) * Matrix3D.at<double>(i,2) 
          + P.at<double>(0,3);

        double num_v =  P.at<double>(1,0) * Matrix3D.at<double>(i,0) 
          + P.at<double>(1,1) * Matrix3D.at<double>(i,1) 
          + P.at<double>(1,2) * Matrix3D.at<double>(i,2) 
          + P.at<double>(1,3);

        double den =    P.at<double>(2,0) * Matrix3D.at<double>(i,0) 
          + P.at<double>(2,1) * Matrix3D.at<double>(i,1) 
          + P.at<double>(2,2) * Matrix3D.at<double>(i,2) 
          + P.at<double>(2,3);

        newMatrix2D.at<double>(i,0)=num_u/den;
        newMatrix2D.at<double>(i,1)=num_v/den;
      } 

      Mat reprojMatrix=newMatrix2D;
      Mat errorDiff=reprojMatrix-Matrix2D;
      int size=errorDiff.rows;
      double sum=0;
      for(int i=0;i<errorDiff.rows;i++)
      {
        sum=sum + sqrt(errorDiff.at<double>(i,0) * errorDiff.at<double>(i,0)
                       + errorDiff.at<double>(i,1) * errorDiff.at<double>(i,1));
      }
      sum=sum/size;
      cout<<"Average Error="<<sum<<endl;
      cout<<"Translation Matrix="<<T<<endl<<endl;
      cout<<"Rotational Matrix="<<R<<endl<<endl;
      cout<<"Camera Matrix="<<CameraMatrix<<endl;
      return 0;
    }
Run Code Online (Sandbox Code Playgroud)

样品1:

  const int numberofpoints = 30;
  float p2d[numberofpoints][2] =
    {{72, 169}, {72,  184}, {71, 264},  {96, 168},  {94, 261},  {94, 276}, {257, 133},
    {254, 322}, {254, 337}, {278, 132}, {278, 146}, {275, 321}, {439, 228},
    {439, 243}, {437, 328}, {435, 431}, {461, 226}, {459, 326}, {459, 342},
    {457, 427}, {457, 444}, {612, 196}, {609, 291}, {605, 392}, {605, 406},
    {634, 191}, {633, 206}, {630, 288}, {630, 303}, {627, 390}};

  float p3d[numberofpoints][3] =
    {{0, 0, 98},  {0, 0, 94},   {0, 0, 75},   {4, 4, 98}, {4, 4, 75}, {4, 4, 71},
    {0, 96, 75},  {0, 96, 25},  {0, 96, 21},  {4, 100, 75},
    {4, 100, 71}, {4, 100, 25}, {96, 0, 98},  {96, 0, 94},
    {96, 0, 75},  {96, 0, 50},  {100, 4, 98}, {100, 4, 75},
    {100, 4, 71}, {100, 4, 50}, {100, 4, 46}, {96, 96, 75},
    {96, 96, 50}, {96, 96, 25}, {96, 96, 21}, {100, 100, 75},
    {100, 100, 71}, {100, 100, 50}, {100, 100, 46}, {100, 100, 25}};
Run Code Online (Sandbox Code Playgroud)

样本2:

 const int numberofpoints = 24;
  float p2d[24][2] =
  {{41, 291}, {41, 494},  {41, 509}, {64, 285}, {64, 303},
     {64, 491}, {195, 146},  {216, 144}, {216, 160}, {431, 337},
     {431, 441}, {431, 543}, {431, 558}, {452, 336}, {452, 349},
     {452, 438}, {452, 457}, {452, 539}, {568, 195}, {566, 291},
     {588, 190}, {587, 209}, {586, 289}, {586, 302}};
  float p3d[24][3] =
  {{0, 0, 75}, {0, 0, 25}, {0, 0, 21}, {4, 4, 75}, {4, 4, 71}, {4, 4, 25},
    {0, 96, 75 }, {4, 100, 75}, {4, 100, 71}, {96, 0, 75}, {96, 0, 50}, {96, 0, 25},
  {96, 0, 21}, {100, 4, 75}, {100, 4, 71}, {100, 4, 50}, {100, 4, 46}, {100, 4, 25}, {96,  96, 75 },  {96,  96, 50 }, {100, 100, 75}, {100, 100, 71}, {100, 100, 50}, {100, 100, 46}};
Run Code Online (Sandbox Code Playgroud)

样本3:

 const int numberofpoints = 33;
  float p2d[numberofpoints][2] =
  {{45, 310},   {43, 412}, {41, 513}, {41, 530}, {68, 305},
    {68, 321}, {66, 405}, {66, 423}, {64, 509}, {201, 70}, {201, 84},
    {200, 155}, {198, 257}, {218, 259}, {218, 271}, {441, 364},
    {439, 464}, {437, 569}, {437, 586}, {462, 361}, {462, 376},
    {460, 462}, {460, 479}, {459, 565}, {583, 117}, {583, 131},
    {580, 215}, {576, 313}, {603, 113}, {600, 214}, {599, 229},
    {596, 311}, {596, 323}};

    float p3d[numberofpoints][3] =
   {{0, 0, 75},   {0, 0, 50}, {0, 0, 25}, {0, 0, 21}, {4, 4, 75}, {4, 4, 71},
    {4, 4, 50}, {4, 4, 46}, {4, 4, 25}, {0, 96, 98}, {0, 96, 94}, {0, 96, 75},
    {0, 96, 50}, {4, 100,75}, {4, 100,71}, {96, 0, 75}, {96, 0, 50}, {96, 0, 25},
    {96, 0, 21}, {100, 4,75}, {100, 4,71}, {100, 4,50}, {100, 4,46}, {100, 4,25},{96, 96,98}, {96, 96,94}, {96, 96,75}, {96, 96,50}, {100, 100, 98}, {100, 100, 75},{100, 100, 71}, {100, 100, 50}, {100, 100, 46}};
Run Code Online (Sandbox Code Playgroud)

Dim*_*ima 0

您还获得哪些其他值?一般来说,相机中心永远不会恰好位于图像的中心,但应该相当接近。