Ich habe ein camera
und ein 3D
Objekt, ich habe die camera matrix
wie in this angegeben berechnet. Das mit der Kamera aufgenommene Bild hat die Größe 1600x1200.
. Aber in der Kameramatrix bekomme ich den Wert von Bild centers
nicht richtig. Anstelle von 800, 600
bekomme ich einige andere Werte. Was sind die möglichen Gründe dafür?Bildmitte in der Kalibriermatrix
#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;
}
Probe 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}};
Probe 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}};
Probe 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}};
Es gibt ein Problem in Ihren Eingangsdaten, oder es ist ein Fehler in Ihren Berechnungen, oder Sie werden die Ergebnisse falsch interpretiert. Ich denke, das deckt alle Möglichkeiten mit so wenig Information in Ihrer Frage ab. – rhashimoto