aux/tracking: Add parameters to calibration

This commit is contained in:
Jakob Bornecrantz 2019-09-27 20:11:17 +01:00
parent 8d0aa220c1
commit ee3f54adb6
3 changed files with 105 additions and 44 deletions

View file

@ -22,11 +22,6 @@ 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_viewer, "T_DEBUG_HSV_VIEWER", false)
// calibration chessboard size - 7x9 'blocks' - the count
// of rows and cols refer to 'internal intersections'
#define CHESSBOARD_ROWS 6
#define CHESSBOARD_COLS 8
// we will use a number of samples spread across the frame
// to ensure a good calibration. must be > 9
#define CALIBRATION_SAMPLES 15
@ -557,9 +552,10 @@ t_calibration_frame(struct xrt_frame_sink *xsink, struct xrt_frame *xf)
*/
extern "C" int
t_calibration_create(struct xrt_frame_context *xfctx,
struct xrt_frame_sink *gui,
struct xrt_frame_sink **out_sink)
t_calibration_stereo_create(struct xrt_frame_context *xfctx,
struct t_calibration_params *params,
struct xrt_frame_sink *gui,
struct xrt_frame_sink **out_sink)
{
auto &c = *(new Calibration());
@ -589,11 +585,16 @@ t_calibration_create(struct xrt_frame_context *xfctx,
// Ensure we only get yuv or yuyv frames.
u_sink_create_to_yuv_or_yuyv(xfctx, *out_sink, out_sink);
c.chessboard_size = cv::Size(CHESSBOARD_COLS, CHESSBOARD_ROWS);
for (int i = 0; i < c.chessboard_size.width * c.chessboard_size.height;
i++) {
cv::Point3f p(i / c.chessboard_size.width,
i % c.chessboard_size.width, 0.0f);
int cross_cols_num = params->checker_cols_num - 1;
int cross_rows_num = params->checker_rows_num - 1;
int num_crosses = cross_cols_num * cross_rows_num;
c.chessboard_size = cv::Size(cross_cols_num, cross_rows_num);
for (int i = 0; i < num_crosses; i++) {
float x = (i / cross_cols_num) * params->checker_size_meters;
float y = (i % cross_cols_num) * params->checker_size_meters;
cv::Point3f p(x, y, 0.0f);
c.chessboard_model.push_back(p);
}

View file

@ -168,6 +168,31 @@ t_psvr_create(struct xrt_frame_context *xfctx,
struct xrt_tracked_psvr **out_xtvr,
struct xrt_frame_sink **out_sink);
/*
*
* Camera calibration
*
*/
#define T_CALIBRATION_DEFAULT_PARAMS \
{ \
9, 7, 0.025f, \
}
struct t_calibration_params
{
int checker_cols_num;
int checker_rows_num;
float checker_size_meters;
};
int
t_calibration_stereo_create(struct xrt_frame_context *xfctx,
struct t_calibration_params *params,
struct xrt_frame_sink *gui,
struct xrt_frame_sink **out_sink);
/*
*
@ -179,10 +204,7 @@ int
t_convert_yuv_or_yuyv_create(struct xrt_frame_sink *next,
struct xrt_frame_sink **out_sink);
int
t_calibration_create(struct xrt_frame_context *xfctx,
struct xrt_frame_sink *gui,
struct xrt_frame_sink **out_sink);
int
t_debug_hsv_picker_create(struct xrt_frame_context *xfctx,

View file

@ -28,7 +28,14 @@
struct calibration_scene
{
struct gui_scene base;
#ifdef XRT_HAVE_OPENCV
struct t_calibration_params params;
#endif
struct xrt_frame_context *xfctx;
struct xrt_fs *xfs;
size_t mode;
};
@ -69,7 +76,7 @@ draw_texture(struct gui_ogl_texture *tex, bool header)
}
static void
scene_render(struct gui_scene *scene, struct program *p)
scene_render_video(struct gui_scene *scene, struct program *p)
{
struct calibration_scene *cs = (struct calibration_scene *)scene;
@ -92,6 +99,55 @@ scene_render(struct gui_scene *scene, struct program *p)
igEnd();
}
static void
scene_render_select(struct gui_scene *scene, struct program *p)
{
struct calibration_scene *cs = (struct calibration_scene *)scene;
#ifdef XRT_HAVE_OPENCV
igBegin("Params", NULL, 0);
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);
static ImVec2 button_dims = {0, 0};
bool pressed = igButton("Done", button_dims);
igEnd();
if (!pressed) {
return;
}
cs->base.render = scene_render_video;
struct xrt_frame_sink *rgb = NULL;
struct xrt_frame_sink *raw = NULL;
struct xrt_frame_sink *cali = NULL;
p->texs[p->num_texs++] =
gui_ogl_sink_create("Calibration", cs->xfctx, &rgb);
u_sink_create_format_converter(cs->xfctx, XRT_FORMAT_R8G8B8, rgb, &rgb);
u_sink_queue_create(cs->xfctx, rgb, &rgb);
p->texs[p->num_texs++] = gui_ogl_sink_create("Raw", cs->xfctx, &raw);
u_sink_create_format_converter(cs->xfctx, XRT_FORMAT_R8G8B8, raw, &raw);
u_sink_queue_create(cs->xfctx, raw, &raw);
t_calibration_stereo_create(cs->xfctx, &cs->params, rgb, &cali);
u_sink_create_to_yuv_or_yuyv(cs->xfctx, cali, &cali);
u_sink_queue_create(cs->xfctx, cali, &cali);
u_sink_split_create(cs->xfctx, raw, cali, &cali);
// Now that we have setup a node graph, start it.
xrt_fs_stream_start(cs->xfs, cali, cs->mode);
#else
gui_scene_delete_me(p, &cs->base);
#endif
}
static void
scene_destroy(struct gui_scene *scene, struct program *p)
{
@ -120,34 +176,16 @@ gui_scene_calibrate(struct program *p,
{
struct calibration_scene *cs = U_TYPED_CALLOC(struct calibration_scene);
cs->base.render = scene_render;
#ifdef XRT_HAVE_OPENCV
struct t_calibration_params def = T_CALIBRATION_DEFAULT_PARAMS;
cs->params = def;
#endif
cs->base.render = scene_render_select;
cs->base.destroy = scene_destroy;
cs->xfctx = xfctx;
cs->xfs = xfs;
cs->mode = mode;
gui_scene_push_front(p, &cs->base);
#ifdef XRT_HAVE_OPENCV
struct xrt_frame_sink *rgb = NULL;
struct xrt_frame_sink *raw = NULL;
struct xrt_frame_sink *cali = NULL;
p->texs[p->num_texs++] =
gui_ogl_sink_create("Calibration", xfctx, &rgb);
u_sink_create_format_converter(xfctx, XRT_FORMAT_R8G8B8, rgb, &rgb);
u_sink_queue_create(xfctx, rgb, &rgb);
p->texs[p->num_texs++] = gui_ogl_sink_create("Raw", xfctx, &raw);
u_sink_create_format_converter(xfctx, XRT_FORMAT_R8G8B8, raw, &raw);
u_sink_queue_create(xfctx, raw, &raw);
t_calibration_create(xfctx, rgb, &cali);
u_sink_create_to_yuv_or_yuyv(xfctx, cali, &cali);
u_sink_queue_create(xfctx, cali, &cali);
u_sink_split_create(xfctx, raw, cali, &cali);
// Now that we have setup a node graph, start it.
xrt_fs_stream_start(xfs, cali, mode);
#else
gui_scene_delete_me(p, &cs->base);
#endif
}