From dd5dd9f5dc69898f6271155ee48e4639e6d1172b Mon Sep 17 00:00:00 2001 From: Alex Bailo Date: Mon, 1 Jul 2024 22:48:41 +0200 Subject: [PATCH 1/3] Extract filename with boost --- McCalib/src/McCalib.cpp | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/McCalib/src/McCalib.cpp b/McCalib/src/McCalib.cpp index 8d0f3ad1..dce3fa2b 100644 --- a/McCalib/src/McCalib.cpp +++ b/McCalib/src/McCalib.cpp @@ -1885,11 +1885,11 @@ void Calibration::refineAllCameraGroupAndObjects() { */ void Calibration::saveReprojectionImages(const int cam_id) { // Prepare the path to save the images - std::string path_root = save_path_ + "Reprojection/"; + const std::string path_root = save_path_ + "Reprojection/"; std::stringstream ss; ss << std::setw(3) << std::setfill('0') << cam_id; - std::string cam_folder = ss.str(); - std::string path_save = path_root + cam_folder + "/"; + const std::string cam_folder = ss.str(); + const std::string path_save = path_root + cam_folder + "/"; // check if the file exist and create it if it does not if (!boost::filesystem::exists(path_root) && path_root.length() > 0) { @@ -1904,7 +1904,7 @@ void Calibration::saveReprojectionImages(const int cam_id) { // Iterate through the frames where this camera has visibility for (const auto &it_frame : frames_) { // Open the image - std::string im_path = it_frame.second->frame_path_[cam_id]; + const std::string im_path = it_frame.second->frame_path_[cam_id]; cv::Mat image = cv::imread(im_path); // Iterate through the camera group observations @@ -1974,10 +1974,9 @@ void Calibration::saveReprojectionImages(const int cam_id) { // cv::waitKey(1); // Save image - std::stringstream ss1; - ss1 << std::setw(6) << std::setfill('0') << it_frame.second->frame_idx_; - std::string image_name = ss1.str() + ".jpg"; - cv::imwrite(path_save + image_name, image); + const boost::filesystem::path im_path_boost(im_path); + const std::string filename = im_path_boost.filename().string(); + cv::imwrite(path_save + filename, image); } } } @@ -1997,11 +1996,11 @@ void Calibration::saveReprojectionImagesAllCam() { */ void Calibration::saveDetectionImages(const int cam_id) { // Prepare the path to save the images - std::string path_root = save_path_ + "Detection/"; + const std::string path_root = save_path_ + "Detection/"; std::stringstream ss; ss << std::setw(3) << std::setfill('0') << cam_id; - std::string cam_folder = ss.str(); - std::string path_save = path_root + cam_folder + "/"; + const std::string cam_folder = ss.str(); + const std::string path_save = path_root + cam_folder + "/"; // check if the file exist and create it if it does not if (!boost::filesystem::exists(path_root) && path_root.length() > 0) { @@ -2053,10 +2052,9 @@ void Calibration::saveDetectionImages(const int cam_id) { // cv::waitKey(1); // Save image - std::stringstream ss1; - ss1 << std::setw(6) << std::setfill('0') << it_frame.second->frame_idx_; - std::string image_name = ss1.str() + ".jpg"; - cv::imwrite(path_save + image_name, image); + const boost::filesystem::path im_path_boost(im_path); + const std::string filename = im_path_boost.filename().string(); + cv::imwrite(path_save + filename, image); } } } From c007810036cd7d0769156570f0be95f25cf44471 Mon Sep 17 00:00:00 2001 From: Alex Bailo Date: Sun, 25 Aug 2024 11:47:29 +0200 Subject: [PATCH 2/3] Writing image names instead of idx --- McCalib/src/McCalib.cpp | 26 +++++++++++++++++++++---- python_utils/compute_error_statistic.py | 14 +++++++++---- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/McCalib/src/McCalib.cpp b/McCalib/src/McCalib.cpp index dce3fa2b..a01c00a9 100644 --- a/McCalib/src/McCalib.cpp +++ b/McCalib/src/McCalib.cpp @@ -2015,7 +2015,7 @@ void Calibration::saveDetectionImages(const int cam_id) { // Iterate through the frames where this camera has visibility for (const auto &it_frame : frames_) { // Open the image - std::string im_path = it_frame.second->frame_path_[cam_id]; + const std::string im_path = it_frame.second->frame_path_[cam_id]; cv::Mat image = cv::imread(im_path); // Iterate through the camera group observations @@ -2243,7 +2243,8 @@ void Calibration::saveReprojectionErrorToFile() { std::string save_reprojection_error = save_path_ + "reprojection_error_data.yml"; cv::FileStorage fs(save_reprojection_error, cv::FileStorage::WRITE); - cv::Mat frame_list; + // cv::Mat frame_list; + std::vector frame_list; int nb_cam_group = cam_group_.size(); fs << "nb_camera_group" << nb_cam_group; @@ -2257,9 +2258,26 @@ void Calibration::saveReprojectionErrorToFile() { std::shared_ptr it_frame_ptr = it_frame.second.lock(); if (it_frame_ptr) { cv::Mat camera_list; - fs << "frame_" + std::to_string(it_frame_ptr->frame_idx_); + // std::cout << "frame_path_.size() == " << it_frame_ptr->frame_path_.size() << std::endl; + // for (const auto frame_path_it : it_frame_ptr->frame_path_) + // { + // std::cout << "frame_path: " << frame_path_it.second << std::endl; + // const boost::filesystem::path im_path_boost(frame_path_it.second); + // const std::string filename = im_path_boost.stem().string(); + // std::cout << "filename: " << filename << std::endl; + // } + // assert(it_frame_ptr->frame_path_.size() == 1u); + + const std::string frame_path = it_frame_ptr->frame_path_.begin()->second; + const boost::filesystem::path frame_path_boost(frame_path); + const std::string frame_name = frame_path_boost.stem().string(); + fs << "frame_" + frame_name; + + // fs << "frame_" + std::to_string(it_frame_ptr->frame_idx_); fs << "{"; - frame_list.push_back(it_frame_ptr->frame_idx_); + frame_list.push_back(frame_name); + + // frame_list.push_back(it_frame_ptr->frame_idx_); // iterate through cameraGroupObs std::map> current_cam_group_obs_vec = diff --git a/python_utils/compute_error_statistic.py b/python_utils/compute_error_statistic.py index 8f4dfb45..ab88798c 100755 --- a/python_utils/compute_error_statistic.py +++ b/python_utils/compute_error_statistic.py @@ -45,12 +45,17 @@ def compute_error_statistic(reprojection_error_data_path: Path) -> None: verify_num_camera_groups(fs) camera_group_id = "camera_group_" + str(0) - frame_list = fs.getNode(camera_group_id).getNode("frame_list").mat() + # frame_list = fs.getNode(camera_group_id).getNode("frame_list").mat() + # frame_list = fs.getNode(camera_group_id).getNode("frame_list") + frame_list_node = fs.getNode(camera_group_id).getNode("frame_list") + frame_list: List[str] = [] + for frame_idx in range(frame_list_node.size()): + frame_list.append(frame_list_node.at(frame_idx).string()) list_mean_error: List[float] = [] list_color = [] list_mean_error_frame: List[float] = [] - for i in range(frame_list.shape[0]): - frame_id = "frame_" + str(frame_list[i][0]) + for frame_name in frame_list: + frame_id = f"frame_{frame_name}" camera_list = fs.getNode(camera_group_id).getNode(frame_id).getNode("camera_list").mat() errors_current_frame = [] @@ -73,7 +78,8 @@ def compute_error_statistic(reprojection_error_data_path: Path) -> None: for _ in range(5): list_mean_error.append(0.0) list_color.append(camera_color[camera_list[0][0]]) - + import pdb + pdb.set_trace() visualize_and_save_results(list_mean_error_frame, reprojection_error_data_path.parent) From 4bab45f93977da561a9695fdb66a1c0614bd86ce Mon Sep 17 00:00:00 2001 From: Alex Bailo Date: Mon, 26 Aug 2024 21:32:25 +0200 Subject: [PATCH 3/3] WIP --- python_utils/compute_error_statistic.py | 9 ++ tests/test_calibration.cpp | 116 ++++++++++++++---------- 2 files changed, 75 insertions(+), 50 deletions(-) diff --git a/python_utils/compute_error_statistic.py b/python_utils/compute_error_statistic.py index ab88798c..423d4447 100755 --- a/python_utils/compute_error_statistic.py +++ b/python_utils/compute_error_statistic.py @@ -47,6 +47,15 @@ def compute_error_statistic(reprojection_error_data_path: Path) -> None: camera_group_id = "camera_group_" + str(0) # frame_list = fs.getNode(camera_group_id).getNode("frame_list").mat() # frame_list = fs.getNode(camera_group_id).getNode("frame_list") + + # frame_list[np.argmax(list_mean_error_frame)] + # frame_list[np.argmax(list_mean_error_frame.remove(np.max(list_mean_error_frame)))] + + # frame_list[list_mean_error_frame.index(sorted(list_mean_error_frame)[-1])] + # frame_list[list_mean_error_frame.index(sorted(list_mean_error_frame)[-2])] + # frame_list[list_mean_error_frame.index(sorted(list_mean_error_frame)[-3])] + # frame_list[list_mean_error_frame.index(sorted(list_mean_error_frame)[-4])] + frame_list_node = fs.getNode(camera_group_id).getNode("frame_list") frame_list: List[str] = [] for frame_idx in range(frame_list_node.size()): diff --git a/tests/test_calibration.cpp b/tests/test_calibration.cpp index 9b1ba430..b448e096 100644 --- a/tests/test_calibration.cpp +++ b/tests/test_calibration.cpp @@ -80,7 +80,7 @@ void calibrateAndCheckGt(std::string config_path, std::string gt_path) { camera_pose_matrix_gt = transform * camera_pose_matrix_gt * transform; double fx_gt = camera_matrix_gt.at(0, 0); - double fy_gt = camera_matrix_gt.at(1, 0); + double fy_gt = camera_matrix_gt.at(1, 1); double cx_gt = camera_matrix_gt.at(0, 2); double cy_gt = camera_matrix_gt.at(1, 2); cv::Mat rot_gt(3, 3, CV_64F); @@ -96,7 +96,7 @@ void calibrateAndCheckGt(std::string config_path, std::string gt_path) { Calib.cam_group_[camera_group_idx]->getCameraPoseMat(camera_idx - 1); double fx_pred = camera_matrix_pred.at(0, 0); - double fy_pred = camera_matrix_pred.at(1, 0); + double fy_pred = camera_matrix_pred.at(1, 1); double cx_pred = camera_matrix_pred.at(0, 2); double cy_pred = camera_matrix_pred.at(1, 2); cv::Mat rot_pred(3, 3, CV_64F); @@ -107,25 +107,77 @@ void calibrateAndCheckGt(std::string config_path, std::string gt_path) { double tran_error = getTranslationError(tran_pred, tran_gt); double rot_error = getRotationError(rot_pred, rot_gt); + std::cout << "camera_idx: " << camera_idx << std::endl; + std::cout << "fx_diff: " << std::abs(fx_pred - fx_gt) << std::endl; + // std::cout << "fy_pred: " << fy_pred << "; fy_gt: " << fy_gt << std::endl; + std::cout << "fy_diff: " << std::abs(fy_pred - fy_gt) << std::endl; + std::cout << "cx_diff: " << std::abs(cx_pred - cx_gt) << std::endl; + std::cout << "cy_diff: " << std::abs(cy_pred - cy_gt) << std::endl; + std::cout << "tran_error: " << tran_error << std::endl; + std::cout << "rot_error: " << rot_error << std::endl; + std::cout << std::endl; + + // TODO: + // 1. remove one image with the worst mean reprojection error and see how that affects the calibration + // 2. repeat the experiment with by removing more images + // 3. if that works, share the results with Francois + // 4. discuss and decide how to implement it + // perform verifications - BOOST_CHECK_CLOSE(fx_pred, fx_gt, INTRINSICS_TOLERANCE); - BOOST_CHECK_CLOSE(fy_pred, fy_gt, INTRINSICS_TOLERANCE); - BOOST_CHECK_CLOSE(cx_pred, cx_gt, INTRINSICS_TOLERANCE); - BOOST_CHECK_CLOSE(cy_pred, cy_gt, INTRINSICS_TOLERANCE); - BOOST_CHECK_SMALL(tran_error, TRANSLATION_ERROR_TOLERANCE); - BOOST_CHECK_SMALL(rot_error, ROTATION_ERROR_TOLERANCE); + // BOOST_CHECK_CLOSE(fx_pred, fx_gt, INTRINSICS_TOLERANCE); + // BOOST_CHECK_CLOSE(fy_pred, fy_gt, INTRINSICS_TOLERANCE); + // BOOST_CHECK_CLOSE(cx_pred, cx_gt, INTRINSICS_TOLERANCE); + // BOOST_CHECK_CLOSE(cy_pred, cy_gt, INTRINSICS_TOLERANCE); + // BOOST_CHECK_SMALL(tran_error, TRANSLATION_ERROR_TOLERANCE); + // BOOST_CHECK_SMALL(rot_error, ROTATION_ERROR_TOLERANCE); } } BOOST_AUTO_TEST_SUITE(CheckCalibration) -BOOST_AUTO_TEST_CASE(CheckBlenderDatasetIsPlacedCorrectly) { - std::string blender_images_path = "../data/Blender_Images"; - bool is_path_existent = boost::filesystem::exists(blender_images_path); - BOOST_REQUIRE_EQUAL(is_path_existent, true); -} +// BOOST_AUTO_TEST_CASE(CheckBlenderDatasetIsPlacedCorrectly) { +// std::string blender_images_path = "../data/Blender_Images"; +// bool is_path_existent = boost::filesystem::exists(blender_images_path); +// BOOST_REQUIRE_EQUAL(is_path_existent, true); +// } + +// BOOST_AUTO_TEST_CASE(CheckCalibrationSyntheticScenario1) { +// std::string config_path = +// "../tests/configs_for_end2end_tests/calib_param_synth_Scenario1.yml"; +// std::string gt_path = "../data/Blender_Images/Scenario_1/GroundTruth.yml"; +// BOOST_REQUIRE_EQUAL(boost::filesystem::exists(config_path), true); +// BOOST_REQUIRE_EQUAL(boost::filesystem::exists(gt_path), true); +// calibrateAndCheckGt(config_path, gt_path); +// } + +// BOOST_AUTO_TEST_CASE(CheckCalibrationSyntheticScenario2) { +// std::string config_path = +// "../tests/configs_for_end2end_tests/calib_param_synth_Scenario2.yml"; +// std::string gt_path = "../data/Blender_Images/Scenario_2/GroundTruth.yml"; +// BOOST_REQUIRE_EQUAL(boost::filesystem::exists(config_path), true); +// BOOST_REQUIRE_EQUAL(boost::filesystem::exists(gt_path), true); +// calibrateAndCheckGt(config_path, gt_path); +// } + +// BOOST_AUTO_TEST_CASE(CheckCalibrationSyntheticScenario3) { +// std::string config_path = +// "../tests/configs_for_end2end_tests/calib_param_synth_Scenario3.yml"; +// std::string gt_path = "../data/Blender_Images/Scenario_3/GroundTruth.yml"; +// BOOST_REQUIRE_EQUAL(boost::filesystem::exists(config_path), true); +// BOOST_REQUIRE_EQUAL(boost::filesystem::exists(gt_path), true); +// calibrateAndCheckGt(config_path, gt_path); +// } + +// BOOST_AUTO_TEST_CASE(CheckCalibrationSyntheticScenario4) { +// std::string config_path = +// "../tests/configs_for_end2end_tests/calib_param_synth_Scenario4.yml"; +// std::string gt_path = "../data/Blender_Images/Scenario_4/GroundTruth.yml"; +// BOOST_REQUIRE_EQUAL(boost::filesystem::exists(config_path), true); +// BOOST_REQUIRE_EQUAL(boost::filesystem::exists(gt_path), true); +// calibrateAndCheckGt(config_path, gt_path); +// } -BOOST_AUTO_TEST_CASE(CheckCalibrationSyntheticScenario1) { +BOOST_AUTO_TEST_CASE(CheckCalibrationSyntheticScenario5) { std::string config_path = "../tests/configs_for_end2end_tests/calib_param_synth_Scenario1.yml"; std::string gt_path = "../data/Blender_Images/Scenario_1/GroundTruth.yml"; @@ -134,40 +186,4 @@ BOOST_AUTO_TEST_CASE(CheckCalibrationSyntheticScenario1) { calibrateAndCheckGt(config_path, gt_path); } -BOOST_AUTO_TEST_CASE(CheckCalibrationSyntheticScenario2) { - std::string config_path = - "../tests/configs_for_end2end_tests/calib_param_synth_Scenario2.yml"; - std::string gt_path = "../data/Blender_Images/Scenario_2/GroundTruth.yml"; - BOOST_REQUIRE_EQUAL(boost::filesystem::exists(config_path), true); - BOOST_REQUIRE_EQUAL(boost::filesystem::exists(gt_path), true); - calibrateAndCheckGt(config_path, gt_path); -} - -BOOST_AUTO_TEST_CASE(CheckCalibrationSyntheticScenario3) { - std::string config_path = - "../tests/configs_for_end2end_tests/calib_param_synth_Scenario3.yml"; - std::string gt_path = "../data/Blender_Images/Scenario_3/GroundTruth.yml"; - BOOST_REQUIRE_EQUAL(boost::filesystem::exists(config_path), true); - BOOST_REQUIRE_EQUAL(boost::filesystem::exists(gt_path), true); - calibrateAndCheckGt(config_path, gt_path); -} - -BOOST_AUTO_TEST_CASE(CheckCalibrationSyntheticScenario4) { - std::string config_path = - "../tests/configs_for_end2end_tests/calib_param_synth_Scenario4.yml"; - std::string gt_path = "../data/Blender_Images/Scenario_4/GroundTruth.yml"; - BOOST_REQUIRE_EQUAL(boost::filesystem::exists(config_path), true); - BOOST_REQUIRE_EQUAL(boost::filesystem::exists(gt_path), true); - calibrateAndCheckGt(config_path, gt_path); -} - -BOOST_AUTO_TEST_CASE(CheckCalibrationSyntheticScenario5) { - std::string config_path = - "../tests/configs_for_end2end_tests/calib_param_synth_Scenario5.yml"; - std::string gt_path = "../data/Blender_Images/Scenario_5/GroundTruth.yml"; - BOOST_REQUIRE_EQUAL(boost::filesystem::exists(config_path), true); - BOOST_REQUIRE_EQUAL(boost::filesystem::exists(gt_path), true); - calibrateAndCheckGt(config_path, gt_path); -} - BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file