@@ -816,6 +816,177 @@ void CV_CameraCalibrationTest_CPP::project( const std::vector<Point3d>& objectPo
816816 }*/
817817}
818818
819+ // --------------------------------- CV_CameraCalibrationFixedExtrinsicsTest_CPP --------------------------------------------
820+
821+ class CV_CameraCalibrationFixedExtrinsicsTest_CPP :public CV_CameraCalibrationTest
822+ {
823+ public:
824+ CV_CameraCalibrationFixedExtrinsicsTest_CPP (const bool _useRodrigues=false );
825+ protected:
826+ virtual void calibrate (const FixtureParams &fp, CalibratedParams &cp );
827+
828+ virtual int checkCalibration (const FixtureParams &fp, CalibratedParams &cp );
829+
830+ /* Whether rotation matrices should be passed in as Rodrigues vectors*/
831+ const bool useRodrigues;
832+ };
833+
834+ CV_CameraCalibrationFixedExtrinsicsTest_CPP::CV_CameraCalibrationFixedExtrinsicsTest_CPP (const bool _useRodrigues )
835+ : useRodrigues( _useRodrigues )
836+ {
837+ }
838+
839+ void CV_CameraCalibrationFixedExtrinsicsTest_CPP::calibrate (const FixtureParams &fp, CalibratedParams &cp )
840+ {
841+ vector<vector<Point3f> >objectPoints ( fp.numImages );
842+ vector<vector<Point2f> >imagePoints ( fp.numImages );
843+ std::vector<Mat> rvecs, tvecs;
844+ Mat newObjMat;
845+ Mat stdDevsMatInt, stdDevsMatExt;
846+ Mat stdDevsMatObj;
847+
848+ for (int i =0 ; i < fp.numImages ; i++ )
849+ {
850+ Mat ( fp.imagePoints [i]).convertTo (imagePoints[i], CV_32F );
851+ Mat ( fp.objectPoints [i]).convertTo (objectPoints[i], CV_32F );
852+ }
853+
854+ CV_Assert ( (size_t )fp.numImages == fp.goodRotMatrs .size () );
855+ CV_Assert ( (size_t )fp.numImages == fp.goodTransVects .size () );
856+
857+ for (int i =0 ; i < fp.numImages ; i++ )
858+ {
859+ Mat rMat =Mat ( fp.goodRotMatrs [i] );
860+
861+ if ( useRodrigues )
862+ {
863+ rvecs.emplace_back ();
864+ cvtest::Rodrigues ( rMat.t (), rvecs.back () );
865+ }
866+ else
867+ {
868+ rvecs.emplace_back ( rMat.t () );
869+ }
870+
871+ tvecs.emplace_back (Mat ( fp.goodTransVects [i] ) );
872+ }
873+
874+ calibrateCameraRO ( objectPoints,
875+ imagePoints,
876+ fp.imageSize ,
877+ fp.iFixedPoint ,
878+ cp.cameraMatrix ,
879+ cp.distortion ,
880+ rvecs,
881+ tvecs,
882+ newObjMat,
883+ stdDevsMatInt,
884+ stdDevsMatExt,
885+ stdDevsMatObj,
886+ cp.perViewErrors ,
887+ fp.flags | CALIB_FIX_EXTRINSIC );
888+
889+ for (int i =0 ; i < fp.numImages ; i++ )
890+ {
891+ if ( useRodrigues )
892+ {
893+ Mat rMat;
894+ cvtest::Rodrigues ( rvecs[i], rMat );
895+ cv::transpose ( rMat, rMat );
896+ cp.rotMatrs .emplace_back ();
897+ rMat.convertTo ( cp.rotMatrs [i], CV_64F );
898+ }
899+ else
900+ {
901+ RotMat rMat =Mat ( rvecs[i].t () );
902+ cp.rotMatrs .emplace_back ( rMat );
903+ }
904+
905+ cp.transVects .emplace_back ( tvecs[i] );
906+ }
907+ }
908+
909+ int CV_CameraCalibrationFixedExtrinsicsTest_CPP::checkCalibration (const FixtureParams &fp, CalibratedParams &cp)
910+ {
911+ int code = cvtest::TS::OK;
912+
913+ /* ========= Compare parameters =========*/
914+ CV_Assert (cp.cameraMatrix .type () == CV_64F && cp.cameraMatrix .size () ==Size (3 ,3 ));
915+ CV_Assert (cp.distortion .type () == CV_64F);
916+
917+ Size dsz = cp.distortion .size ();
918+ CV_Assert (dsz ==Size (4 ,1 ) || dsz ==Size (1 ,4 ) || dsz ==Size (5 ,1 ) || dsz ==Size (1 ,5 ));
919+
920+ /* ----- Compare focal lengths -----*/
921+ code =compare (&cp.cameraMatrix .at <double >(0 ,0 ), &fp.goodFcx ,1 ,0.1 ," fx" );
922+ if ( code <0 )
923+ return code;
924+
925+ code =compare (&cp.cameraMatrix .at <double >(1 ,1 ), &fp.goodFcy ,1 ,0.1 ," fy" );
926+ if ( code <0 )
927+ return code;
928+
929+ /* ----- Compare principal points -----*/
930+ code =compare (&cp.cameraMatrix .at <double >(0 ,2 ), &fp.goodCx ,1 ,0.1 ," cx" );
931+ if ( code <0 )
932+ return code;
933+
934+ code =compare (&cp.cameraMatrix .at <double >(1 ,2 ), &fp.goodCy ,1 ,0.1 ," cy" );
935+ if ( code <0 )
936+ return code;
937+
938+ /* ----- Compare distortion -----*/
939+ code =compare (&cp.distortion .at <double >(0 ), &fp.goodDistortion .at <double >(0 ),4 ,0.1 ," [k1,k2,p1,p2]" );
940+ if ( code <0 )
941+ return code;
942+
943+ /* ----- Check extrinsics are the same -----*/
944+ CV_Assert (cp.rotMatrs .size () == (size_t )fp.numImages );
945+ CV_Assert (cp.transVects .size () == (size_t )fp.numImages );
946+
947+ for (int i =0 ; i < fp.numImages ; i++ )
948+ {
949+ RotMat goodRotMat;
950+
951+ if ( useRodrigues )
952+ {
953+ Mat rMat =Mat ( fp.goodRotMatrs [i] );
954+ Mat rvec;
955+ cvtest::Rodrigues ( rMat.t (), rvec );
956+ cvtest::Rodrigues ( rvec, rMat );
957+ cv::transpose ( rMat, rMat );
958+ rMat.convertTo ( goodRotMat, CV_64F );
959+ }
960+ else
961+ {
962+ goodRotMat = fp.goodRotMatrs [i];
963+ }
964+
965+ if ( cp.rotMatrs [i] != goodRotMat )
966+ {
967+ printf (" rot mats for frame #%d are different\n " , i);
968+ std::cout <<" curr:\n " << cp.rotMatrs [i] << std::endl;
969+ std::cout <<" good:\n " << goodRotMat << std::endl;
970+
971+ code = TS::FAIL_BAD_ACCURACY;
972+ break ;
973+ }
974+
975+ if ( cp.transVects [i] != fp.goodTransVects [i] )
976+ {
977+ printf (" rot mats for frame #%d are different\n " , i);
978+ std::cout <<" curr:\n " << cp.transVects [i] << std::endl;
979+ std::cout <<" good:\n " << fp.goodTransVects [i] << std::endl;
980+
981+ code = TS::FAIL_BAD_ACCURACY;
982+ break ;
983+ }
984+ }
985+ if ( code <0 )
986+ return code;
987+
988+ return code;
989+ }
819990
820991// ----------------------------------------- CV_CalibrationMatrixValuesTest --------------------------------
821992
@@ -1697,6 +1868,9 @@ void CV_StereoCalibrationTest_CPP::correct( const Mat& F,
16971868// /////////////////////////////////////////////////////////////////////////////////////////////////
16981869
16991870TEST (Calib3d_CalibrateCamera_CPP, regression) { CV_CameraCalibrationTest_CPP test; test.safe_run (); }
1871+ TEST (Calib3d_CalibrateCamera_CPP, fixedExtrinsics) { CV_CameraCalibrationFixedExtrinsicsTest_CPP test; test.safe_run (); }
1872+ TEST (Calib3d_CalibrateCamera_CPP, fixedExtrinsicsRodrigues) {
1873+ CV_CameraCalibrationFixedExtrinsicsTest_CPP test{true /* useRodrigues*/ }; test.safe_run (); }
17001874TEST (Calib3d_CalibrationMatrixValues_CPP, accuracy) { CV_CalibrationMatrixValuesTest_CPP test; test.safe_run (); }
17011875TEST (Calib3d_ProjectPoints_CPP, regression) { CV_ProjectPointsTest_CPP test; test.safe_run (); }
17021876