mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2024-12-29 11:06: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_debug.h"
|
||||||
#include "util/u_frame.h"
|
#include "util/u_frame.h"
|
||||||
#include "util/u_format.h"
|
#include "util/u_format.h"
|
||||||
|
#include "util/u_logging.h"
|
||||||
|
|
||||||
#include "tracking/t_tracking.h"
|
#include "tracking/t_tracking.h"
|
||||||
#include "tracking/t_calibration_opencv.hpp"
|
#include "tracking/t_calibration_opencv.hpp"
|
||||||
|
@ -22,6 +23,13 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <utility>
|
#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_filter, "T_DEBUG_HSV_FILTER", false)
|
||||||
DEBUG_GET_ONCE_BOOL_OPTION(hsv_picker, "T_DEBUG_HSV_PICKER", false)
|
DEBUG_GET_ONCE_BOOL_OPTION(hsv_picker, "T_DEBUG_HSV_PICKER", false)
|
||||||
|
@ -99,6 +107,8 @@ public:
|
||||||
cv::Size dims = {8, 6};
|
cv::Size dims = {8, 6};
|
||||||
enum t_board_pattern pattern = T_BOARD_CHECKERS;
|
enum t_board_pattern pattern = T_BOARD_CHECKERS;
|
||||||
float spacing_meters = 0.05;
|
float spacing_meters = 0.05;
|
||||||
|
bool marker; //!< Center board marker for sb_checkers.
|
||||||
|
bool normalize_image; //!< For SB checkers.
|
||||||
} board;
|
} board;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
|
@ -325,6 +335,45 @@ do_view_chess(class Calibration &c, struct ViewState &view, cv::Mat &gray, cv::M
|
||||||
return found;
|
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
|
static bool
|
||||||
do_view_circles(class Calibration &c, struct ViewState &view, cv::Mat &gray, cv::Mat &rgb)
|
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: //
|
case T_BOARD_CHECKERS: //
|
||||||
found = do_view_chess(c, view, gray, rgb);
|
found = do_view_chess(c, view, gray, rgb);
|
||||||
break;
|
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: //
|
case T_BOARD_CIRCLES: //
|
||||||
found = do_view_circles(c, view, gray, rgb);
|
found = do_view_circles(c, view, gray, rgb);
|
||||||
break;
|
break;
|
||||||
|
@ -405,6 +459,7 @@ build_board_position(class Calibration &c)
|
||||||
|
|
||||||
switch (c.board.pattern) {
|
switch (c.board.pattern) {
|
||||||
case T_BOARD_CHECKERS:
|
case T_BOARD_CHECKERS:
|
||||||
|
case T_BOARD_SB_CHECKERS:
|
||||||
case T_BOARD_CIRCLES:
|
case T_BOARD_CIRCLES:
|
||||||
// Nothing to do.
|
// Nothing to do.
|
||||||
break;
|
break;
|
||||||
|
@ -416,6 +471,7 @@ build_board_position(class Calibration &c)
|
||||||
|
|
||||||
switch (c.board.pattern) {
|
switch (c.board.pattern) {
|
||||||
case T_BOARD_CHECKERS:
|
case T_BOARD_CHECKERS:
|
||||||
|
case T_BOARD_SB_CHECKERS:
|
||||||
case T_BOARD_CIRCLES:
|
case T_BOARD_CIRCLES:
|
||||||
c.board.model_f32.reserve(rows_num * cols_num);
|
c.board.model_f32.reserve(rows_num * cols_num);
|
||||||
c.board.model_f64.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 *gui,
|
||||||
struct xrt_frame_sink **out_sink)
|
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());
|
auto &c = *(new Calibration());
|
||||||
|
|
||||||
// Basic setup.
|
// Basic setup.
|
||||||
|
@ -1238,6 +1307,15 @@ t_calibration_stereo_create(struct xrt_frame_context *xfctx,
|
||||||
c.subpixel_enable = params->checkers.subpixel_enable;
|
c.subpixel_enable = params->checkers.subpixel_enable;
|
||||||
c.subpixel_size = params->checkers.subpixel_size;
|
c.subpixel_size = params->checkers.subpixel_size;
|
||||||
break;
|
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:
|
case T_BOARD_CIRCLES:
|
||||||
c.board.dims = {
|
c.board.dims = {
|
||||||
params->circles.cols,
|
params->circles.cols,
|
||||||
|
@ -1307,6 +1385,8 @@ t_calibration_stereo_create(struct xrt_frame_context *xfctx,
|
||||||
push_model(c);
|
push_model(c);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -351,6 +351,8 @@ t_slam_start(struct xrt_tracked_slam *xts);
|
||||||
enum t_board_pattern
|
enum t_board_pattern
|
||||||
{
|
{
|
||||||
T_BOARD_CHECKERS,
|
T_BOARD_CHECKERS,
|
||||||
|
//! Sector based checker board, using `cv::findChessboardCornersSB`.
|
||||||
|
T_BOARD_SB_CHECKERS,
|
||||||
T_BOARD_CIRCLES,
|
T_BOARD_CIRCLES,
|
||||||
T_BOARD_ASYMMETRIC_CIRCLES,
|
T_BOARD_ASYMMETRIC_CIRCLES,
|
||||||
};
|
};
|
||||||
|
@ -390,6 +392,16 @@ struct t_calibration_params
|
||||||
int subpixel_size;
|
int subpixel_size;
|
||||||
} checkers;
|
} checkers;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
int cols;
|
||||||
|
int rows;
|
||||||
|
float size_meters;
|
||||||
|
|
||||||
|
bool marker;
|
||||||
|
bool normalize_image;
|
||||||
|
} sb_checkers;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
int cols;
|
int cols;
|
||||||
|
@ -446,6 +458,13 @@ t_calibration_params_default(struct t_calibration_params *p)
|
||||||
p->checkers.subpixel_enable = true;
|
p->checkers.subpixel_enable = true;
|
||||||
p->checkers.subpixel_size = 5;
|
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.
|
// Symmetrical circles.
|
||||||
p->circles.cols = 9;
|
p->circles.cols = 9;
|
||||||
p->circles.rows = 7;
|
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);
|
igInputInt("Collect in groups of #", &cs->params.num_collect_restart, 1, 5, 0);
|
||||||
|
|
||||||
igSeparator();
|
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) {
|
switch (cs->params.pattern) {
|
||||||
case T_BOARD_CHECKERS:
|
case T_BOARD_CHECKERS:
|
||||||
igInputInt("Checkerboard Rows", &cs->params.checkers.rows, 1, 5, 0);
|
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);
|
igCheckbox("Subpixel", &cs->params.checkers.subpixel_enable);
|
||||||
igInputInt("Subpixel Search Size", &cs->params.checkers.subpixel_size, 1, 5, 0);
|
igInputInt("Subpixel Search Size", &cs->params.checkers.subpixel_size, 1, 5, 0);
|
||||||
break;
|
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:
|
case T_BOARD_CIRCLES:
|
||||||
igInputInt("Circle Rows", &cs->params.circles.rows, 1, 5, 0);
|
igInputInt("Circle Rows", &cs->params.circles.rows, 1, 5, 0);
|
||||||
igInputInt("Circle Columns", &cs->params.circles.cols, 1, 5, 0);
|
igInputInt("Circle Columns", &cs->params.circles.cols, 1, 5, 0);
|
||||||
|
|
Loading…
Reference in a new issue