use cpp functions in cvCalibrateCamera2 to make it more readable
This commit is contained in:
parent
b3ac274617
commit
742fb559f7
@ -1232,12 +1232,12 @@ CV_IMPL double cvCalibrateCamera2( const CvMat* objectPoints,
|
|||||||
CvMat* rvecs, CvMat* tvecs, int flags, CvTermCriteria termCrit )
|
CvMat* rvecs, CvMat* tvecs, int flags, CvTermCriteria termCrit )
|
||||||
{
|
{
|
||||||
const int NINTRINSIC = 16;
|
const int NINTRINSIC = 16;
|
||||||
Ptr<CvMat> matM, _m, _Ji, _Je, _err;
|
|
||||||
CvLevMarq solver;
|
CvLevMarq solver;
|
||||||
double reprojErr = 0;
|
double reprojErr = 0;
|
||||||
|
|
||||||
double A[9], k[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
|
Matx33d A;
|
||||||
CvMat matA = cvMat(3, 3, CV_64F, A), _k;
|
double k[12] = {0};
|
||||||
|
CvMat matA = cvMat(3, 3, CV_64F, A.val), _k;
|
||||||
int i, nimages, maxPoints = 0, ni = 0, pos, total = 0, nparams, npstep, cn;
|
int i, nimages, maxPoints = 0, ni = 0, pos, total = 0, nparams, npstep, cn;
|
||||||
double aspectRatio = 0.;
|
double aspectRatio = 0.;
|
||||||
|
|
||||||
@ -1302,25 +1302,31 @@ CV_IMPL double cvCalibrateCamera2( const CvMat* objectPoints,
|
|||||||
ni = npoints->data.i[i*npstep];
|
ni = npoints->data.i[i*npstep];
|
||||||
if( ni < 4 )
|
if( ni < 4 )
|
||||||
{
|
{
|
||||||
char buf[100];
|
CV_Error_( CV_StsOutOfRange, ("The number of points in the view #%d is < 4", i));
|
||||||
sprintf( buf, "The number of points in the view #%d is < 4", i );
|
|
||||||
CV_Error( CV_StsOutOfRange, buf );
|
|
||||||
}
|
}
|
||||||
maxPoints = MAX( maxPoints, ni );
|
maxPoints = MAX( maxPoints, ni );
|
||||||
total += ni;
|
total += ni;
|
||||||
}
|
}
|
||||||
|
|
||||||
matM.reset(cvCreateMat( 1, total, CV_64FC3 ));
|
Mat matM( 1, total, CV_64FC3 );
|
||||||
_m.reset(cvCreateMat( 1, total, CV_64FC2 ));
|
Mat _m( 1, total, CV_64FC2 );
|
||||||
|
|
||||||
cvConvertPointsHomogeneous( objectPoints, matM );
|
if(CV_MAT_CN(objectPoints->type) == 3) {
|
||||||
cvConvertPointsHomogeneous( imagePoints, _m );
|
cvarrToMat(objectPoints).convertTo(matM, CV_64F);
|
||||||
|
} else {
|
||||||
|
convertPointsHomogeneous(cvarrToMat(objectPoints), matM);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(CV_MAT_CN(imagePoints->type) == 2) {
|
||||||
|
cvarrToMat(imagePoints).convertTo(_m, CV_64F);
|
||||||
|
} else {
|
||||||
|
convertPointsHomogeneous(cvarrToMat(imagePoints), _m);
|
||||||
|
}
|
||||||
|
|
||||||
nparams = NINTRINSIC + nimages*6;
|
nparams = NINTRINSIC + nimages*6;
|
||||||
_Ji.reset(cvCreateMat( maxPoints*2, NINTRINSIC, CV_64FC1 ));
|
Mat _Ji( maxPoints*2, NINTRINSIC, CV_64FC1, Scalar(0));
|
||||||
_Je.reset(cvCreateMat( maxPoints*2, 6, CV_64FC1 ));
|
Mat _Je( maxPoints*2, 6, CV_64FC1 );
|
||||||
_err.reset(cvCreateMat( maxPoints*2, 1, CV_64FC1 ));
|
Mat _err( maxPoints*2, 1, CV_64FC1 );
|
||||||
cvZero( _Ji );
|
|
||||||
|
|
||||||
_k = cvMat( distCoeffs->rows, distCoeffs->cols, CV_MAKETYPE(CV_64F,CV_MAT_CN(distCoeffs->type)), k);
|
_k = cvMat( distCoeffs->rows, distCoeffs->cols, CV_MAKETYPE(CV_64F,CV_MAT_CN(distCoeffs->type)), k);
|
||||||
if( distCoeffs->rows*distCoeffs->cols*CV_MAT_CN(distCoeffs->type) < 8 )
|
if( distCoeffs->rows*distCoeffs->cols*CV_MAT_CN(distCoeffs->type) < 8 )
|
||||||
@ -1336,23 +1342,23 @@ CV_IMPL double cvCalibrateCamera2( const CvMat* objectPoints,
|
|||||||
if( flags & CV_CALIB_USE_INTRINSIC_GUESS )
|
if( flags & CV_CALIB_USE_INTRINSIC_GUESS )
|
||||||
{
|
{
|
||||||
cvConvert( cameraMatrix, &matA );
|
cvConvert( cameraMatrix, &matA );
|
||||||
if( A[0] <= 0 || A[4] <= 0 )
|
if( A(0, 0) <= 0 || A(1, 1) <= 0 )
|
||||||
CV_Error( CV_StsOutOfRange, "Focal length (fx and fy) must be positive" );
|
CV_Error( CV_StsOutOfRange, "Focal length (fx and fy) must be positive" );
|
||||||
if( A[2] < 0 || A[2] >= imageSize.width ||
|
if( A(0, 2) < 0 || A(0, 2) >= imageSize.width ||
|
||||||
A[5] < 0 || A[5] >= imageSize.height )
|
A(1, 2) < 0 || A(1, 2) >= imageSize.height )
|
||||||
CV_Error( CV_StsOutOfRange, "Principal point must be within the image" );
|
CV_Error( CV_StsOutOfRange, "Principal point must be within the image" );
|
||||||
if( fabs(A[1]) > 1e-5 )
|
if( fabs(A(0, 1)) > 1e-5 )
|
||||||
CV_Error( CV_StsOutOfRange, "Non-zero skew is not supported by the function" );
|
CV_Error( CV_StsOutOfRange, "Non-zero skew is not supported by the function" );
|
||||||
if( fabs(A[3]) > 1e-5 || fabs(A[6]) > 1e-5 ||
|
if( fabs(A(1, 0)) > 1e-5 || fabs(A(2, 0)) > 1e-5 ||
|
||||||
fabs(A[7]) > 1e-5 || fabs(A[8]-1) > 1e-5 )
|
fabs(A(2, 1)) > 1e-5 || fabs(A(2,2)-1) > 1e-5 )
|
||||||
CV_Error( CV_StsOutOfRange,
|
CV_Error( CV_StsOutOfRange,
|
||||||
"The intrinsic matrix must have [fx 0 cx; 0 fy cy; 0 0 1] shape" );
|
"The intrinsic matrix must have [fx 0 cx; 0 fy cy; 0 0 1] shape" );
|
||||||
A[1] = A[3] = A[6] = A[7] = 0.;
|
A(0, 1) = A(1, 0) = A(2, 0) = A(2, 1) = 0.;
|
||||||
A[8] = 1.;
|
A(2, 2) = 1.;
|
||||||
|
|
||||||
if( flags & CV_CALIB_FIX_ASPECT_RATIO )
|
if( flags & CV_CALIB_FIX_ASPECT_RATIO )
|
||||||
{
|
{
|
||||||
aspectRatio = A[0]/A[4];
|
aspectRatio = A(0, 0)/A(1, 1);
|
||||||
|
|
||||||
if( aspectRatio < minValidAspectRatio || aspectRatio > maxValidAspectRatio )
|
if( aspectRatio < minValidAspectRatio || aspectRatio > maxValidAspectRatio )
|
||||||
CV_Error( CV_StsOutOfRange,
|
CV_Error( CV_StsOutOfRange,
|
||||||
@ -1362,13 +1368,13 @@ CV_IMPL double cvCalibrateCamera2( const CvMat* objectPoints,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CvScalar mean, sdv;
|
Scalar mean, sdv;
|
||||||
cvAvgSdv( matM, &mean, &sdv );
|
meanStdDev(matM, mean, sdv);
|
||||||
if( fabs(mean.val[2]) > 1e-5 || fabs(sdv.val[2]) > 1e-5 )
|
if( fabs(mean[2]) > 1e-5 || fabs(sdv[2]) > 1e-5 )
|
||||||
CV_Error( CV_StsBadArg,
|
CV_Error( CV_StsBadArg,
|
||||||
"For non-planar calibration rigs the initial intrinsic matrix must be specified" );
|
"For non-planar calibration rigs the initial intrinsic matrix must be specified" );
|
||||||
for( i = 0; i < total; i++ )
|
for( i = 0; i < total; i++ )
|
||||||
((CvPoint3D64f*)matM->data.db)[i].z = 0.;
|
matM.at<Point3d>(i).z = 0.;
|
||||||
|
|
||||||
if( flags & CV_CALIB_FIX_ASPECT_RATIO )
|
if( flags & CV_CALIB_FIX_ASPECT_RATIO )
|
||||||
{
|
{
|
||||||
@ -1378,7 +1384,8 @@ CV_IMPL double cvCalibrateCamera2( const CvMat* objectPoints,
|
|||||||
CV_Error( CV_StsOutOfRange,
|
CV_Error( CV_StsOutOfRange,
|
||||||
"The specified aspect ratio (= cameraMatrix[0][0] / cameraMatrix[1][1]) is incorrect" );
|
"The specified aspect ratio (= cameraMatrix[0][0] / cameraMatrix[1][1]) is incorrect" );
|
||||||
}
|
}
|
||||||
cvInitIntrinsicParams2D( matM, _m, npoints, imageSize, &matA, aspectRatio );
|
CvMat _matM(matM), m(_m);
|
||||||
|
cvInitIntrinsicParams2D( &_matM, &m, npoints, imageSize, &matA, aspectRatio );
|
||||||
}
|
}
|
||||||
|
|
||||||
solver.init( nparams, 0, termCrit );
|
solver.init( nparams, 0, termCrit );
|
||||||
@ -1387,10 +1394,8 @@ CV_IMPL double cvCalibrateCamera2( const CvMat* objectPoints,
|
|||||||
double* param = solver.param->data.db;
|
double* param = solver.param->data.db;
|
||||||
uchar* mask = solver.mask->data.ptr;
|
uchar* mask = solver.mask->data.ptr;
|
||||||
|
|
||||||
param[0] = A[0]; param[1] = A[4]; param[2] = A[2]; param[3] = A[5];
|
param[0] = A(0, 0); param[1] = A(1, 1); param[2] = A(0, 2); param[3] = A(1, 2);
|
||||||
param[4] = k[0]; param[5] = k[1]; param[6] = k[2]; param[7] = k[3];
|
std::copy(k, k + 12, param + 4);
|
||||||
param[8] = k[4]; param[9] = k[5]; param[10] = k[6]; param[11] = k[7];
|
|
||||||
param[12] = k[8]; param[13] = k[9]; param[14] = k[10]; param[15] = k[11];
|
|
||||||
|
|
||||||
if( flags & CV_CALIB_FIX_FOCAL_LENGTH )
|
if( flags & CV_CALIB_FIX_FOCAL_LENGTH )
|
||||||
mask[0] = mask[1] = 0;
|
mask[0] = mask[1] = 0;
|
||||||
@ -1405,18 +1410,13 @@ CV_IMPL double cvCalibrateCamera2( const CvMat* objectPoints,
|
|||||||
flags |= CV_CALIB_FIX_K4 + CV_CALIB_FIX_K5 + CV_CALIB_FIX_K6;
|
flags |= CV_CALIB_FIX_K4 + CV_CALIB_FIX_K5 + CV_CALIB_FIX_K6;
|
||||||
if( !(flags & CV_CALIB_THIN_PRISM_MODEL))
|
if( !(flags & CV_CALIB_THIN_PRISM_MODEL))
|
||||||
flags |= CALIB_FIX_S1_S2_S3_S4;
|
flags |= CALIB_FIX_S1_S2_S3_S4;
|
||||||
if( flags & CV_CALIB_FIX_K1 )
|
|
||||||
mask[4] = 0;
|
mask[ 4] = !(flags & CALIB_FIX_K1);
|
||||||
if( flags & CV_CALIB_FIX_K2 )
|
mask[ 5] = !(flags & CALIB_FIX_K2);
|
||||||
mask[5] = 0;
|
mask[ 8] = !(flags & CALIB_FIX_K3);
|
||||||
if( flags & CV_CALIB_FIX_K3 )
|
mask[ 9] = !(flags & CALIB_FIX_K4);
|
||||||
mask[8] = 0;
|
mask[10] = !(flags & CALIB_FIX_K5);
|
||||||
if( flags & CV_CALIB_FIX_K4 )
|
mask[11] = !(flags & CALIB_FIX_K6);
|
||||||
mask[9] = 0;
|
|
||||||
if( flags & CV_CALIB_FIX_K5 )
|
|
||||||
mask[10] = 0;
|
|
||||||
if( flags & CV_CALIB_FIX_K6 )
|
|
||||||
mask[11] = 0;
|
|
||||||
|
|
||||||
if(flags & CALIB_FIX_S1_S2_S3_S4)
|
if(flags & CALIB_FIX_S1_S2_S3_S4)
|
||||||
{
|
{
|
||||||
@ -1430,14 +1430,14 @@ CV_IMPL double cvCalibrateCamera2( const CvMat* objectPoints,
|
|||||||
// 2. initialize extrinsic parameters
|
// 2. initialize extrinsic parameters
|
||||||
for( i = 0, pos = 0; i < nimages; i++, pos += ni )
|
for( i = 0, pos = 0; i < nimages; i++, pos += ni )
|
||||||
{
|
{
|
||||||
CvMat _Mi, _mi, _ri, _ti;
|
CvMat _ri, _ti;
|
||||||
ni = npoints->data.i[i*npstep];
|
ni = npoints->data.i[i*npstep];
|
||||||
|
|
||||||
cvGetRows( solver.param, &_ri, NINTRINSIC + i*6, NINTRINSIC + i*6 + 3 );
|
cvGetRows( solver.param, &_ri, NINTRINSIC + i*6, NINTRINSIC + i*6 + 3 );
|
||||||
cvGetRows( solver.param, &_ti, NINTRINSIC + i*6 + 3, NINTRINSIC + i*6 + 6 );
|
cvGetRows( solver.param, &_ti, NINTRINSIC + i*6 + 3, NINTRINSIC + i*6 + 6 );
|
||||||
|
|
||||||
cvGetCols( matM, &_Mi, pos, pos + ni );
|
CvMat _Mi(matM.colRange(pos, pos + ni));
|
||||||
cvGetCols( _m, &_mi, pos, pos + ni );
|
CvMat _mi(_m.colRange(pos, pos + ni));
|
||||||
|
|
||||||
cvFindExtrinsicCameraParams2( &_Mi, &_mi, &matA, &_k, &_ri, &_ti );
|
cvFindExtrinsicCameraParams2( &_Mi, &_mi, &matA, &_k, &_ri, &_ti );
|
||||||
}
|
}
|
||||||
@ -1457,10 +1457,8 @@ CV_IMPL double cvCalibrateCamera2( const CvMat* objectPoints,
|
|||||||
pparam[0] = pparam[1]*aspectRatio;
|
pparam[0] = pparam[1]*aspectRatio;
|
||||||
}
|
}
|
||||||
|
|
||||||
A[0] = param[0]; A[4] = param[1]; A[2] = param[2]; A[5] = param[3];
|
A(0, 0) = param[0]; A(1, 1) = param[1]; A(0, 2) = param[2]; A(1, 2) = param[3];
|
||||||
k[0] = param[4]; k[1] = param[5]; k[2] = param[6]; k[3] = param[7];
|
std::copy(param + 4, param + 4 + 12, k);
|
||||||
k[4] = param[8]; k[5] = param[9]; k[6] = param[10]; k[7] = param[11];
|
|
||||||
k[8] = param[12];k[9] = param[13];k[10] = param[14];k[11] = param[15];
|
|
||||||
|
|
||||||
if( !proceed )
|
if( !proceed )
|
||||||
break;
|
break;
|
||||||
@ -1469,24 +1467,24 @@ CV_IMPL double cvCalibrateCamera2( const CvMat* objectPoints,
|
|||||||
|
|
||||||
for( i = 0, pos = 0; i < nimages; i++, pos += ni )
|
for( i = 0, pos = 0; i < nimages; i++, pos += ni )
|
||||||
{
|
{
|
||||||
CvMat _Mi, _mi, _ri, _ti, _dpdr, _dpdt, _dpdf, _dpdc, _dpdk, _mp, _part;
|
CvMat _ri, _ti;
|
||||||
ni = npoints->data.i[i*npstep];
|
ni = npoints->data.i[i*npstep];
|
||||||
|
|
||||||
cvGetRows( solver.param, &_ri, NINTRINSIC + i*6, NINTRINSIC + i*6 + 3 );
|
cvGetRows( solver.param, &_ri, NINTRINSIC + i*6, NINTRINSIC + i*6 + 3 );
|
||||||
cvGetRows( solver.param, &_ti, NINTRINSIC + i*6 + 3, NINTRINSIC + i*6 + 6 );
|
cvGetRows( solver.param, &_ti, NINTRINSIC + i*6 + 3, NINTRINSIC + i*6 + 6 );
|
||||||
|
|
||||||
cvGetCols( matM, &_Mi, pos, pos + ni );
|
CvMat _Mi(matM.colRange(pos, pos + ni));
|
||||||
cvGetCols( _m, &_mi, pos, pos + ni );
|
CvMat _mi(_m.colRange(pos, pos + ni));
|
||||||
|
|
||||||
_Je->rows = _Ji->rows = _err->rows = ni*2;
|
_Je.resize(ni*2); _Ji.resize(ni*2); _err.resize(ni*2);
|
||||||
cvGetCols( _Je, &_dpdr, 0, 3 );
|
CvMat _dpdr(_Je.colRange(0, 3));
|
||||||
cvGetCols( _Je, &_dpdt, 3, 6 );
|
CvMat _dpdt(_Je.colRange(3, 6));
|
||||||
cvGetCols( _Ji, &_dpdf, 0, 2 );
|
CvMat _dpdf(_Ji.colRange(0, 2));
|
||||||
cvGetCols( _Ji, &_dpdc, 2, 4 );
|
CvMat _dpdc(_Ji.colRange(2, 4));
|
||||||
cvGetCols( _Ji, &_dpdk, 4, NINTRINSIC );
|
CvMat _dpdk(_Ji.colRange(4, NINTRINSIC));
|
||||||
cvReshape( _err, &_mp, 2, 1 );
|
CvMat _mp(_err.reshape(2, 1));
|
||||||
|
|
||||||
if( _JtJ || _JtErr )
|
if( solver.state == CvLevMarq::CALC_J )
|
||||||
{
|
{
|
||||||
cvProjectPoints2( &_Mi, &_ri, &_ti, &matA, &_k, &_mp, &_dpdr, &_dpdt,
|
cvProjectPoints2( &_Mi, &_ri, &_ti, &matA, &_k, &_mp, &_dpdr, &_dpdt,
|
||||||
(flags & CV_CALIB_FIX_FOCAL_LENGTH) ? 0 : &_dpdf,
|
(flags & CV_CALIB_FIX_FOCAL_LENGTH) ? 0 : &_dpdf,
|
||||||
@ -1498,26 +1496,20 @@ CV_IMPL double cvCalibrateCamera2( const CvMat* objectPoints,
|
|||||||
|
|
||||||
cvSub( &_mp, &_mi, &_mp );
|
cvSub( &_mp, &_mi, &_mp );
|
||||||
|
|
||||||
if( _JtJ || _JtErr )
|
if( solver.state == CvLevMarq::CALC_J )
|
||||||
{
|
{
|
||||||
cvGetSubRect( _JtJ, &_part, cvRect(0,0,NINTRINSIC,NINTRINSIC) );
|
Mat JtJ(cvarrToMat(_JtJ)), JtErr(cvarrToMat(_JtErr));
|
||||||
cvGEMM( _Ji, _Ji, 1, &_part, 1, &_part, CV_GEMM_A_T );
|
|
||||||
|
|
||||||
cvGetSubRect( _JtJ, &_part, cvRect(NINTRINSIC+i*6,NINTRINSIC+i*6,6,6) );
|
// see HZ: (A6.14) for details on the structure of the Jacobian
|
||||||
cvGEMM( _Je, _Je, 1, 0, 0, &_part, CV_GEMM_A_T );
|
JtJ(Rect(0, 0, NINTRINSIC, NINTRINSIC)) += _Ji.t() * _Ji;
|
||||||
|
JtJ(Rect(NINTRINSIC + i * 6, NINTRINSIC + i * 6, 6, 6)) = _Je.t() * _Je;
|
||||||
|
JtJ(Rect(NINTRINSIC + i * 6, 0, 6, NINTRINSIC)) = _Ji.t() * _Je;
|
||||||
|
|
||||||
cvGetSubRect( _JtJ, &_part, cvRect(NINTRINSIC+i*6,0,6,NINTRINSIC) );
|
JtErr.rowRange(0, NINTRINSIC) += _Ji.t() * _err;
|
||||||
cvGEMM( _Ji, _Je, 1, 0, 0, &_part, CV_GEMM_A_T );
|
JtErr.rowRange(NINTRINSIC + i * 6, NINTRINSIC + (i + 1) * 6) = _Je.t() * _err;
|
||||||
|
|
||||||
cvGetRows( _JtErr, &_part, 0, NINTRINSIC );
|
|
||||||
cvGEMM( _Ji, _err, 1, &_part, 1, &_part, CV_GEMM_A_T );
|
|
||||||
|
|
||||||
cvGetRows( _JtErr, &_part, NINTRINSIC + i*6, NINTRINSIC + (i+1)*6 );
|
|
||||||
cvGEMM( _Je, _err, 1, 0, 0, &_part, CV_GEMM_A_T );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double errNorm = cvNorm( &_mp, 0, CV_L2 );
|
reprojErr += norm(_err, NORM_L2SQR);
|
||||||
reprojErr += errNorm*errNorm;
|
|
||||||
}
|
}
|
||||||
if( _errNorm )
|
if( _errNorm )
|
||||||
*_errNorm = reprojErr;
|
*_errNorm = reprojErr;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user