t/calib: Re-organize parameters and make it possible to select board type

This commit is contained in:
Jakob Bornecrantz 2019-11-22 11:41:36 +00:00
parent 9a4b55758a
commit 86dc9e1a6b
3 changed files with 113 additions and 41 deletions

View file

@ -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);

View file

@ -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;

View file

@ -24,6 +24,8 @@
#include "gui_common.h"
#include "gui_imgui.h"
#include <assert.h>
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};