J'ai un camera
et un objet 3D
, j'ai calculé le camera matrix
comme indiqué dans this. L'image capturée en utilisant l'appareil photo a la taille 1600x1200.
Mais dans la matrice de la caméra, je ne reçois pas la valeur de l'image centers
correctement. Au lieu de 800, 600
je reçois d'autres valeurs. Quelles seront les raisons possibles de cela.Centre de l'image dans la matrice d'étalonnage
#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;
}
EXEMPLE 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}};
EXEMPLE 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}};
EXEMPLE 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}};
Il y a un problème dans vos données d'entrée, ou il y a une erreur dans vos calculs, ou vous interprétez mal les résultats. Je pense que cela couvre toutes les possibilités avec si peu d'informations dans votre question. – rhashimoto