diff --git a/src/xrt/auxiliary/tracking/t_calibration.cpp b/src/xrt/auxiliary/tracking/t_calibration.cpp index 3e9870e9a..f0c6480d4 100644 --- a/src/xrt/auxiliary/tracking/t_calibration.cpp +++ b/src/xrt/auxiliary/tracking/t_calibration.cpp @@ -110,16 +110,6 @@ struct ViewState cv::Mat map2 = {}; }; -/*! - * What type of pattern is being used. - */ -enum class Pattern -{ - CHESSBOARD, - CIRCLES_GRID, - ASYMMETRIC_CIRCLES_GRID, -}; - /*! * Main class for doing calibration. */ @@ -139,7 +129,7 @@ public: { Model model = {}; cv::Size dims = {8, 6}; - Pattern pattern = Pattern::CHESSBOARD; + enum t_board_pattern pattern = T_BOARD_CHECKERS; float spacing_meters = 0.05; } board; @@ -335,7 +325,7 @@ do_view_circles(class Calibration &c, cv::Mat &rgb) { int flags = 0; - if (c.board.pattern == Pattern::ASYMMETRIC_CIRCLES_GRID) { + if (c.board.pattern == T_BOARD_ASYMMETRIC_CIRCLES) { flags |= cv::CALIB_CB_ASYMMETRIC_GRID; } @@ -386,13 +376,13 @@ do_view(class Calibration &c, bool found = false; switch (c.board.pattern) { - case Pattern::CHESSBOARD: + case T_BOARD_CHECKERS: // found = do_view_chess(c, view, grey, rgb); break; - case Pattern::CIRCLES_GRID: + case T_BOARD_CIRCLES: // found = do_view_circles(c, view, grey, rgb); break; - case Pattern::ASYMMETRIC_CIRCLES_GRID: + case T_BOARD_ASYMMETRIC_CIRCLES: // found = do_view_circles(c, view, grey, rgb); break; default: assert(false); @@ -429,19 +419,19 @@ build_board_position(class Calibration &c) float size_meters = c.board.spacing_meters; switch (c.board.pattern) { - case Pattern::CHESSBOARD: - case Pattern::CIRCLES_GRID: + case T_BOARD_CHECKERS: + case T_BOARD_CIRCLES: // Nothing to do. break; - case Pattern::ASYMMETRIC_CIRCLES_GRID: + case T_BOARD_ASYMMETRIC_CIRCLES: // From diagonal size to "square" size. size_meters = sqrt((size_meters * size_meters) / 2.0); break; } switch (c.board.pattern) { - case Pattern::CHESSBOARD: - case Pattern::CIRCLES_GRID: + case T_BOARD_CHECKERS: + case T_BOARD_CIRCLES: for (int i = 0; i < rows_num; ++i) { for (int j = 0; j < cols_num; ++j) { cv::Point3f p = { @@ -453,7 +443,7 @@ build_board_position(class Calibration &c) } } break; - case Pattern::ASYMMETRIC_CIRCLES_GRID: + case T_BOARD_ASYMMETRIC_CIRCLES: for (int i = 0; i < rows_num; ++i) { for (int j = 0; j < cols_num; ++j) { cv::Point3f p = { @@ -991,20 +981,42 @@ t_calibration_stereo_create(struct xrt_frame_context *xfctx, *out_sink = &c.base; // Copy the parameters. - c.board.dims = { - params->checker_cols_num - 1, - params->checker_rows_num - 1, - }; c.use_fisheye = params->use_fisheye; - c.board.spacing_meters = params->checker_size_meters; - c.subpixel_enable = params->subpixel_enable; - c.subpixel_size = params->subpixel_size; + c.board.pattern = params->pattern; + switch (params->pattern) { + case T_BOARD_CHECKERS: + c.board.dims = { + params->checkers.cols - 1, + params->checkers.rows - 1, + }; + c.board.spacing_meters = params->checkers.size_meters; + c.subpixel_enable = params->checkers.subpixel_enable; + c.subpixel_size = params->checkers.subpixel_size; + break; + case T_BOARD_CIRCLES: + c.board.dims = { + params->circles.cols, + params->circles.rows, + }; + c.board.spacing_meters = params->circles.distance_meters; + break; + case T_BOARD_ASYMMETRIC_CIRCLES: + c.board.dims = { + params->asymmetric_circles.cols, + params->asymmetric_circles.rows, + }; + c.board.spacing_meters = + params->asymmetric_circles.diagonal_distance_meters; + break; + default: assert(false); + } c.num_wait_for = params->num_wait_for; c.num_collect_total = params->num_collect_total; c.num_collect_restart = params->num_collect_restart; c.mirror_rgb_image = params->mirror_rgb_image; c.save_images = params->save_images; + // Setup a initial message. P("Waiting for camera"); make_gui_str(c); diff --git a/src/xrt/auxiliary/tracking/t_tracking.h b/src/xrt/auxiliary/tracking/t_tracking.h index 1b0eae2aa..59268f2a1 100644 --- a/src/xrt/auxiliary/tracking/t_tracking.h +++ b/src/xrt/auxiliary/tracking/t_tracking.h @@ -329,20 +329,64 @@ t_psvr_create(struct xrt_frame_context *xfctx, #define T_CALIBRATION_DEFAULT_PARAMS \ { \ - false, 9, 7, 0.025f, true, 5, 5, 20, 1, false, true \ + false, T_BOARD_CHECKERS, \ + { \ + 9, 7, 0.025f, true, 5, \ + }, \ + { \ + 9, \ + 7, \ + 0.025f, \ + }, \ + { \ + 5, \ + 17, \ + 0.02f, \ + }, \ + 5, 20, 1, false, true, \ } +/*! + * Board pattern type. + */ +enum t_board_pattern +{ + T_BOARD_CHECKERS, + T_BOARD_CIRCLES, + T_BOARD_ASYMMETRIC_CIRCLES, +}; + struct t_calibration_params { //! Should we use fisheye version of the calibration functions. bool use_fisheye; - int checker_cols_num; - int checker_rows_num; - float checker_size_meters; + //! What type of pattern are we using for calibration. + enum t_board_pattern pattern; - bool subpixel_enable; - int subpixel_size; + struct + { + int cols; + int rows; + float size_meters; + + bool subpixel_enable; + int subpixel_size; + } checkers; + + struct + { + int cols; + int rows; + float distance_meters; + } circles; + + struct + { + int cols; + int rows; + float diagonal_distance_meters; + } asymmetric_circles; int num_wait_for; int num_collect_total; diff --git a/src/xrt/state_trackers/gui/gui_scene_calibrate.c b/src/xrt/state_trackers/gui/gui_scene_calibrate.c index f94bfd1e9..a82a09bbf 100644 --- a/src/xrt/state_trackers/gui/gui_scene_calibrate.c +++ b/src/xrt/state_trackers/gui/gui_scene_calibrate.c @@ -24,6 +24,8 @@ #include "gui_common.h" #include "gui_imgui.h" +#include + struct calibration_scene { @@ -120,13 +122,27 @@ scene_render_select(struct gui_scene *scene, struct gui_program *p) igInputInt("Collect in groups of #", &cs->params.num_collect_restart, 1, 5, 0); igSeparator(); - igInputFloat("Checker Size (m)", &cs->params.checker_size_meters, 0.0005, 0.001, NULL, 0); - igInputInt("Checkerboard Rows", &cs->params.checker_rows_num, 1, 5, 0); - igInputInt("Checkerboard Columns", &cs->params.checker_cols_num, 1, 5, 0); - - igSeparator(); - igCheckbox("Subpixel", &cs->params.subpixel_enable); - igInputInt("Subpixel Search Size", &cs->params.subpixel_size, 1, 5, 0); + igComboStr("Board type", (int*)&cs->params.pattern, "Checkers\0Circles\0Asymetric Circles\0\0", 3); + switch (cs->params.pattern) { + case T_BOARD_CHECKERS: + igInputInt("Checkerboard Rows", &cs->params.checkers.rows, 1, 5, 0); + igInputInt("Checkerboard Columns", &cs->params.checkers.cols, 1, 5, 0); + igInputFloat("Checker Size (m)", &cs->params.checkers.size_meters, 0.0005, 0.001, NULL, 0); + igCheckbox("Subpixel", &cs->params.checkers.subpixel_enable); + igInputInt("Subpixel Search Size", &cs->params.checkers.subpixel_size, 1, 5, 0); + break; + case T_BOARD_CIRCLES: + igInputInt("Circle Rows", &cs->params.circles.rows, 1, 5, 0); + igInputInt("Circle Columns", &cs->params.circles.cols, 1, 5, 0); + igInputFloat("Spacing (m)", &cs->params.circles.distance_meters, 0.0005, 0.001, NULL, 0); + break; + case T_BOARD_ASYMMETRIC_CIRCLES: + igInputInt("Circle Rows", &cs->params.asymmetric_circles.rows, 1, 5, 0); + igInputInt("Circle Columns", &cs->params.asymmetric_circles.cols, 1, 5, 0); + igInputFloat("Diagonal spacing (m)", &cs->params.asymmetric_circles.diagonal_distance_meters, 0.0005, 0.001, NULL, 0); + break; + default: assert(false); + } // clang-format on static ImVec2 button_dims = {0, 0};