2011-02-10 04:55:11 +08:00
|
|
|
/*M///////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
|
|
|
//
|
|
|
|
// By downloading, copying, installing or using the software you agree to this license.
|
|
|
|
// If you do not agree to this license, do not download, install,
|
|
|
|
// copy or use the software.
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// Intel License Agreement
|
|
|
|
// For Open Source Computer Vision Library
|
|
|
|
//
|
|
|
|
// Copyright (C) 2000, Intel Corporation, all rights reserved.
|
|
|
|
// Third party copyrights are property of their respective owners.
|
|
|
|
//
|
|
|
|
// Redistribution and use in source and binary forms, with or without modification,
|
|
|
|
// are permitted provided that the following conditions are met:
|
|
|
|
//
|
|
|
|
// * Redistribution's of source code must retain the above copyright notice,
|
|
|
|
// this list of conditions and the following disclaimer.
|
|
|
|
//
|
|
|
|
// * Redistribution's in binary form must reproduce the above copyright notice,
|
|
|
|
// this list of conditions and the following disclaimer in the documentation
|
|
|
|
// and/or other materials provided with the distribution.
|
|
|
|
//
|
|
|
|
// * The name of Intel Corporation may not be used to endorse or promote products
|
|
|
|
// derived from this software without specific prior written permission.
|
|
|
|
//
|
|
|
|
// This software is provided by the copyright holders and contributors "as is" and
|
|
|
|
// any express or implied warranties, including, but not limited to, the implied
|
|
|
|
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
|
|
|
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
|
|
|
// indirect, incidental, special, exemplary, or consequential damages
|
|
|
|
// (including, but not limited to, procurement of substitute goods or services;
|
|
|
|
// loss of use, data, or profits; or business interruption) however caused
|
|
|
|
// and on any theory of liability, whether in contract, strict liability,
|
|
|
|
// or tort (including negligence or otherwise) arising in any way out of
|
|
|
|
// the use of this software, even if advised of the possibility of such damage.
|
|
|
|
//
|
|
|
|
//M*/
|
|
|
|
|
|
|
|
#include "test_precomp.hpp"
|
|
|
|
#include "test_chessboardgenerator.hpp"
|
2018-11-09 21:12:22 +08:00
|
|
|
#include "opencv2/core/types_c.h"
|
2011-02-10 04:55:11 +08:00
|
|
|
|
2017-11-05 21:48:40 +08:00
|
|
|
namespace opencv_test { namespace {
|
2011-02-10 04:55:11 +08:00
|
|
|
|
|
|
|
class CV_CameraCalibrationBadArgTest : public cvtest::BadArgTest
|
|
|
|
{
|
|
|
|
public:
|
2018-11-09 21:12:22 +08:00
|
|
|
CV_CameraCalibrationBadArgTest() {}
|
2011-02-10 04:55:11 +08:00
|
|
|
~CV_CameraCalibrationBadArgTest() {}
|
2012-10-17 15:12:04 +08:00
|
|
|
protected:
|
|
|
|
void run(int);
|
2014-01-18 05:30:29 +08:00
|
|
|
void run_func(void) {}
|
2011-02-10 04:55:11 +08:00
|
|
|
|
|
|
|
struct C_Caller
|
|
|
|
{
|
2018-11-09 21:12:22 +08:00
|
|
|
_InputArray imgPts_arg;
|
|
|
|
_InputArray objPts_arg;
|
|
|
|
_OutputArray rvecs_arg;
|
|
|
|
_OutputArray tvecs_arg;
|
|
|
|
_OutputArray newObjPts_arg;
|
|
|
|
_InputOutputArray cameraMatrix_arg;
|
|
|
|
_InputOutputArray distCoeffs_arg;
|
|
|
|
|
|
|
|
std::vector<std::vector<Point2f> > imgPts;
|
|
|
|
std::vector<std::vector<Point3f> > objPts;
|
|
|
|
|
|
|
|
Size imageSize0, imageSize;
|
|
|
|
int iFixedPoint0, iFixedPoint;
|
|
|
|
Mat cameraMatrix;
|
|
|
|
Mat distCoeffs;
|
|
|
|
std::vector<Mat> rvecs;
|
|
|
|
std::vector<Mat> tvecs;
|
|
|
|
std::vector<Point3f> newObjPts;
|
|
|
|
int flags0, flags;
|
|
|
|
|
|
|
|
void initArgs()
|
|
|
|
{
|
|
|
|
imgPts_arg = imgPts;
|
|
|
|
objPts_arg = objPts;
|
|
|
|
rvecs_arg = rvecs;
|
|
|
|
tvecs_arg = tvecs;
|
|
|
|
newObjPts_arg = newObjPts;
|
|
|
|
cameraMatrix_arg = cameraMatrix;
|
|
|
|
distCoeffs_arg = distCoeffs;
|
|
|
|
imageSize = imageSize0;
|
|
|
|
flags = flags0;
|
|
|
|
iFixedPoint = iFixedPoint0;
|
|
|
|
}
|
2011-02-10 04:55:11 +08:00
|
|
|
|
2012-10-17 15:12:04 +08:00
|
|
|
void operator()() const
|
|
|
|
{
|
2018-11-09 21:12:22 +08:00
|
|
|
calibrateCameraRO(objPts_arg, imgPts_arg, imageSize, iFixedPoint,
|
|
|
|
cameraMatrix_arg, distCoeffs_arg, rvecs_arg, tvecs_arg,
|
|
|
|
newObjPts_arg, flags);
|
2011-02-10 04:55:11 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
void CV_CameraCalibrationBadArgTest::run( int /* start_from */ )
|
2012-10-17 15:12:04 +08:00
|
|
|
{
|
2018-11-09 21:12:22 +08:00
|
|
|
const int M = 2;
|
|
|
|
Size imgSize(800, 600);
|
2011-02-10 04:55:11 +08:00
|
|
|
Mat_<float> camMat(3, 3);
|
|
|
|
Mat_<float> distCoeffs0(1, 5);
|
2012-10-17 15:12:04 +08:00
|
|
|
|
|
|
|
camMat << 300.f, 0.f, imgSize.width/2.f, 0, 300.f, imgSize.height/2.f, 0.f, 0.f, 1.f;
|
2011-02-10 04:55:11 +08:00
|
|
|
distCoeffs0 << 1.2f, 0.2f, 0.f, 0.f, 0.f;
|
2012-10-17 15:12:04 +08:00
|
|
|
|
2011-02-10 04:55:11 +08:00
|
|
|
ChessBoardGenerator cbg(Size(8,6));
|
2018-11-09 21:12:22 +08:00
|
|
|
Size corSize = cbg.cornersSize();
|
|
|
|
vector<Point2f> corners;
|
|
|
|
cbg(Mat(imgSize, CV_8U, Scalar(0)), camMat, distCoeffs0, corners);
|
|
|
|
|
|
|
|
C_Caller caller;
|
|
|
|
caller.imageSize0 = imgSize;
|
|
|
|
caller.iFixedPoint0 = -1;
|
|
|
|
caller.flags0 = 0;
|
2011-02-10 04:55:11 +08:00
|
|
|
|
2012-10-17 15:12:04 +08:00
|
|
|
/////////////////////////////
|
2011-02-10 04:55:11 +08:00
|
|
|
Mat cameraMatrix_cpp;
|
|
|
|
Mat distCoeffs_cpp;
|
|
|
|
Mat rvecs_cpp;
|
2012-10-17 15:12:04 +08:00
|
|
|
Mat tvecs_cpp;
|
Merge pull request #12772 from xoox:calib-release-object
More accurate pinhole camera calibration with imperfect planar target (#12772)
43 commits:
* Add derivatives with respect to object points
Add an output parameter to calculate derivatives of image points with
respect to 3D coordinates of object points. The output jacobian matrix
is a 2Nx3N matrix where N is the number of points.
This commit introduces incompatibility to old function signature.
* Set zero for dpdo matrix before using
dpdo is a sparse matrix with only non-zero value close to major
diagonal. Set it to zero because only elements near major diagonal are
computed.
* Add jacobian columns to projectPoints()
The output jacobian matrix of derivatives with respect to coordinates of
3D object points are added. This might break callers who assume the
columns of jacobian matrix.
* Adapt test code to updated project functions
The test cases for projectPoints() and cvProjectPoints2() are updated to
fit new function signatures.
* Add accuracy test code for dpdo
* Add badarg test for dpdo
* Add new enum item for new calibration method
CALIB_RELEASE_OBJECT is used to whether to release 3D coordinates of
object points. The method was proposed in: K. H. Strobl and G. Hirzinger.
"More Accurate Pinhole Camera Calibration with Imperfect Planar Target".
In Proceedings of the IEEE International Conference on Computer Vision
(ICCV 2011), 1st IEEE Workshop on Challenges and Opportunities in Robot
Perception, Barcelona, Spain, pp. 1068-1075, November 2011.
* Add releasing object method into internal function
It's a simple extension of the standard calibration scheme. We choose to
fix the first and last object point and a user-selected fixed point.
* Add interfaces for extended calibration method
* Refine document for calibrateCamera()
When releasing object points, only the z coordinates of the
objectPoints[0].back is fixed.
* Add link to strobl2011iccv paper
* Improve documentation for calibrateCamera()
* Add implementations of wrapping calibrateCamera()
* Add checking for params of new calibration method
If input parameters are not qualified, then fall back to standard
calibration method.
* Add camera calibration method of releasing object
The current implementation is equal to or better than
https://github.com/xoox/calibrel
* Update doc for CALIB_RELEASE_OBJECT
CALIB_USE_QR or CALIB_USE_LU could be used for faster calibration with
potentially less precise and less stable in some rare cases.
* Add RELEASE_OBJECT calibration to tutorial code
To select the calibration method of releasing object points, a command
line parameter `-d=<number>` should be provided.
* Update tutorial doc for camera_calibration
If the method of releasing object points is merged into OpenCV. It will
be expected to be firstly released in 4.1, I think.
* Reduce epsilon for cornerSubPix()
Epsilon of 0.1 is a bigger one. Preciser corner positions are required
with calibration method of releasing object.
* Refine camera calibration tutorial
The hypothesis coordinates are used to indicate which distance must be
measured between two specified object points.
* Update sample calibration code method selection
Similar to camera_calibration tutorial application, a command line
argument `-dt=<number>` is used to select the calibration method.
* Add guard to flags of cvCalibrateCamera2()
cvCalibrateCamera2() doesn't accept CALIB_RELEASE_OBJECT unless overload
interface is added in the future.
* Simplify fallback when iFixedPoint is out of range
* Refactor projectPoints() to keep compatibilities
* Fix arg string "Bad rvecs header"
* Read calibration flags from test data files
Instead of being hard coded into source file, the calibration flags will
be read from test data files.
opencv_extra/testdata/cv/cameracalibration/calib?.dat must be sync with
the test code.
* Add new C interface of cvCalibrateCamera4()
With this new added C interface, the extended calibration method with
CALIB_RELEASE_OBJECT can be called by C API.
* Add regression test of extended calibration method
It has been tested with new added test data in xoox:calib-release-object
branch of opencv_extra.
* Fix assertion in test_cameracalibration.cpp
The total number of refined 3D object coordinates is checked.
* Add checker for iFixedPoint in cvCalibrateCamera4
If iFixedPoint is out of rational range, fall back to standard method.
* Fix documentation for overloaded calibrateCamera()
* Remove calibration flag of CALIB_RELEASE_OBJECT
The method selection is based on the range of the index of fixed point.
For minus values, standard calibration method will be chosen. Values in
a rational range will make the object-releasing calibration method
selected.
* Use new interfaces instead of function overload
Existing interfaces are preserved and new interfaces are added. Since
most part of the code base are shared, calibrateCamera() is now a
wrapper function of calibrateCameraRO().
* Fix exported name of calibrateCameraRO()
* Update documentation for calibrateCameraRO()
The circumstances where this method is mostly helpful are described.
* Add note on the rigidity of the calibration target
* Update documentation for calibrateCameraRO()
It is clarified that iFixedPoint is used as a switch to select
calibration method. If input data are not qualified, exceptions will be
thrown instead of fallback scheme.
* Clarify iFixedPoint as switch and remove fallback
iFixedPoint is now used as a switch for calibration method selection. No
fallback scheme is utilized anymore. If the input data are not
qualified, exceptions will be thrown.
* Add badarg test for object-releasing method
* Fix document format of sample list
List items of same level should be indented the same way. Otherwise they
will be formatted as nested lists by Doxygen.
* Add brief intro for objectPoints and imagePoints
* Sync tutorial to sample calibration code
* Update tutorial compatibility version to 4.0
2018-10-26 00:38:55 +08:00
|
|
|
Mat newObjPts_cpp;
|
2012-10-17 15:12:04 +08:00
|
|
|
|
2018-11-09 21:12:22 +08:00
|
|
|
std::vector<Point3f> objPts_cpp;
|
|
|
|
for(int y = 0; y < corSize.height; ++y)
|
|
|
|
for(int x = 0; x < corSize.width; ++x)
|
|
|
|
objPts_cpp.push_back(Point3f((float)x, (float)y, 0.f));
|
|
|
|
caller.objPts.resize(M);
|
|
|
|
caller.imgPts.resize(M);
|
Merge pull request #12772 from xoox:calib-release-object
More accurate pinhole camera calibration with imperfect planar target (#12772)
43 commits:
* Add derivatives with respect to object points
Add an output parameter to calculate derivatives of image points with
respect to 3D coordinates of object points. The output jacobian matrix
is a 2Nx3N matrix where N is the number of points.
This commit introduces incompatibility to old function signature.
* Set zero for dpdo matrix before using
dpdo is a sparse matrix with only non-zero value close to major
diagonal. Set it to zero because only elements near major diagonal are
computed.
* Add jacobian columns to projectPoints()
The output jacobian matrix of derivatives with respect to coordinates of
3D object points are added. This might break callers who assume the
columns of jacobian matrix.
* Adapt test code to updated project functions
The test cases for projectPoints() and cvProjectPoints2() are updated to
fit new function signatures.
* Add accuracy test code for dpdo
* Add badarg test for dpdo
* Add new enum item for new calibration method
CALIB_RELEASE_OBJECT is used to whether to release 3D coordinates of
object points. The method was proposed in: K. H. Strobl and G. Hirzinger.
"More Accurate Pinhole Camera Calibration with Imperfect Planar Target".
In Proceedings of the IEEE International Conference on Computer Vision
(ICCV 2011), 1st IEEE Workshop on Challenges and Opportunities in Robot
Perception, Barcelona, Spain, pp. 1068-1075, November 2011.
* Add releasing object method into internal function
It's a simple extension of the standard calibration scheme. We choose to
fix the first and last object point and a user-selected fixed point.
* Add interfaces for extended calibration method
* Refine document for calibrateCamera()
When releasing object points, only the z coordinates of the
objectPoints[0].back is fixed.
* Add link to strobl2011iccv paper
* Improve documentation for calibrateCamera()
* Add implementations of wrapping calibrateCamera()
* Add checking for params of new calibration method
If input parameters are not qualified, then fall back to standard
calibration method.
* Add camera calibration method of releasing object
The current implementation is equal to or better than
https://github.com/xoox/calibrel
* Update doc for CALIB_RELEASE_OBJECT
CALIB_USE_QR or CALIB_USE_LU could be used for faster calibration with
potentially less precise and less stable in some rare cases.
* Add RELEASE_OBJECT calibration to tutorial code
To select the calibration method of releasing object points, a command
line parameter `-d=<number>` should be provided.
* Update tutorial doc for camera_calibration
If the method of releasing object points is merged into OpenCV. It will
be expected to be firstly released in 4.1, I think.
* Reduce epsilon for cornerSubPix()
Epsilon of 0.1 is a bigger one. Preciser corner positions are required
with calibration method of releasing object.
* Refine camera calibration tutorial
The hypothesis coordinates are used to indicate which distance must be
measured between two specified object points.
* Update sample calibration code method selection
Similar to camera_calibration tutorial application, a command line
argument `-dt=<number>` is used to select the calibration method.
* Add guard to flags of cvCalibrateCamera2()
cvCalibrateCamera2() doesn't accept CALIB_RELEASE_OBJECT unless overload
interface is added in the future.
* Simplify fallback when iFixedPoint is out of range
* Refactor projectPoints() to keep compatibilities
* Fix arg string "Bad rvecs header"
* Read calibration flags from test data files
Instead of being hard coded into source file, the calibration flags will
be read from test data files.
opencv_extra/testdata/cv/cameracalibration/calib?.dat must be sync with
the test code.
* Add new C interface of cvCalibrateCamera4()
With this new added C interface, the extended calibration method with
CALIB_RELEASE_OBJECT can be called by C API.
* Add regression test of extended calibration method
It has been tested with new added test data in xoox:calib-release-object
branch of opencv_extra.
* Fix assertion in test_cameracalibration.cpp
The total number of refined 3D object coordinates is checked.
* Add checker for iFixedPoint in cvCalibrateCamera4
If iFixedPoint is out of rational range, fall back to standard method.
* Fix documentation for overloaded calibrateCamera()
* Remove calibration flag of CALIB_RELEASE_OBJECT
The method selection is based on the range of the index of fixed point.
For minus values, standard calibration method will be chosen. Values in
a rational range will make the object-releasing calibration method
selected.
* Use new interfaces instead of function overload
Existing interfaces are preserved and new interfaces are added. Since
most part of the code base are shared, calibrateCamera() is now a
wrapper function of calibrateCameraRO().
* Fix exported name of calibrateCameraRO()
* Update documentation for calibrateCameraRO()
The circumstances where this method is mostly helpful are described.
* Add note on the rigidity of the calibration target
* Update documentation for calibrateCameraRO()
It is clarified that iFixedPoint is used as a switch to select
calibration method. If input data are not qualified, exceptions will be
thrown instead of fallback scheme.
* Clarify iFixedPoint as switch and remove fallback
iFixedPoint is now used as a switch for calibration method selection. No
fallback scheme is utilized anymore. If the input data are not
qualified, exceptions will be thrown.
* Add badarg test for object-releasing method
* Fix document format of sample list
List items of same level should be indented the same way. Otherwise they
will be formatted as nested lists by Doxygen.
* Add brief intro for objectPoints and imagePoints
* Sync tutorial to sample calibration code
* Update tutorial compatibility version to 4.0
2018-10-26 00:38:55 +08:00
|
|
|
for(int i = 0; i < M; i++)
|
2018-11-09 21:12:22 +08:00
|
|
|
{
|
|
|
|
caller.objPts[i] = objPts_cpp;
|
|
|
|
caller.imgPts[i] = corners;
|
|
|
|
}
|
|
|
|
caller.cameraMatrix.create(3, 3, CV_32F);
|
|
|
|
caller.distCoeffs.create(5, 1, CV_32F);
|
|
|
|
caller.rvecs.clear();
|
|
|
|
caller.tvecs.clear();
|
|
|
|
caller.newObjPts.clear();
|
2011-02-10 04:55:11 +08:00
|
|
|
|
|
|
|
/* /*//*/ */
|
|
|
|
int errors = 0;
|
2012-10-17 15:12:04 +08:00
|
|
|
|
2018-11-09 21:12:22 +08:00
|
|
|
caller.initArgs();
|
|
|
|
caller.objPts_arg = noArray();
|
2024-03-05 17:18:31 +08:00
|
|
|
errors += run_test_case( cv::Error::StsBadArg, "None passed in objPts", caller);
|
2011-02-10 04:55:11 +08:00
|
|
|
|
2018-11-09 21:12:22 +08:00
|
|
|
caller.initArgs();
|
|
|
|
caller.imgPts_arg = noArray();
|
2024-03-05 17:18:31 +08:00
|
|
|
errors += run_test_case( cv::Error::StsBadArg, "None passed in imgPts", caller );
|
2012-10-17 15:12:04 +08:00
|
|
|
|
2018-11-09 21:12:22 +08:00
|
|
|
caller.initArgs();
|
|
|
|
caller.cameraMatrix_arg = noArray();
|
2024-03-05 17:18:31 +08:00
|
|
|
errors += run_test_case( cv::Error::StsBadArg, "Zero passed in cameraMatrix", caller );
|
2011-02-10 04:55:11 +08:00
|
|
|
|
2018-11-09 21:12:22 +08:00
|
|
|
caller.initArgs();
|
|
|
|
caller.distCoeffs_arg = noArray();
|
2024-03-05 17:18:31 +08:00
|
|
|
errors += run_test_case( cv::Error::StsBadArg, "Zero passed in distCoeffs", caller );
|
2011-02-10 04:55:11 +08:00
|
|
|
|
2018-11-09 21:12:22 +08:00
|
|
|
caller.initArgs();
|
|
|
|
caller.imageSize.width = -1;
|
2024-03-05 17:18:31 +08:00
|
|
|
errors += run_test_case( cv::Error::StsOutOfRange, "Bad image width", caller );
|
2011-02-10 04:55:11 +08:00
|
|
|
|
2018-11-09 21:12:22 +08:00
|
|
|
caller.initArgs();
|
|
|
|
caller.imageSize.height = -1;
|
2024-03-05 17:18:31 +08:00
|
|
|
errors += run_test_case( cv::Error::StsOutOfRange, "Bad image height", caller );
|
2011-02-10 04:55:11 +08:00
|
|
|
|
2018-11-09 21:12:22 +08:00
|
|
|
caller.initArgs();
|
|
|
|
caller.imgPts[0].clear();
|
2024-03-05 17:18:31 +08:00
|
|
|
errors += run_test_case( cv::Error::StsBadSize, "Bad imgpts[0]", caller );
|
2018-11-09 21:12:22 +08:00
|
|
|
caller.imgPts[0] = caller.imgPts[1];
|
2011-02-10 04:55:11 +08:00
|
|
|
|
2018-11-09 21:12:22 +08:00
|
|
|
caller.initArgs();
|
|
|
|
caller.objPts[1].clear();
|
2024-03-05 17:18:31 +08:00
|
|
|
errors += run_test_case( cv::Error::StsBadSize, "Bad objpts[1]", caller );
|
2018-11-09 21:12:22 +08:00
|
|
|
caller.objPts[1] = caller.objPts[0];
|
2012-10-17 15:12:04 +08:00
|
|
|
|
2018-11-09 21:12:22 +08:00
|
|
|
caller.initArgs();
|
|
|
|
Mat badCM = Mat::zeros(4, 4, CV_64F);
|
|
|
|
caller.cameraMatrix_arg = badCM;
|
|
|
|
caller.flags = CALIB_USE_INTRINSIC_GUESS;
|
2024-03-05 17:18:31 +08:00
|
|
|
errors += run_test_case( cv::Error::StsBadArg, "Bad camearaMatrix header", caller );
|
2011-02-10 04:55:11 +08:00
|
|
|
|
2018-11-09 21:12:22 +08:00
|
|
|
caller.initArgs();
|
|
|
|
Mat badDC = Mat::zeros(10, 10, CV_64F);
|
|
|
|
caller.distCoeffs_arg = badDC;
|
|
|
|
caller.flags = CALIB_USE_INTRINSIC_GUESS;
|
2024-03-05 17:18:31 +08:00
|
|
|
errors += run_test_case( cv::Error::StsBadArg, "Bad camearaMatrix header", caller );
|
Merge pull request #12772 from xoox:calib-release-object
More accurate pinhole camera calibration with imperfect planar target (#12772)
43 commits:
* Add derivatives with respect to object points
Add an output parameter to calculate derivatives of image points with
respect to 3D coordinates of object points. The output jacobian matrix
is a 2Nx3N matrix where N is the number of points.
This commit introduces incompatibility to old function signature.
* Set zero for dpdo matrix before using
dpdo is a sparse matrix with only non-zero value close to major
diagonal. Set it to zero because only elements near major diagonal are
computed.
* Add jacobian columns to projectPoints()
The output jacobian matrix of derivatives with respect to coordinates of
3D object points are added. This might break callers who assume the
columns of jacobian matrix.
* Adapt test code to updated project functions
The test cases for projectPoints() and cvProjectPoints2() are updated to
fit new function signatures.
* Add accuracy test code for dpdo
* Add badarg test for dpdo
* Add new enum item for new calibration method
CALIB_RELEASE_OBJECT is used to whether to release 3D coordinates of
object points. The method was proposed in: K. H. Strobl and G. Hirzinger.
"More Accurate Pinhole Camera Calibration with Imperfect Planar Target".
In Proceedings of the IEEE International Conference on Computer Vision
(ICCV 2011), 1st IEEE Workshop on Challenges and Opportunities in Robot
Perception, Barcelona, Spain, pp. 1068-1075, November 2011.
* Add releasing object method into internal function
It's a simple extension of the standard calibration scheme. We choose to
fix the first and last object point and a user-selected fixed point.
* Add interfaces for extended calibration method
* Refine document for calibrateCamera()
When releasing object points, only the z coordinates of the
objectPoints[0].back is fixed.
* Add link to strobl2011iccv paper
* Improve documentation for calibrateCamera()
* Add implementations of wrapping calibrateCamera()
* Add checking for params of new calibration method
If input parameters are not qualified, then fall back to standard
calibration method.
* Add camera calibration method of releasing object
The current implementation is equal to or better than
https://github.com/xoox/calibrel
* Update doc for CALIB_RELEASE_OBJECT
CALIB_USE_QR or CALIB_USE_LU could be used for faster calibration with
potentially less precise and less stable in some rare cases.
* Add RELEASE_OBJECT calibration to tutorial code
To select the calibration method of releasing object points, a command
line parameter `-d=<number>` should be provided.
* Update tutorial doc for camera_calibration
If the method of releasing object points is merged into OpenCV. It will
be expected to be firstly released in 4.1, I think.
* Reduce epsilon for cornerSubPix()
Epsilon of 0.1 is a bigger one. Preciser corner positions are required
with calibration method of releasing object.
* Refine camera calibration tutorial
The hypothesis coordinates are used to indicate which distance must be
measured between two specified object points.
* Update sample calibration code method selection
Similar to camera_calibration tutorial application, a command line
argument `-dt=<number>` is used to select the calibration method.
* Add guard to flags of cvCalibrateCamera2()
cvCalibrateCamera2() doesn't accept CALIB_RELEASE_OBJECT unless overload
interface is added in the future.
* Simplify fallback when iFixedPoint is out of range
* Refactor projectPoints() to keep compatibilities
* Fix arg string "Bad rvecs header"
* Read calibration flags from test data files
Instead of being hard coded into source file, the calibration flags will
be read from test data files.
opencv_extra/testdata/cv/cameracalibration/calib?.dat must be sync with
the test code.
* Add new C interface of cvCalibrateCamera4()
With this new added C interface, the extended calibration method with
CALIB_RELEASE_OBJECT can be called by C API.
* Add regression test of extended calibration method
It has been tested with new added test data in xoox:calib-release-object
branch of opencv_extra.
* Fix assertion in test_cameracalibration.cpp
The total number of refined 3D object coordinates is checked.
* Add checker for iFixedPoint in cvCalibrateCamera4
If iFixedPoint is out of rational range, fall back to standard method.
* Fix documentation for overloaded calibrateCamera()
* Remove calibration flag of CALIB_RELEASE_OBJECT
The method selection is based on the range of the index of fixed point.
For minus values, standard calibration method will be chosen. Values in
a rational range will make the object-releasing calibration method
selected.
* Use new interfaces instead of function overload
Existing interfaces are preserved and new interfaces are added. Since
most part of the code base are shared, calibrateCamera() is now a
wrapper function of calibrateCameraRO().
* Fix exported name of calibrateCameraRO()
* Update documentation for calibrateCameraRO()
The circumstances where this method is mostly helpful are described.
* Add note on the rigidity of the calibration target
* Update documentation for calibrateCameraRO()
It is clarified that iFixedPoint is used as a switch to select
calibration method. If input data are not qualified, exceptions will be
thrown instead of fallback scheme.
* Clarify iFixedPoint as switch and remove fallback
iFixedPoint is now used as a switch for calibration method selection. No
fallback scheme is utilized anymore. If the input data are not
qualified, exceptions will be thrown.
* Add badarg test for object-releasing method
* Fix document format of sample list
List items of same level should be indented the same way. Otherwise they
will be formatted as nested lists by Doxygen.
* Add brief intro for objectPoints and imagePoints
* Sync tutorial to sample calibration code
* Update tutorial compatibility version to 4.0
2018-10-26 00:38:55 +08:00
|
|
|
|
2011-02-10 04:55:11 +08:00
|
|
|
if (errors)
|
|
|
|
ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
|
|
|
|
else
|
2012-10-17 15:12:04 +08:00
|
|
|
ts->set_failed_test_info(cvtest::TS::OK);
|
2011-02-10 04:55:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
class CV_Rodrigues2BadArgTest : public cvtest::BadArgTest
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
CV_Rodrigues2BadArgTest() {}
|
|
|
|
~CV_Rodrigues2BadArgTest() {}
|
2012-10-17 15:12:04 +08:00
|
|
|
protected:
|
2014-01-18 05:30:29 +08:00
|
|
|
void run_func(void) {}
|
2011-02-10 04:55:11 +08:00
|
|
|
|
|
|
|
struct C_Caller
|
2012-10-17 15:12:04 +08:00
|
|
|
{
|
2018-11-09 21:12:22 +08:00
|
|
|
_InputArray src_arg;
|
|
|
|
_OutputArray dst_arg, j_arg;
|
|
|
|
|
|
|
|
Mat src;
|
|
|
|
Mat dst;
|
|
|
|
Mat jacobian;
|
|
|
|
|
|
|
|
void initArgs()
|
|
|
|
{
|
|
|
|
src_arg = src;
|
|
|
|
dst_arg = dst;
|
|
|
|
j_arg = jacobian;
|
|
|
|
}
|
2011-02-10 04:55:11 +08:00
|
|
|
|
2018-11-09 21:12:22 +08:00
|
|
|
void operator()()
|
|
|
|
{
|
|
|
|
cv::Rodrigues(src_arg, dst_arg, j_arg);
|
|
|
|
}
|
2011-02-10 04:55:11 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
void run(int /* start_from */ )
|
|
|
|
{
|
2018-11-09 21:12:22 +08:00
|
|
|
Mat src_cpp(3, 1, CV_32F);
|
|
|
|
Mat dst_cpp(3, 3, CV_32F);
|
2011-02-10 04:55:11 +08:00
|
|
|
|
2018-11-09 21:12:22 +08:00
|
|
|
C_Caller caller;
|
2012-10-17 15:12:04 +08:00
|
|
|
|
2011-02-10 04:55:11 +08:00
|
|
|
/*/*//*/*/
|
|
|
|
int errors = 0;
|
|
|
|
|
2018-11-09 21:12:22 +08:00
|
|
|
caller.initArgs();
|
|
|
|
caller.src_arg = noArray();
|
2024-03-05 17:18:31 +08:00
|
|
|
errors += run_test_case( cv::Error::StsBadArg, "Src is empty matrix", caller );
|
2011-02-10 04:55:11 +08:00
|
|
|
|
2018-11-09 21:12:22 +08:00
|
|
|
caller.initArgs();
|
|
|
|
caller.src = Mat::zeros(3, 1, CV_8U);
|
2024-03-05 17:18:31 +08:00
|
|
|
errors += run_test_case( cv::Error::StsUnsupportedFormat, "Bad src formart", caller );
|
2012-10-17 15:12:04 +08:00
|
|
|
|
2018-11-09 21:12:22 +08:00
|
|
|
caller.initArgs();
|
|
|
|
caller.src = Mat::zeros(1, 1, CV_32F);
|
2024-03-05 17:18:31 +08:00
|
|
|
errors += run_test_case( cv::Error::StsBadSize, "Bad src size", caller );
|
2012-10-17 15:12:04 +08:00
|
|
|
|
2011-02-10 04:55:11 +08:00
|
|
|
if (errors)
|
|
|
|
ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
|
|
|
|
else
|
2012-10-17 15:12:04 +08:00
|
|
|
ts->set_failed_test_info(cvtest::TS::OK);
|
2011-02-10 04:55:11 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
|
|
class CV_ProjectPoints2BadArgTest : public cvtest::BadArgTest
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
CV_ProjectPoints2BadArgTest() : camMat(3, 3), distCoeffs(1, 5)
|
2012-10-17 15:12:04 +08:00
|
|
|
{
|
2011-02-10 04:55:11 +08:00
|
|
|
Size imsSize(800, 600);
|
2012-10-17 15:12:04 +08:00
|
|
|
camMat << 300.f, 0.f, imsSize.width/2.f, 0, 300.f, imsSize.height/2.f, 0.f, 0.f, 1.f;
|
2011-02-10 04:55:11 +08:00
|
|
|
distCoeffs << 1.2f, 0.2f, 0.f, 0.f, 0.f;
|
2014-01-18 05:30:29 +08:00
|
|
|
}
|
|
|
|
~CV_ProjectPoints2BadArgTest() {}
|
2012-10-17 15:12:04 +08:00
|
|
|
protected:
|
2014-01-18 05:30:29 +08:00
|
|
|
void run_func(void) {}
|
2011-02-10 04:55:11 +08:00
|
|
|
|
|
|
|
Mat_<float> camMat;
|
|
|
|
Mat_<float> distCoeffs;
|
2012-10-17 15:12:04 +08:00
|
|
|
|
2011-02-10 04:55:11 +08:00
|
|
|
struct C_Caller
|
2012-10-17 15:12:04 +08:00
|
|
|
{
|
2018-11-09 21:12:22 +08:00
|
|
|
_InputArray objectPoints_arg, rvec_arg, tvec_arg, A_arg, DC_arg;
|
|
|
|
_OutputArray imagePoints_arg;
|
|
|
|
Mat objectPoints;
|
|
|
|
Mat r_vec;
|
|
|
|
Mat t_vec;
|
|
|
|
Mat A;
|
|
|
|
Mat distCoeffs;
|
|
|
|
Mat imagePoints;
|
|
|
|
Mat J;
|
|
|
|
double aspectRatio0, aspectRatio;
|
|
|
|
|
|
|
|
void initArgs()
|
|
|
|
{
|
|
|
|
objectPoints_arg = objectPoints;
|
|
|
|
imagePoints_arg = imagePoints;
|
|
|
|
rvec_arg = r_vec;
|
|
|
|
tvec_arg = t_vec;
|
|
|
|
A_arg = A;
|
|
|
|
DC_arg = distCoeffs;
|
|
|
|
aspectRatio = aspectRatio0;
|
|
|
|
}
|
2011-02-10 04:55:11 +08:00
|
|
|
|
2012-10-17 15:12:04 +08:00
|
|
|
void operator()()
|
|
|
|
{
|
2018-11-09 21:12:22 +08:00
|
|
|
projectPoints(objectPoints_arg, rvec_arg, tvec_arg, A_arg, DC_arg,
|
|
|
|
imagePoints_arg, J, aspectRatio );
|
2011-02-10 04:55:11 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
void run(int /* start_from */ )
|
2012-10-17 15:12:04 +08:00
|
|
|
{
|
2018-11-09 21:12:22 +08:00
|
|
|
C_Caller caller;
|
2011-02-10 04:55:11 +08:00
|
|
|
|
|
|
|
const int n = 10;
|
|
|
|
|
|
|
|
Mat objectPoints_cpp(1, n, CV_32FC3);
|
|
|
|
randu(objectPoints_cpp, Scalar::all(1), Scalar::all(10));
|
2018-11-09 21:12:22 +08:00
|
|
|
caller.objectPoints = objectPoints_cpp;
|
|
|
|
caller.t_vec = Mat::zeros(1, 3, CV_32F);
|
2020-12-02 04:42:15 +08:00
|
|
|
Rodrigues(Mat::eye(3, 3, CV_32F), caller.r_vec);
|
2018-11-09 21:12:22 +08:00
|
|
|
caller.A = Mat::eye(3, 3, CV_32F);
|
|
|
|
caller.distCoeffs = Mat::zeros(1, 5, CV_32F);
|
|
|
|
caller.aspectRatio0 = 1.0;
|
2012-10-17 15:12:04 +08:00
|
|
|
|
2011-02-10 04:55:11 +08:00
|
|
|
/********************/
|
|
|
|
int errors = 0;
|
|
|
|
|
2018-11-09 21:12:22 +08:00
|
|
|
caller.initArgs();
|
|
|
|
caller.objectPoints_arg = noArray();
|
2024-03-05 17:18:31 +08:00
|
|
|
errors += run_test_case( cv::Error::StsBadArg, "Zero objectPoints", caller );
|
2012-10-17 15:12:04 +08:00
|
|
|
|
2018-11-09 21:12:22 +08:00
|
|
|
caller.initArgs();
|
|
|
|
caller.rvec_arg = noArray();
|
2024-03-05 17:18:31 +08:00
|
|
|
errors += run_test_case( cv::Error::StsBadArg, "Zero r_vec", caller );
|
2011-02-10 04:55:11 +08:00
|
|
|
|
2018-11-09 21:12:22 +08:00
|
|
|
caller.initArgs();
|
|
|
|
caller.tvec_arg = noArray();
|
2024-03-05 17:18:31 +08:00
|
|
|
errors += run_test_case( cv::Error::StsBadArg, "Zero t_vec", caller );
|
2011-02-10 04:55:11 +08:00
|
|
|
|
2018-11-09 21:12:22 +08:00
|
|
|
caller.initArgs();
|
|
|
|
caller.A_arg = noArray();
|
2024-03-05 17:18:31 +08:00
|
|
|
errors += run_test_case( cv::Error::StsBadArg, "Zero camMat", caller );
|
2011-02-10 04:55:11 +08:00
|
|
|
|
2018-11-09 21:12:22 +08:00
|
|
|
caller.initArgs();
|
|
|
|
caller.imagePoints_arg = noArray();
|
2024-03-05 17:18:31 +08:00
|
|
|
errors += run_test_case( cv::Error::StsBadArg, "Zero imagePoints", caller );
|
2011-02-10 04:55:11 +08:00
|
|
|
|
2018-11-09 21:12:22 +08:00
|
|
|
Mat save_rvec = caller.r_vec;
|
|
|
|
caller.initArgs();
|
|
|
|
caller.r_vec.create(2, 2, CV_32F);
|
2024-03-05 17:18:31 +08:00
|
|
|
errors += run_test_case( cv::Error::StsBadArg, "Bad rvec format", caller );
|
2011-02-10 04:55:11 +08:00
|
|
|
|
2018-11-09 21:12:22 +08:00
|
|
|
caller.initArgs();
|
|
|
|
caller.r_vec.create(1, 3, CV_8U);
|
2024-03-05 17:18:31 +08:00
|
|
|
errors += run_test_case( cv::Error::StsBadArg, "Bad rvec format", caller );
|
2018-11-09 21:12:22 +08:00
|
|
|
caller.r_vec = save_rvec;
|
2012-10-17 15:12:04 +08:00
|
|
|
|
2011-02-10 04:55:11 +08:00
|
|
|
/****************************/
|
2018-11-09 21:12:22 +08:00
|
|
|
Mat save_tvec = caller.t_vec;
|
|
|
|
caller.initArgs();
|
|
|
|
caller.t_vec.create(3, 3, CV_32F);
|
2024-03-05 17:18:31 +08:00
|
|
|
errors += run_test_case( cv::Error::StsBadArg, "Bad tvec format", caller );
|
2011-02-10 04:55:11 +08:00
|
|
|
|
2018-11-09 21:12:22 +08:00
|
|
|
caller.initArgs();
|
|
|
|
caller.t_vec.create(1, 3, CV_8U);
|
2024-03-05 17:18:31 +08:00
|
|
|
errors += run_test_case( cv::Error::StsBadArg, "Bad tvec format", caller );
|
2018-11-09 21:12:22 +08:00
|
|
|
caller.t_vec = save_tvec;
|
2012-10-17 15:12:04 +08:00
|
|
|
|
2011-02-10 04:55:11 +08:00
|
|
|
/****************************/
|
2018-11-09 21:12:22 +08:00
|
|
|
Mat save_A = caller.A;
|
|
|
|
caller.initArgs();
|
|
|
|
caller.A.create(2, 2, CV_32F);
|
2024-03-05 17:18:31 +08:00
|
|
|
errors += run_test_case( cv::Error::StsBadArg, "Bad A format", caller );
|
2018-11-09 21:12:22 +08:00
|
|
|
caller.A = save_A;
|
2011-02-10 04:55:11 +08:00
|
|
|
|
|
|
|
/****************************/
|
2018-11-09 21:12:22 +08:00
|
|
|
Mat save_DC = caller.distCoeffs;
|
|
|
|
caller.initArgs();
|
|
|
|
caller.distCoeffs.create(3, 3, CV_32F);
|
2024-03-05 17:18:31 +08:00
|
|
|
errors += run_test_case( cv::Error::StsBadArg, "Bad distCoeffs format", caller );
|
2018-11-09 21:12:22 +08:00
|
|
|
caller.distCoeffs = save_DC;
|
2012-10-17 15:12:04 +08:00
|
|
|
|
2011-02-10 04:55:11 +08:00
|
|
|
if (errors)
|
|
|
|
ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
|
|
|
|
else
|
2012-10-17 15:12:04 +08:00
|
|
|
ts->set_failed_test_info(cvtest::TS::OK);
|
2011-02-10 04:55:11 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2018-11-09 21:12:22 +08:00
|
|
|
TEST(Calib3d_CalibrateCamera_CPP, badarg) { CV_CameraCalibrationBadArgTest test; test.safe_run(); }
|
|
|
|
TEST(Calib3d_Rodrigues_CPP, badarg) { CV_Rodrigues2BadArgTest test; test.safe_run(); }
|
|
|
|
TEST(Calib3d_ProjectPoints_CPP, badarg) { CV_ProjectPoints2BadArgTest test; test.safe_run(); }
|
2017-11-05 21:48:40 +08:00
|
|
|
|
|
|
|
}} // namespace
|