|
|
@@ -293,17 +293,14 @@ namespace camera_calibrator_impl {
|
|
|
// rotate corners if needed
|
|
|
auto rot_mat = rodrigues_to_mat(chess_r);
|
|
|
auto rot_quat = glm::quat_cast(rot_mat);
|
|
|
- break; // TODO: test the commented code
|
|
|
-
|
|
|
-// if (!last_rot_quat.has_value()
|
|
|
-// // https://math.stackexchange.com/questions/90081/quaternion-distance
|
|
|
-// || 1 - glm::dot(rot_quat, *last_rot_quat) < quat_threshold) {
|
|
|
-// last_rot_quat = rot_quat;
|
|
|
-// break;
|
|
|
-// } else {
|
|
|
-// std::ranges::reverse(corner);
|
|
|
-// SPDLOG_DEBUG("Flipped.");
|
|
|
-// }
|
|
|
+ if (!last_rot_quat.has_value()
|
|
|
+ // https://math.stackexchange.com/questions/90081/quaternion-distance
|
|
|
+ || 1 - glm::dot(rot_quat, *last_rot_quat) < quat_threshold) {
|
|
|
+ last_rot_quat = rot_quat;
|
|
|
+ break;
|
|
|
+ } else {
|
|
|
+ std::ranges::reverse(corner);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
auto ret_mat = to_transform_mat(to_vec3(chess_t),
|
|
|
@@ -341,7 +338,7 @@ namespace camera_calibrator_impl {
|
|
|
result_ts_offset = (offset_l + offset_r) / 2;
|
|
|
|
|
|
ts_offset = result_ts_offset;
|
|
|
- result_mat = calib_hand_eye();
|
|
|
+ result_mat = glm::inverse(calib_hand_eye());
|
|
|
SPDLOG_INFO("Estimated temporal offset is {}ms", result_ts_offset / 1000);
|
|
|
|
|
|
auto err_val = evaluate_hand_eye(result_mat);
|
|
|
@@ -351,6 +348,18 @@ namespace camera_calibrator_impl {
|
|
|
SPDLOG_INFO("Average 2D projection error is {:.2f}pix", img_reproj_err);
|
|
|
}
|
|
|
|
|
|
+ camera_intrinsic_v0 camera_calibrator_impl::hand_eye_calib::intrinsic_v0() {
|
|
|
+ auto ret = camera_intrinsic_v0();
|
|
|
+ ret.fx = intrinsic_mat[0][0];
|
|
|
+ ret.fy = intrinsic_mat[1][1];
|
|
|
+ ret.cx = intrinsic_mat[2][0];
|
|
|
+ ret.cy = intrinsic_mat[2][1];
|
|
|
+ std::ranges::copy(dist_coeffs, std::back_inserter(ret.dist));
|
|
|
+ ret.width = img_size.width;
|
|
|
+ ret.height = img_size.height;
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
}
|
|
|
|
|
|
camera_calibrator::impl::impl(const create_config &_conf) {
|
|
|
@@ -361,7 +370,7 @@ camera_calibrator::impl::impl(const create_config &_conf) {
|
|
|
camera_calibrator::impl::~impl() {
|
|
|
if (tp != nullptr) {
|
|
|
tp->purge();
|
|
|
- stop();
|
|
|
+ stop(true); // on_exit = true, force exit
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -386,7 +395,9 @@ void camera_calibrator::impl::process() {
|
|
|
auto valid_imgs =
|
|
|
img_pool | std::views::filter([](const auto &item) {
|
|
|
assert(item.process_finished);
|
|
|
- return item.corners_detected;
|
|
|
+ if (!item.corners_detected) return false;
|
|
|
+ if (item.corner_sharpness > sharpness_threshold) return false;
|
|
|
+ return true;
|
|
|
}) | std::views::transform([](const auto &item) {
|
|
|
assert(!item.corners.empty());
|
|
|
return hand_eye_calib::image_store_type(
|
|
|
@@ -407,6 +418,7 @@ void camera_calibrator::impl::process() {
|
|
|
conf.sophiar_conn->update_transform_variable(
|
|
|
conf.result_transform_var, ret);
|
|
|
}
|
|
|
+ conf.cb_func(calib->intrinsic_v0());
|
|
|
}
|
|
|
|
|
|
void camera_calibrator::impl::simulate_process(const simulate_info_type &info) {
|
|
|
@@ -415,12 +427,14 @@ void camera_calibrator::impl::simulate_process(const simulate_info_type &info) {
|
|
|
process();
|
|
|
}
|
|
|
|
|
|
-void camera_calibrator::impl::stop() {
|
|
|
+void camera_calibrator::impl::stop(bool on_exit) {
|
|
|
assert(img_conn.connected());
|
|
|
img_conn.disconnect();
|
|
|
tp = nullptr; // implicit wait()
|
|
|
- save_track_data();
|
|
|
- process();
|
|
|
+ if (!on_exit) {
|
|
|
+ save_track_data();
|
|
|
+ process();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
void camera_calibrator::impl::save_track_data() {
|
|
|
@@ -493,20 +507,6 @@ void camera_calibrator::impl::load_track_data(const std::string &path) {
|
|
|
item.corners_detected = true;
|
|
|
item.process_finished = true;
|
|
|
}
|
|
|
-}
|
|
|
-
|
|
|
-void camera_calibrator::impl::load_fake_data() {
|
|
|
- auto dist_coeffs = cv::Mat::zeros(1, 8, CV_64FC1);
|
|
|
- // @formatter:off
|
|
|
- cv::Mat intrinsic_mat = (cv::Mat_<double>(3, 3) <<
|
|
|
- 1000.f, 0.f, 500.f,
|
|
|
- 0.f, 1000.f, 500.f,
|
|
|
- 0.f, 0.f, 1.f);
|
|
|
- // @formatter:on
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
}
|
|
|
|
|
|
void camera_calibrator::impl::per_image_process(img_store_type *st) {
|
|
|
@@ -530,7 +530,7 @@ void camera_calibrator::impl::per_image_process(img_store_type *st) {
|
|
|
bool ok = cv::findChessboardCorners(img_gray, conf.pattern_size,
|
|
|
img_corners, corner_flag);
|
|
|
if (!ok) {
|
|
|
- last_finish.store(nullptr, std::memory_order::relaxed);
|
|
|
+// last_finish.store(nullptr, std::memory_order::relaxed);
|
|
|
return;
|
|
|
}
|
|
|
st->corners_detected = true;
|
|
|
@@ -540,7 +540,14 @@ void camera_calibrator::impl::per_image_process(img_store_type *st) {
|
|
|
auto zero_zone = cv::Size(-1, -1);
|
|
|
auto term_crit = cv::TermCriteria(cv::TermCriteria::COUNT | cv::TermCriteria::EPS, 20, 0.03);
|
|
|
cv::cornerSubPix(img_gray, img_corners, win_size, zero_zone, term_crit);
|
|
|
- st->corners = std::move(img_corners);
|
|
|
+ st->corners = img_corners;
|
|
|
+
|
|
|
+ // evaluate sharpness
|
|
|
+ auto sharpness = cv::estimateChessboardSharpness(
|
|
|
+ img_gray, conf.pattern_size, img_corners);
|
|
|
+ st->corner_sharpness = sharpness[0];
|
|
|
+ if (st->corner_sharpness > sharpness_threshold) return;
|
|
|
+
|
|
|
++img_ok_cnt;
|
|
|
}
|
|
|
|
|
|
@@ -627,6 +634,16 @@ void camera_calibrator::impl::show() {
|
|
|
ImGui::Text("Pending Images: %ld", tp->get_tasks_total());
|
|
|
ImGui::Text("Track Count: %ld", track_pool.size());
|
|
|
ImGui::Text("Image Count: %d / %ld", (int) img_ok_cnt, img_pool.size());
|
|
|
+ auto last_st = last_finish.load(std::memory_order::consume);
|
|
|
+ if (last_st != nullptr && last_st->corners_detected) {
|
|
|
+ if (last_st->corner_sharpness <= sharpness_threshold) {
|
|
|
+ ImGui::PushStyleColor(ImGuiCol_Text, (ImVec4) ImColor(0, 255, 0));
|
|
|
+ } else {
|
|
|
+ ImGui::PushStyleColor(ImGuiCol_Text, (ImVec4) ImColor(255, 0, 0));
|
|
|
+ }
|
|
|
+ ImGui::Text("Last sharpness: %.2f", last_st->corner_sharpness);
|
|
|
+ ImGui::PopStyleColor();
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|