mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2024-12-28 18:46:18 +00:00
t/calibration: Add support for findChessboardCornersSB
This commit is contained in:
parent
d86adce39d
commit
de283a8b0c
|
@ -14,6 +14,7 @@
|
|||
#include "util/u_debug.h"
|
||||
#include "util/u_frame.h"
|
||||
#include "util/u_format.h"
|
||||
#include "util/u_logging.h"
|
||||
|
||||
#include "tracking/t_tracking.h"
|
||||
#include "tracking/t_calibration_opencv.hpp"
|
||||
|
@ -22,6 +23,13 @@
|
|||
#include <sys/stat.h>
|
||||
#include <utility>
|
||||
|
||||
#if CV_MAJOR_VERSION >= 4
|
||||
#define SB_CHEESBOARD_CORNERS_SUPPORTED
|
||||
#if CV_MINOR_VERSION >= 3 || CV_MAJOR_VERSION > 4
|
||||
#define SB_CHEESBOARD_CORNERS_MARKER_SUPPORTED
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
DEBUG_GET_ONCE_BOOL_OPTION(hsv_filter, "T_DEBUG_HSV_FILTER", false)
|
||||
DEBUG_GET_ONCE_BOOL_OPTION(hsv_picker, "T_DEBUG_HSV_PICKER", false)
|
||||
|
@ -99,6 +107,8 @@ public:
|
|||
cv::Size dims = {8, 6};
|
||||
enum t_board_pattern pattern = T_BOARD_CHECKERS;
|
||||
float spacing_meters = 0.05;
|
||||
bool marker; //!< Center board marker for sb_checkers.
|
||||
bool normalize_image; //!< For SB checkers.
|
||||
} board;
|
||||
|
||||
struct
|
||||
|
@ -325,6 +335,45 @@ do_view_chess(class Calibration &c, struct ViewState &view, cv::Mat &gray, cv::M
|
|||
return found;
|
||||
}
|
||||
|
||||
#ifdef SB_CHEESBOARD_CORNERS_SUPPORTED
|
||||
static bool
|
||||
do_view_sb_checkers(class Calibration &c, struct ViewState &view, cv::Mat &gray, cv::Mat &rgb)
|
||||
{
|
||||
/*
|
||||
* Fisheye requires measurement and model to be double, other functions
|
||||
* requires them to be floats (like cornerSubPix). So we give in
|
||||
* current_f32 here and convert below.
|
||||
*/
|
||||
|
||||
int flags = 0;
|
||||
if (c.board.normalize_image) {
|
||||
flags += cv::CALIB_CB_NORMALIZE_IMAGE;
|
||||
}
|
||||
|
||||
#ifdef SB_CHEESBOARD_CORNERS_MARKER_SUPPORTED
|
||||
if (c.board.marker) {
|
||||
// Only available in OpenCV 4.3 and above.
|
||||
flags += cv::CALIB_CB_MARKER;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool found = cv::findChessboardCornersSB(gray, // Image
|
||||
c.board.dims, // patternSize
|
||||
view.current_f32, // corners
|
||||
flags); // flags
|
||||
|
||||
// Do the conversion here.
|
||||
view.current_f64.clear(); // Doesn't effect capacity.
|
||||
for (const cv::Point2f &p : view.current_f32) {
|
||||
view.current_f64.emplace_back(double(p.x), double(p.y));
|
||||
}
|
||||
|
||||
do_view_coverage(c, view, gray, rgb, found);
|
||||
|
||||
return found;
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool
|
||||
do_view_circles(class Calibration &c, struct ViewState &view, cv::Mat &gray, cv::Mat &rgb)
|
||||
{
|
||||
|
@ -364,6 +413,11 @@ do_view(class Calibration &c, struct ViewState &view, cv::Mat &gray, cv::Mat &rg
|
|||
case T_BOARD_CHECKERS: //
|
||||
found = do_view_chess(c, view, gray, rgb);
|
||||
break;
|
||||
#ifdef SB_CHEESBOARD_CORNERS_SUPPORTED
|
||||
case T_BOARD_SB_CHECKERS: //
|
||||
found = do_view_sb_checkers(c, view, gray, rgb);
|
||||
break;
|
||||
#endif
|
||||
case T_BOARD_CIRCLES: //
|
||||
found = do_view_circles(c, view, gray, rgb);
|
||||
break;
|
||||
|
@ -405,6 +459,7 @@ build_board_position(class Calibration &c)
|
|||
|
||||
switch (c.board.pattern) {
|
||||
case T_BOARD_CHECKERS:
|
||||
case T_BOARD_SB_CHECKERS:
|
||||
case T_BOARD_CIRCLES:
|
||||
// Nothing to do.
|
||||
break;
|
||||
|
@ -416,6 +471,7 @@ build_board_position(class Calibration &c)
|
|||
|
||||
switch (c.board.pattern) {
|
||||
case T_BOARD_CHECKERS:
|
||||
case T_BOARD_SB_CHECKERS:
|
||||
case T_BOARD_CIRCLES:
|
||||
c.board.model_f32.reserve(rows_num * cols_num);
|
||||
c.board.model_f64.reserve(rows_num * cols_num);
|
||||
|
@ -1217,6 +1273,19 @@ t_calibration_stereo_create(struct xrt_frame_context *xfctx,
|
|||
struct xrt_frame_sink *gui,
|
||||
struct xrt_frame_sink **out_sink)
|
||||
{
|
||||
#ifndef SB_CHEESBOARD_CORNERS_SUPPORTED
|
||||
if (params->pattern == T_BOARD_SB_CHECKERS) {
|
||||
U_LOG_E("OpenCV %u.%u doesn't support SB chessboard!", CV_MAJOR_VERSION, CV_MINOR_VERSION);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
#ifndef SB_CHEESBOARD_CORNERS_MARKER_SUPPORTED
|
||||
if (params->pattern == T_BOARD_SB_CHECKERS && params->sb_checkers.marker) {
|
||||
U_LOG_W("OpenCV %u.%u doesn't support SB chessboard marker option!", CV_MAJOR_VERSION,
|
||||
CV_MINOR_VERSION);
|
||||
}
|
||||
#endif
|
||||
|
||||
auto &c = *(new Calibration());
|
||||
|
||||
// Basic setup.
|
||||
|
@ -1238,6 +1307,15 @@ t_calibration_stereo_create(struct xrt_frame_context *xfctx,
|
|||
c.subpixel_enable = params->checkers.subpixel_enable;
|
||||
c.subpixel_size = params->checkers.subpixel_size;
|
||||
break;
|
||||
case T_BOARD_SB_CHECKERS:
|
||||
c.board.dims = {
|
||||
params->sb_checkers.cols,
|
||||
params->sb_checkers.rows,
|
||||
};
|
||||
c.board.spacing_meters = params->sb_checkers.size_meters;
|
||||
c.board.marker = params->sb_checkers.marker;
|
||||
c.board.normalize_image = params->sb_checkers.normalize_image;
|
||||
break;
|
||||
case T_BOARD_CIRCLES:
|
||||
c.board.dims = {
|
||||
params->circles.cols,
|
||||
|
@ -1307,6 +1385,8 @@ t_calibration_stereo_create(struct xrt_frame_context *xfctx,
|
|||
push_model(c);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -351,6 +351,8 @@ t_slam_start(struct xrt_tracked_slam *xts);
|
|||
enum t_board_pattern
|
||||
{
|
||||
T_BOARD_CHECKERS,
|
||||
//! Sector based checker board, using `cv::findChessboardCornersSB`.
|
||||
T_BOARD_SB_CHECKERS,
|
||||
T_BOARD_CIRCLES,
|
||||
T_BOARD_ASYMMETRIC_CIRCLES,
|
||||
};
|
||||
|
@ -390,6 +392,16 @@ struct t_calibration_params
|
|||
int subpixel_size;
|
||||
} checkers;
|
||||
|
||||
struct
|
||||
{
|
||||
int cols;
|
||||
int rows;
|
||||
float size_meters;
|
||||
|
||||
bool marker;
|
||||
bool normalize_image;
|
||||
} sb_checkers;
|
||||
|
||||
struct
|
||||
{
|
||||
int cols;
|
||||
|
@ -446,6 +458,13 @@ t_calibration_params_default(struct t_calibration_params *p)
|
|||
p->checkers.subpixel_enable = true;
|
||||
p->checkers.subpixel_size = 5;
|
||||
|
||||
// Sector based checker board.
|
||||
p->sb_checkers.cols = 14;
|
||||
p->sb_checkers.rows = 9;
|
||||
p->sb_checkers.size_meters = 0.01206f;
|
||||
p->sb_checkers.marker = false;
|
||||
p->sb_checkers.normalize_image = false;
|
||||
|
||||
// Symmetrical circles.
|
||||
p->circles.cols = 9;
|
||||
p->circles.rows = 7;
|
||||
|
|
|
@ -273,7 +273,7 @@ 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();
|
||||
igComboStr("Board type", (int *)&cs->params.pattern, "Checkers\0Circles\0Asymetric Circles\0\0", 3);
|
||||
igComboStr("Board type", (int *)&cs->params.pattern, "Checkers\0Corners SB\0Circles\0Asymetric Circles\0\0", 3);
|
||||
switch (cs->params.pattern) {
|
||||
case T_BOARD_CHECKERS:
|
||||
igInputInt("Checkerboard Rows", &cs->params.checkers.rows, 1, 5, 0);
|
||||
|
@ -282,6 +282,13 @@ scene_render_select(struct gui_scene *scene, struct gui_program *p)
|
|||
igCheckbox("Subpixel", &cs->params.checkers.subpixel_enable);
|
||||
igInputInt("Subpixel Search Size", &cs->params.checkers.subpixel_size, 1, 5, 0);
|
||||
break;
|
||||
case T_BOARD_SB_CHECKERS:
|
||||
igInputInt("Internal Corner Rows", &cs->params.sb_checkers.rows, 1, 5, 0);
|
||||
igInputInt("Internal Corner Columns", &cs->params.sb_checkers.cols, 1, 5, 0);
|
||||
igInputFloat("Corner Spacing (m)", &cs->params.sb_checkers.size_meters, 0.0005, 0.001, NULL, 0);
|
||||
igCheckbox("Marker", &cs->params.sb_checkers.marker);
|
||||
igCheckbox("Normalize image", &cs->params.sb_checkers.normalize_image);
|
||||
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);
|
||||
|
|
Loading…
Reference in a new issue