Commit 4142e737 authored by Vadim Pisarevsky's avatar Vadim Pisarevsky

Merge pull request #6453 from sovrasov:extend_calibrateCamera

parents 7fadf570 46fb46c5
...@@ -767,6 +767,14 @@ k-th translation vector (see the next output parameter description) brings the c ...@@ -767,6 +767,14 @@ k-th translation vector (see the next output parameter description) brings the c
from the model coordinate space (in which object points are specified) to the world coordinate from the model coordinate space (in which object points are specified) to the world coordinate
space, that is, a real position of the calibration pattern in the k-th pattern view (k=0.. *M* -1). space, that is, a real position of the calibration pattern in the k-th pattern view (k=0.. *M* -1).
@param tvecs Output vector of translation vectors estimated for each pattern view. @param tvecs Output vector of translation vectors estimated for each pattern view.
@param stdDeviationsIntrinsics Output vector of standard deviations estimated for intrinsic parameters.
Order of deviations values:
\f$(f_x, f_y, c_x, c_y, k_1, k_2, p_1, p_2, k_3, k_4, k_5, k_6 , s_1, s_2, s_3,
s_4, \tau_x, \tau_y)\f$ If one of parameters is not estimated, it's deviation is equals to zero.
@param stdDeviationsExtrinsics Output vector of standard deviations estimated for extrinsic parameters.
Order of deviations values: \f$(R_1, T_1, \dotsc , R_M, T_M)\f$ where M is number of pattern views,
\f$R_i, T_i\f$ are concatenated 1x3 vectors.
@param perViewErrors Output vector of average re-projection errors estimated for each pattern view.
@param flags Different flags that may be zero or a combination of the following values: @param flags Different flags that may be zero or a combination of the following values:
- **CV_CALIB_USE_INTRINSIC_GUESS** cameraMatrix contains valid initial values of - **CV_CALIB_USE_INTRINSIC_GUESS** cameraMatrix contains valid initial values of
fx, fy, cx, cy that are optimized further. Otherwise, (cx, cy) is initially set to the image fx, fy, cx, cy that are optimized further. Otherwise, (cx, cy) is initially set to the image
...@@ -841,6 +849,24 @@ The function returns the final re-projection error. ...@@ -841,6 +849,24 @@ The function returns the final re-projection error.
@sa @sa
findChessboardCorners, solvePnP, initCameraMatrix2D, stereoCalibrate, undistort findChessboardCorners, solvePnP, initCameraMatrix2D, stereoCalibrate, undistort
*/ */
CV_EXPORTS_AS(calibrateCameraExtended) double calibrateCamera( InputArrayOfArrays objectPoints,
InputArrayOfArrays imagePoints, Size imageSize,
InputOutputArray cameraMatrix, InputOutputArray distCoeffs,
OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs,
OutputArray stdDeviationsIntrinsics,
OutputArray stdDeviationsExtrinsics,
OutputArray perViewErrors,
int flags = 0, TermCriteria criteria = TermCriteria(
TermCriteria::COUNT + TermCriteria::EPS, 30, DBL_EPSILON) );
/** @overload double calibrateCamera( InputArrayOfArrays objectPoints,
InputArrayOfArrays imagePoints, Size imageSize,
InputOutputArray cameraMatrix, InputOutputArray distCoeffs,
OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs,
OutputArray stdDeviations, OutputArray perViewErrors,
int flags = 0, TermCriteria criteria = TermCriteria(
TermCriteria::COUNT + TermCriteria::EPS, 30, DBL_EPSILON) )
*/
CV_EXPORTS_W double calibrateCamera( InputArrayOfArrays objectPoints, CV_EXPORTS_W double calibrateCamera( InputArrayOfArrays objectPoints,
InputArrayOfArrays imagePoints, Size imageSize, InputArrayOfArrays imagePoints, Size imageSize,
InputOutputArray cameraMatrix, InputOutputArray distCoeffs, InputOutputArray cameraMatrix, InputOutputArray distCoeffs,
......
...@@ -246,6 +246,7 @@ CVAPI(void) cvDrawChessboardCorners( CvArr* image, CvSize pattern_size, ...@@ -246,6 +246,7 @@ CVAPI(void) cvDrawChessboardCorners( CvArr* image, CvSize pattern_size,
#define CV_CALIB_TILTED_MODEL 262144 #define CV_CALIB_TILTED_MODEL 262144
#define CV_CALIB_FIX_TAUX_TAUY 524288 #define CV_CALIB_FIX_TAUX_TAUY 524288
#define CV_CALIB_NINTRINSIC 18
/* Finds intrinsic and extrinsic camera parameters /* Finds intrinsic and extrinsic camera parameters
from a few views of known calibration pattern */ from a few views of known calibration pattern */
......
This diff is collapsed.
...@@ -241,6 +241,8 @@ bool CvLevMarq::updateAlt( const CvMat*& _param, CvMat*& _JtJ, CvMat*& _JtErr, d ...@@ -241,6 +241,8 @@ bool CvLevMarq::updateAlt( const CvMat*& _param, CvMat*& _JtJ, CvMat*& _JtErr, d
cvNorm(param, prevParam, CV_RELATIVE_L2) < criteria.epsilon ) cvNorm(param, prevParam, CV_RELATIVE_L2) < criteria.epsilon )
{ {
_param = param; _param = param;
_JtJ = JtJ;
_JtErr = JtErr;
state = DONE; state = DONE;
return false; return false;
} }
......
...@@ -259,7 +259,7 @@ protected: ...@@ -259,7 +259,7 @@ protected:
virtual void calibrate( int imageCount, int* pointCounts, virtual void calibrate( int imageCount, int* pointCounts,
CvSize imageSize, CvPoint2D64f* imagePoints, CvPoint3D64f* objectPoints, CvSize imageSize, CvPoint2D64f* imagePoints, CvPoint3D64f* objectPoints,
double* distortionCoeffs, double* cameraMatrix, double* translationVectors, double* distortionCoeffs, double* cameraMatrix, double* translationVectors,
double* rotationMatrices, int flags ) = 0; double* rotationMatrices, double *stdDevs, double* perViewErrors, int flags ) = 0;
virtual void project( int pointCount, CvPoint3D64f* objectPoints, virtual void project( int pointCount, CvPoint3D64f* objectPoints,
double* rotationMatrix, double* translationVector, double* rotationMatrix, double* translationVector,
double* cameraMatrix, double* distortion, CvPoint2D64f* imagePoints ) = 0; double* cameraMatrix, double* distortion, CvPoint2D64f* imagePoints ) = 0;
...@@ -303,9 +303,13 @@ void CV_CameraCalibrationTest::run( int start_from ) ...@@ -303,9 +303,13 @@ void CV_CameraCalibrationTest::run( int start_from )
double* transVects; double* transVects;
double* rotMatrs; double* rotMatrs;
double* stdDevs;
double* perViewErrors;
double* goodTransVects; double* goodTransVects;
double* goodRotMatrs; double* goodRotMatrs;
double* goodPerViewErrors;
double* goodStdDevs;
double cameraMatrix[3*3]; double cameraMatrix[3*3];
double distortion[5]={0,0,0,0,0}; double distortion[5]={0,0,0,0,0};
...@@ -424,9 +428,13 @@ void CV_CameraCalibrationTest::run( int start_from ) ...@@ -424,9 +428,13 @@ void CV_CameraCalibrationTest::run( int start_from )
/* Allocate memory for translate vectors and rotmatrixs*/ /* Allocate memory for translate vectors and rotmatrixs*/
transVects = (double*)cvAlloc(3 * 1 * numImages * sizeof(double)); transVects = (double*)cvAlloc(3 * 1 * numImages * sizeof(double));
rotMatrs = (double*)cvAlloc(3 * 3 * numImages * sizeof(double)); rotMatrs = (double*)cvAlloc(3 * 3 * numImages * sizeof(double));
stdDevs = (double*)cvAlloc((CV_CALIB_NINTRINSIC + 6*numImages) * sizeof(double));
perViewErrors = (double*)cvAlloc(numImages * sizeof(double));
goodTransVects = (double*)cvAlloc(3 * 1 * numImages * sizeof(double)); goodTransVects = (double*)cvAlloc(3 * 1 * numImages * sizeof(double));
goodRotMatrs = (double*)cvAlloc(3 * 3 * numImages * sizeof(double)); goodRotMatrs = (double*)cvAlloc(3 * 3 * numImages * sizeof(double));
goodPerViewErrors = (double*)cvAlloc(numImages * sizeof(double));
goodStdDevs = (double*)cvAlloc((CV_CALIB_NINTRINSIC + 6*numImages) * sizeof(double));
/* Read object points */ /* Read object points */
i = 0;/* shift for current point */ i = 0;/* shift for current point */
...@@ -501,6 +509,13 @@ void CV_CameraCalibrationTest::run( int start_from ) ...@@ -501,6 +509,13 @@ void CV_CameraCalibrationTest::run( int start_from )
} }
} }
/* Read good stdDeviations */
for (i = 0; i < CV_CALIB_NINTRINSIC + numImages*6; i++)
{
values_read = fscanf(file, "%lf", goodStdDevs + i);
CV_Assert(values_read == 1);
}
calibFlags = 0 calibFlags = 0
// + CV_CALIB_FIX_PRINCIPAL_POINT // + CV_CALIB_FIX_PRINCIPAL_POINT
// + CV_CALIB_ZERO_TANGENT_DIST // + CV_CALIB_ZERO_TANGENT_DIST
...@@ -526,6 +541,8 @@ void CV_CameraCalibrationTest::run( int start_from ) ...@@ -526,6 +541,8 @@ void CV_CameraCalibrationTest::run( int start_from )
cameraMatrix, cameraMatrix,
transVects, transVects,
rotMatrs, rotMatrs,
stdDevs,
perViewErrors,
calibFlags ); calibFlags );
/* ---- Reproject points to the image ---- */ /* ---- Reproject points to the image ---- */
...@@ -553,6 +570,8 @@ void CV_CameraCalibrationTest::run( int start_from ) ...@@ -553,6 +570,8 @@ void CV_CameraCalibrationTest::run( int start_from )
meanDy = 0; meanDy = 0;
for( currImage = 0; currImage < numImages; currImage++ ) for( currImage = 0; currImage < numImages; currImage++ )
{ {
double imageMeanDx = 0;
double imageMeanDy = 0;
for( currPoint = 0; currPoint < etalonSize.width * etalonSize.height; currPoint++ ) for( currPoint = 0; currPoint < etalonSize.width * etalonSize.height; currPoint++ )
{ {
rx = reprojectPoints[i].x; rx = reprojectPoints[i].x;
...@@ -563,6 +582,9 @@ void CV_CameraCalibrationTest::run( int start_from ) ...@@ -563,6 +582,9 @@ void CV_CameraCalibrationTest::run( int start_from )
meanDx += dx; meanDx += dx;
meanDy += dy; meanDy += dy;
imageMeanDx += dx*dx;
imageMeanDy += dy*dy;
dx = fabs(dx); dx = fabs(dx);
dy = fabs(dy); dy = fabs(dy);
...@@ -573,6 +595,13 @@ void CV_CameraCalibrationTest::run( int start_from ) ...@@ -573,6 +595,13 @@ void CV_CameraCalibrationTest::run( int start_from )
maxDy = dy; maxDy = dy;
i++; i++;
} }
goodPerViewErrors[currImage] = sqrt( (imageMeanDx + imageMeanDy) /
(etalonSize.width * etalonSize.height));
//only for c-version of test (it does not provides evaluation of perViewErrors
//and returns zeros)
if(perViewErrors[currImage] == 0.0)
perViewErrors[currImage] = goodPerViewErrors[currImage];
} }
meanDx /= numImages * etalonSize.width * etalonSize.height; meanDx /= numImages * etalonSize.width * etalonSize.height;
...@@ -613,6 +642,23 @@ void CV_CameraCalibrationTest::run( int start_from ) ...@@ -613,6 +642,23 @@ void CV_CameraCalibrationTest::run( int start_from )
if( code < 0 ) if( code < 0 )
goto _exit_; goto _exit_;
/* ----- Compare per view re-projection errors ----- */
code = compare(perViewErrors,goodPerViewErrors, numImages,0.1,"per view errors vector");
if( code < 0 )
goto _exit_;
/* ----- Compare standard deviations of parameters ----- */
//only for c-version of test (it does not provides evaluation of stdDevs
//and returns zeros)
for ( i = 0; i < CV_CALIB_NINTRINSIC + 6*numImages; i++)
{
if(stdDevs[i] == 0.0)
stdDevs[i] = goodStdDevs[i];
}
code = compare(stdDevs,goodStdDevs, CV_CALIB_NINTRINSIC + 6*numImages,.5,"stdDevs vector");
if( code < 0 )
goto _exit_;
if( maxDx > 1.0 ) if( maxDx > 1.0 )
{ {
ts->printf( cvtest::TS::LOG, ts->printf( cvtest::TS::LOG,
...@@ -636,8 +682,12 @@ void CV_CameraCalibrationTest::run( int start_from ) ...@@ -636,8 +682,12 @@ void CV_CameraCalibrationTest::run( int start_from )
cvFree(&transVects); cvFree(&transVects);
cvFree(&rotMatrs); cvFree(&rotMatrs);
cvFree(&stdDevs);
cvFree(&perViewErrors);
cvFree(&goodTransVects); cvFree(&goodTransVects);
cvFree(&goodRotMatrs); cvFree(&goodRotMatrs);
cvFree(&goodPerViewErrors);
cvFree(&goodStdDevs);
fclose(file); fclose(file);
file = 0; file = 0;
...@@ -676,20 +726,28 @@ protected: ...@@ -676,20 +726,28 @@ protected:
virtual void calibrate( int imageCount, int* pointCounts, virtual void calibrate( int imageCount, int* pointCounts,
CvSize imageSize, CvPoint2D64f* imagePoints, CvPoint3D64f* objectPoints, CvSize imageSize, CvPoint2D64f* imagePoints, CvPoint3D64f* objectPoints,
double* distortionCoeffs, double* cameraMatrix, double* translationVectors, double* distortionCoeffs, double* cameraMatrix, double* translationVectors,
double* rotationMatrices, int flags ); double* rotationMatrices, double *stdDevs, double* perViewErrors, int flags );
virtual void project( int pointCount, CvPoint3D64f* objectPoints, virtual void project( int pointCount, CvPoint3D64f* objectPoints,
double* rotationMatrix, double* translationVector, double* rotationMatrix, double* translationVector,
double* cameraMatrix, double* distortion, CvPoint2D64f* imagePoints ); double* cameraMatrix, double* distortion, CvPoint2D64f* imagePoints );
}; };
void CV_CameraCalibrationTest_C::calibrate( int imageCount, int* pointCounts, void CV_CameraCalibrationTest_C::calibrate(int imageCount, int* pointCounts,
CvSize imageSize, CvPoint2D64f* imagePoints, CvPoint3D64f* objectPoints, CvSize imageSize, CvPoint2D64f* imagePoints, CvPoint3D64f* objectPoints,
double* distortionCoeffs, double* cameraMatrix, double* translationVectors, double* distortionCoeffs, double* cameraMatrix, double* translationVectors,
double* rotationMatrices, int flags ) double* rotationMatrices, double *stdDevs, double *perViewErrors, int flags )
{ {
int i, total = 0; int i, total = 0;
for( i = 0; i < imageCount; i++ ) for( i = 0; i < imageCount; i++ )
{
perViewErrors[i] = 0.0;
total += pointCounts[i]; total += pointCounts[i];
}
for( i = 0; i < CV_CALIB_NINTRINSIC + imageCount*6; i++)
{
stdDevs[i] = 0.0;
}
CvMat _objectPoints = cvMat(1, total, CV_64FC3, objectPoints); CvMat _objectPoints = cvMat(1, total, CV_64FC3, objectPoints);
CvMat _imagePoints = cvMat(1, total, CV_64FC2, imagePoints); CvMat _imagePoints = cvMat(1, total, CV_64FC2, imagePoints);
...@@ -700,8 +758,7 @@ void CV_CameraCalibrationTest_C::calibrate( int imageCount, int* pointCounts, ...@@ -700,8 +758,7 @@ void CV_CameraCalibrationTest_C::calibrate( int imageCount, int* pointCounts,
CvMat _translationVectors = cvMat(imageCount, 3, CV_64F, translationVectors); CvMat _translationVectors = cvMat(imageCount, 3, CV_64F, translationVectors);
cvCalibrateCamera2(&_objectPoints, &_imagePoints, &_pointCounts, imageSize, cvCalibrateCamera2(&_objectPoints, &_imagePoints, &_pointCounts, imageSize,
&_cameraMatrix, &_distCoeffs, &_rotationMatrices, &_translationVectors, &_cameraMatrix, &_distCoeffs, &_rotationMatrices, &_translationVectors, flags);
flags);
} }
void CV_CameraCalibrationTest_C::project( int pointCount, CvPoint3D64f* objectPoints, void CV_CameraCalibrationTest_C::project( int pointCount, CvPoint3D64f* objectPoints,
...@@ -728,22 +785,24 @@ protected: ...@@ -728,22 +785,24 @@ protected:
virtual void calibrate( int imageCount, int* pointCounts, virtual void calibrate( int imageCount, int* pointCounts,
CvSize imageSize, CvPoint2D64f* imagePoints, CvPoint3D64f* objectPoints, CvSize imageSize, CvPoint2D64f* imagePoints, CvPoint3D64f* objectPoints,
double* distortionCoeffs, double* cameraMatrix, double* translationVectors, double* distortionCoeffs, double* cameraMatrix, double* translationVectors,
double* rotationMatrices, int flags ); double* rotationMatrices, double *stdDevs, double* perViewErrors, int flags );
virtual void project( int pointCount, CvPoint3D64f* objectPoints, virtual void project( int pointCount, CvPoint3D64f* objectPoints,
double* rotationMatrix, double* translationVector, double* rotationMatrix, double* translationVector,
double* cameraMatrix, double* distortion, CvPoint2D64f* imagePoints ); double* cameraMatrix, double* distortion, CvPoint2D64f* imagePoints );
}; };
void CV_CameraCalibrationTest_CPP::calibrate( int imageCount, int* pointCounts, void CV_CameraCalibrationTest_CPP::calibrate(int imageCount, int* pointCounts,
CvSize _imageSize, CvPoint2D64f* _imagePoints, CvPoint3D64f* _objectPoints, CvSize _imageSize, CvPoint2D64f* _imagePoints, CvPoint3D64f* _objectPoints,
double* _distortionCoeffs, double* _cameraMatrix, double* translationVectors, double* _distortionCoeffs, double* _cameraMatrix, double* translationVectors,
double* rotationMatrices, int flags ) double* rotationMatrices, double *stdDevs, double *perViewErrors, int flags )
{ {
vector<vector<Point3f> > objectPoints( imageCount ); vector<vector<Point3f> > objectPoints( imageCount );
vector<vector<Point2f> > imagePoints( imageCount ); vector<vector<Point2f> > imagePoints( imageCount );
Size imageSize = _imageSize; Size imageSize = _imageSize;
Mat cameraMatrix, distCoeffs(1,4,CV_64F,Scalar::all(0)); Mat cameraMatrix, distCoeffs(1,4,CV_64F,Scalar::all(0));
vector<Mat> rvecs, tvecs; vector<Mat> rvecs, tvecs;
Mat stdDevsMatInt, stdDevsMatExt;
Mat perViewErrorsMat;
CvPoint3D64f* op = _objectPoints; CvPoint3D64f* op = _objectPoints;
CvPoint2D64f* ip = _imagePoints; CvPoint2D64f* ip = _imagePoints;
...@@ -770,8 +829,23 @@ void CV_CameraCalibrationTest_CPP::calibrate( int imageCount, int* pointCounts, ...@@ -770,8 +829,23 @@ void CV_CameraCalibrationTest_CPP::calibrate( int imageCount, int* pointCounts,
distCoeffs, distCoeffs,
rvecs, rvecs,
tvecs, tvecs,
stdDevsMatInt,
stdDevsMatExt,
perViewErrorsMat,
flags ); flags );
assert( stdDevsMatInt.type() == CV_64F );
assert( stdDevsMatInt.total() == static_cast<size_t>(CV_CALIB_NINTRINSIC) );
memcpy( stdDevs, stdDevsMatInt.ptr(), CV_CALIB_NINTRINSIC*sizeof(double) );
assert( stdDevsMatExt.type() == CV_64F );
assert( stdDevsMatExt.total() == static_cast<size_t>(6*imageCount) );
memcpy( stdDevs + CV_CALIB_NINTRINSIC, stdDevsMatExt.ptr(), 6*imageCount*sizeof(double) );
assert( perViewErrorsMat.type() == CV_64F);
assert( perViewErrorsMat.total() == static_cast<size_t>(imageCount) );
memcpy( perViewErrors, perViewErrorsMat.ptr(), imageCount*sizeof(double) );
assert( cameraMatrix.type() == CV_64FC1 ); assert( cameraMatrix.type() == CV_64FC1 );
memcpy( _cameraMatrix, cameraMatrix.ptr(), 9*sizeof(double) ); memcpy( _cameraMatrix, cameraMatrix.ptr(), 9*sizeof(double) );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment