|
|
@@ -2,6 +2,7 @@
|
|
|
#include "core/imgui_utility.hpp"
|
|
|
#include "third_party/scope_guard.hpp"
|
|
|
#include "render/render_utility.h"
|
|
|
+#include "render/render_texture.h"
|
|
|
|
|
|
#include <boost/asio/post.hpp>
|
|
|
|
|
|
@@ -356,6 +357,8 @@ void camera_calibrator::impl::start() {
|
|
|
track_pool.clear();
|
|
|
img_ok_cnt = 0;
|
|
|
|
|
|
+ coverage_fbo = std::make_unique<smart_frame_buffer>();
|
|
|
+
|
|
|
assert(tp == nullptr);
|
|
|
tp = std::make_unique<BS::thread_pool>(conf.num_threads);
|
|
|
img_conn = OBJ_SIG(conf.img_name)->connect(
|
|
|
@@ -408,6 +411,7 @@ void camera_calibrator::impl::stop(bool on_exit) {
|
|
|
assert(img_conn.connected());
|
|
|
img_conn.disconnect();
|
|
|
tp = nullptr; // implicit wait()
|
|
|
+ coverage_fbo = nullptr;
|
|
|
if (!on_exit) {
|
|
|
save_track_data();
|
|
|
process();
|
|
|
@@ -545,13 +549,18 @@ void camera_calibrator::impl::img_callback(obj_name_type name) {
|
|
|
auto cur_ts = OBJ_TS(conf.img_name);
|
|
|
auto ref_t = conf.sophiar_conn
|
|
|
->query_transform_variable(conf.ref_transform_var);
|
|
|
- if (!ref_t.has_value()) {
|
|
|
- return;
|
|
|
- } else {
|
|
|
- auto &item = track_pool.emplace_back();
|
|
|
- item.ref_mat = to_mat4(*ref_t);
|
|
|
- item.sample_ts = cur_ts;
|
|
|
- }
|
|
|
+ if (!ref_t.has_value()) return;
|
|
|
+ auto &item = track_pool.emplace_back();
|
|
|
+ item.ref_mat = to_mat4(*ref_t);
|
|
|
+ item.sample_ts = cur_ts;
|
|
|
+
|
|
|
+ auto err_t = conf.sophiar_conn
|
|
|
+ ->query_double_variable(conf.ref_error_var);
|
|
|
+ if (!err_t.has_value()) return;
|
|
|
+// assert(err_t.has_value());
|
|
|
+ item.track_error = *err_t;
|
|
|
+ last_track_err = item.track_error;
|
|
|
+ if (item.track_error > track_err_threshold) return;
|
|
|
|
|
|
// throttle
|
|
|
if (tp->get_tasks_queued() > conf.num_threads - 1) {
|
|
|
@@ -570,13 +579,7 @@ void camera_calibrator::impl::img_callback(obj_name_type name) {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
-void camera_calibrator::impl::render() {
|
|
|
- if (tp == nullptr) return; // not running
|
|
|
- auto st = last_finish.load(std::memory_order::acquire);
|
|
|
- if (st == nullptr) return;
|
|
|
- assert(st->process_finished);
|
|
|
- if (!st->corners_detected) return;
|
|
|
-
|
|
|
+void camera_calibrator::impl::render_corners(const corner_type &corner, NVGcolor color) {
|
|
|
auto size = query_viewport_size();
|
|
|
nvgBeginFrame(vg, size.width, size.height, 1.0f);
|
|
|
auto closer = sg::make_scope_guard([this] {
|
|
|
@@ -588,14 +591,47 @@ void camera_calibrator::impl::render() {
|
|
|
|
|
|
nvgBeginPath(vg);
|
|
|
static constexpr auto r = 5.0f;
|
|
|
- for (auto &p: st->corners) {
|
|
|
+ for (auto &p: corner) {
|
|
|
nvgCircle(vg, p.x, size.height - p.y, r); // flip Y
|
|
|
}
|
|
|
nvgPathWinding(vg, NVG_HOLE);
|
|
|
- nvgFillColor(vg, nvgRGB(255, 0, 0));
|
|
|
+ nvgFillColor(vg, color);
|
|
|
nvgFill(vg);
|
|
|
}
|
|
|
|
|
|
+void camera_calibrator::impl::render() {
|
|
|
+ if (tp == nullptr) return; // not running
|
|
|
+
|
|
|
+ // render coverage
|
|
|
+ assert(coverage_fbo != nullptr);
|
|
|
+ if (coverage_fbo->id == 0) [[unlikely]] { // lazy creation for img_size
|
|
|
+ auto fbo_conf = smart_frame_buffer::create_config{
|
|
|
+ .size = img_size,
|
|
|
+ .depth_fmt = GL_DEPTH24_STENCIL8,
|
|
|
+ };
|
|
|
+ coverage_fbo->create(fbo_conf);
|
|
|
+ } else {
|
|
|
+ auto tex_conf = tex_render_info{
|
|
|
+ .mode = TEX_COLOR_ONLY,
|
|
|
+ };
|
|
|
+ tex_conf.color.fmt = COLOR_RGB;
|
|
|
+ tex_conf.color.id = coverage_fbo->color_tex[0].id;
|
|
|
+ tex_conf.color.alpha = 0.5f;
|
|
|
+ render_texture(tex_conf);
|
|
|
+ }
|
|
|
+
|
|
|
+ auto st = last_finish.load(std::memory_order::acquire);
|
|
|
+ if (st == nullptr) return;
|
|
|
+ assert(st->process_finished);
|
|
|
+ if (!st->corners_detected) return;
|
|
|
+
|
|
|
+ render_corners(st->corners, nvgRGB(255, 0, 0));
|
|
|
+
|
|
|
+ coverage_fbo->bind();
|
|
|
+ render_corners(st->corners, nvgRGB(0, 255, 0));
|
|
|
+ coverage_fbo->unbind();
|
|
|
+}
|
|
|
+
|
|
|
void camera_calibrator::impl::show() {
|
|
|
auto ctx = conf.ctx;
|
|
|
bool is_running = (tp != nullptr);
|
|
|
@@ -618,15 +654,18 @@ 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());
|
|
|
+
|
|
|
+ { // track error
|
|
|
+ auto guard = imgui_valid_style_guard(
|
|
|
+ last_track_err <= track_err_threshold);
|
|
|
+ ImGui::Text("Last Track Error: %.2f", last_track_err);
|
|
|
+ }
|
|
|
+
|
|
|
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();
|
|
|
+ auto guard = imgui_valid_style_guard(
|
|
|
+ last_st->corner_sharpness <= sharpness_threshold);
|
|
|
+ ImGui::Text("Last Sharpness: %.2f", last_st->corner_sharpness);
|
|
|
}
|
|
|
}
|
|
|
}
|