1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-21 19:33:03 +04:00

Merge pull request #27791 from asmorkalov:as/multiview_term_criteria

Add term criteria to multivew calibration
This commit is contained in:
Alexander Smorkalov
2025-09-17 18:55:07 +03:00
committed by GitHub
3 changed files with 31 additions and 21 deletions
+5 -2
View File
@@ -1341,6 +1341,7 @@ See @ref CALIB_USE_INTRINSIC_GUESS and other `CALIB_` constants. Expected shape:
@param[out] distortions Distortion coefficients. Output size: NUM_CAMERAS x NUM_PARAMS.
@param[out] perFrameErrors RMSE value for each visible frame, (-1 for non-visible). Output size: NUM_CAMERAS x NUM_FRAMES.
@param[out] initializationPairs Pairs with camera indices that were used for initial pairwise stereo calibration.
@param[in] criteria Termination criteria for the iterative optimization algorithm.
Output size: (NUM_CAMERAS-1) x 2.
@@ -1382,7 +1383,8 @@ CV_EXPORTS_AS(calibrateMultiviewExtended) double calibrateMultiview (
InputOutputArrayOfArrays Rs, InputOutputArrayOfArrays Ts,
OutputArray initializationPairs, OutputArrayOfArrays rvecs0,
OutputArrayOfArrays tvecs0, OutputArray perFrameErrors,
InputArray flagsForIntrinsics=noArray(), int flags = 0);
InputArray flagsForIntrinsics=noArray(), int flags = 0,
TermCriteria criteria = TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 100, DBL_EPSILON));
/// @overload
CV_EXPORTS_W double calibrateMultiview (
@@ -1390,7 +1392,8 @@ CV_EXPORTS_W double calibrateMultiview (
const std::vector<cv::Size>& imageSize, InputArray detectionMask, InputArray models,
InputOutputArrayOfArrays Ks, InputOutputArrayOfArrays distortions,
InputOutputArrayOfArrays Rs, InputOutputArrayOfArrays Ts,
InputArray flagsForIntrinsics=noArray(), int flags = 0);
InputArray flagsForIntrinsics=noArray(), int flags = 0,
TermCriteria criteria = TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 100, DBL_EPSILON));
/** @brief Computes Hand-Eye calibration: \f$_{}^{g}\textrm{T}_c\f$
+14 -12
View File
@@ -265,7 +265,7 @@ static void pairwiseRegistration (const std::vector<std::pair<int,int>> &pairs,
const std::vector<std::vector<Mat>> &imagePoints, const std::vector<std::vector<int>> &overlaps,
const std::vector<std::vector<bool>> &detection_mask_mat, const std::vector<Mat> &Ks,
const std::vector<Mat> &distortions, std::vector<Matx33d> &Rs_vec, std::vector<Vec3d> &Ts_vec,
Mat &intrinsic_flags, int extrinsic_flags = 0) {
Mat &intrinsic_flags, int extrinsic_flags, TermCriteria criteria) {
CV_UNUSED(intrinsic_flags);
const int NUM_FRAMES = (int)objPoints_norm.size();
const int NUM_CAMERAS = (int)detection_mask_mat.size();
@@ -308,7 +308,8 @@ static void pairwiseRegistration (const std::vector<std::pair<int,int>> &pairs,
registerCameras(grid_points1, grid_points2, image_points1, image_points2,
Ks[c1], distortions[c1], cv::CameraModel(models.at<uchar>(c1)),
Ks[c2], distortions[c2], cv::CameraModel(models.at<uchar>(c2)),
R, T, noArray(), noArray(), noArray(), noArray(), noArray(), extrinsic_flags);
R, T, noArray(), noArray(), noArray(), noArray(), noArray(),
extrinsic_flags, criteria);
// R_0 = I
// R_ij = R_i R_j^T => R_i = R_ij R_j
@@ -328,7 +329,7 @@ static void pairwiseStereoCalibration (const std::vector<std::pair<int,int>> &pa
const std::vector<std::vector<Mat>> &imagePoints, const std::vector<std::vector<int>> &overlaps,
const std::vector<std::vector<bool>> &detection_mask_mat, const std::vector<Mat> &Ks,
const std::vector<Mat> &distortions, std::vector<Matx33d> &Rs_vec, std::vector<Vec3d> &Ts_vec,
Mat &intrinsic_flags, int extrinsic_flags = 0) {
Mat &intrinsic_flags, int extrinsic_flags, TermCriteria criteria) {
const int NUM_FRAMES = (int)objPoints_norm.size();
const int NUM_CAMERAS = (int)detection_mask_mat.size();
std::vector<Matx33d> Rs_prior;
@@ -375,7 +376,8 @@ static void pairwiseStereoCalibration (const std::vector<std::pair<int,int>> &pa
fisheye::stereoCalibrate(grid_points, image_points1, image_points2,
Ks[c1], distortions[c1],
Ks[c2], distortions[c2],
Size(), R, T, extrinsic_flags);
Size(), R, T,
extrinsic_flags, criteria);
} else {
extrinsic_flags |= CALIB_FIX_INTRINSIC;
if ((intrinsic_flags.at<int>(c1) & CALIB_RATIONAL_MODEL) || (intrinsic_flags.at<int>(c2) & CALIB_RATIONAL_MODEL))
@@ -386,7 +388,8 @@ static void pairwiseStereoCalibration (const std::vector<std::pair<int,int>> &pa
stereoCalibrate(grid_points, image_points1, image_points2,
Ks[c1], distortions[c1],
Ks[c2], distortions[c2],
Size(), R, T, noArray(), noArray(), noArray(), extrinsic_flags);
Size(), R, T, noArray(), noArray(), noArray(),
extrinsic_flags, criteria);
}
// R_0 = I
@@ -576,7 +579,7 @@ double calibrateMultiview(
InputOutputArrayOfArrays Rs, InputOutputArrayOfArrays Ts,
OutputArray initializationPairs, OutputArrayOfArrays rvecs0,
OutputArrayOfArrays tvecs0, OutputArray perFrameErrors,
InputArray flagsForIntrinsics, int flags) {
InputArray flagsForIntrinsics, int flags, TermCriteria criteria) {
CV_CheckFalse(objPoints.empty(), "Objects points must not be empty!");
CV_CheckFalse(imagePoints.empty(), "Image points must not be empty!");
CV_CheckFalse(imageSize.empty(), "Image size per camera must not be empty!");
@@ -801,10 +804,10 @@ double calibrateMultiview(
if(flags & cv::CALIB_STEREO_REGISTRATION) {
multiview::pairwiseStereoCalibration(pairs, models_mat, objPoints_norm, imagePoints,
overlaps, detection_mask_mat, Ks_vec, distortions_vec, Rs_vec, Ts_vec, flagsForIntrinsics_mat);
overlaps, detection_mask_mat, Ks_vec, distortions_vec, Rs_vec, Ts_vec, flagsForIntrinsics_mat, 0, criteria);
} else {
multiview::pairwiseRegistration(pairs, models_mat, objPoints_norm, imagePoints,
overlaps, detection_mask_mat, Ks_vec, distortions_vec, Rs_vec, Ts_vec, flagsForIntrinsics_mat);
overlaps, detection_mask_mat, Ks_vec, distortions_vec, Rs_vec, Ts_vec, flagsForIntrinsics_mat, 0, criteria);
}
const int NUM_VALID_FRAMES = countNonZero(valid_frames);
@@ -853,10 +856,9 @@ double calibrateMultiview(
cnt_valid_frame++;
}
TermCriteria termCrit (TermCriteria::COUNT+TermCriteria::EPS, 100, 1e-6);
const float RBS_FNC_SCALE = 30;
multiview::RobustExpFunction robust_fnc(RBS_FNC_SCALE);
multiview::optimizeLM(param, robust_fnc, termCrit, valid_frames, detection_mask_mat, objPoints_norm,
multiview::optimizeLM(param, robust_fnc, criteria, valid_frames, detection_mask_mat, objPoints_norm,
imagePoints, Ks_vec, distortions_vec, models_mat, NUM_PATTERN_PTS);
const auto * const params = &param[0];
@@ -967,10 +969,10 @@ double calibrateMultiview(
const std::vector<cv::Size>& imageSize, InputArray detectionMask, InputArray models,
InputOutputArrayOfArrays Ks, InputOutputArrayOfArrays distortions,
InputOutputArrayOfArrays Rs, InputOutputArrayOfArrays Ts,
InputArray flagsForIntrinsics, int flags) {
InputArray flagsForIntrinsics, int flags, TermCriteria criteria) {
return calibrateMultiview(objPoints, imagePoints, imageSize, detectionMask, models, Ks, distortions,
Rs, Ts, noArray(), noArray(), noArray(), noArray(), flagsForIntrinsics, flags);
Rs, Ts, noArray(), noArray(), noArray(), noArray(), flagsForIntrinsics, flags, criteria);
}
+12 -7
View File
@@ -302,7 +302,8 @@ TEST_F(MultiViewTest, OneLine)
std::vector<std::vector<cv::Mat>> image_points_all;
cv::Mat visibility;
loadImagePoints(root, cam_names, num_frames, image_points_all, visibility);
EXPECT_EQ(cam_names.size(), image_points_all.size());
ASSERT_EQ(cam_names.size(), image_points_all.size());
ASSERT_TRUE(!image_points_all.empty());
for(size_t i = 0; i < cam_names.size(); i++)
{
EXPECT_TRUE(!image_points_all[i].empty());
@@ -475,7 +476,8 @@ TEST_F(MultiViewTest, CamsToFloor)
std::vector<std::vector<cv::Mat>> image_points_all;
cv::Mat visibility;
loadImagePoints(root, cam_names, num_frames, image_points_all, visibility);
EXPECT_EQ(cam_names.size(), image_points_all.size());
ASSERT_EQ(cam_names.size(), image_points_all.size());
ASSERT_TRUE(!image_points_all.empty());
for(size_t i = 0; i < cam_names.size(); i++)
{
EXPECT_TRUE(!image_points_all[i].empty());
@@ -542,7 +544,8 @@ TEST_F(MultiViewTest, Hetero)
std::vector<std::vector<cv::Mat>> image_points_all;
cv::Mat visibility;
loadImagePoints(root, cam_names, num_frames, image_points_all, visibility);
EXPECT_EQ(cam_names.size(), image_points_all.size());
ASSERT_EQ(cam_names.size(), image_points_all.size());
ASSERT_TRUE(!image_points_all.empty());
for(size_t i = 0; i < cam_names.size(); i++)
{
EXPECT_TRUE(!image_points_all[i].empty());
@@ -613,10 +616,11 @@ TEST_F(RegisterCamerasTest, hetero1)
std::vector<std::vector<cv::Mat>> image_points_all;
cv::Mat visibility;
loadImagePoints(root, cam_names, num_frames, image_points_all, visibility);
EXPECT_EQ(cam_names.size(), image_points_all.size());
ASSERT_EQ(cam_names.size(), image_points_all.size());
ASSERT_TRUE(!image_points_all.empty());
for(size_t i = 0; i < cam_names.size(); i++)
{
EXPECT_TRUE(!image_points_all[i].empty());
ASSERT_TRUE(!image_points_all[i].empty());
}
cv::Mat K1, dist1;
@@ -670,10 +674,11 @@ TEST_F(RegisterCamerasTest, hetero2)
std::vector<std::vector<cv::Mat>> image_points_all;
cv::Mat visibility;
loadImagePoints(root, cam_names, num_frames, image_points_all, visibility);
EXPECT_EQ(cam_names.size(), image_points_all.size());
ASSERT_EQ(cam_names.size(), image_points_all.size());
ASSERT_TRUE(!image_points_all.empty());
for(size_t i = 0; i < cam_names.size(); i++)
{
EXPECT_TRUE(!image_points_all[i].empty());
ASSERT_TRUE(!image_points_all[i].empty());
}
cv::Mat K1, dist1;