Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Analyze calibration without bad images #78

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 35 additions & 19 deletions McCalib/src/McCalib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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
Expand Down Expand Up @@ -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);
}
}
}
Expand All @@ -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) {
Expand All @@ -2016,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
Expand Down Expand Up @@ -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);
}
}
}
Expand Down Expand Up @@ -2245,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<std::string> frame_list;
int nb_cam_group = cam_group_.size();
fs << "nb_camera_group" << nb_cam_group;

Expand All @@ -2259,9 +2258,26 @@ void Calibration::saveReprojectionErrorToFile() {
std::shared_ptr<Frame> 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<int, std::weak_ptr<CameraGroupObs>> current_cam_group_obs_vec =
Expand Down
23 changes: 19 additions & 4 deletions python_utils/compute_error_statistic.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,26 @@ 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[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()):
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 = []

Expand All @@ -73,7 +87,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)


Expand Down
116 changes: 66 additions & 50 deletions tests/test_calibration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<double>(0, 0);
double fy_gt = camera_matrix_gt.at<double>(1, 0);
double fy_gt = camera_matrix_gt.at<double>(1, 1);
double cx_gt = camera_matrix_gt.at<double>(0, 2);
double cy_gt = camera_matrix_gt.at<double>(1, 2);
cv::Mat rot_gt(3, 3, CV_64F);
Expand All @@ -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<double>(0, 0);
double fy_pred = camera_matrix_pred.at<double>(1, 0);
double fy_pred = camera_matrix_pred.at<double>(1, 1);
double cx_pred = camera_matrix_pred.at<double>(0, 2);
double cy_pred = camera_matrix_pred.at<double>(1, 2);
cv::Mat rot_pred(3, 3, CV_64F);
Expand All @@ -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";
Expand All @@ -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()
Loading