diff --git a/src/xrt/auxiliary/tracking/t_calibration.cpp b/src/xrt/auxiliary/tracking/t_calibration.cpp index 04b122084..40ea1affe 100644 --- a/src/xrt/auxiliary/tracking/t_calibration.cpp +++ b/src/xrt/auxiliary/tracking/t_calibration.cpp @@ -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); } diff --git a/src/xrt/auxiliary/tracking/t_tracking.h b/src/xrt/auxiliary/tracking/t_tracking.h index 71d118bf4..3782bb466 100644 --- a/src/xrt/auxiliary/tracking/t_tracking.h +++ b/src/xrt/auxiliary/tracking/t_tracking.h @@ -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, diff --git a/src/xrt/targets/gui/gui_scene_calibrate.c b/src/xrt/targets/gui/gui_scene_calibrate.c index 529f3780f..5f509fcb4 100644 --- a/src/xrt/targets/gui/gui_scene_calibrate.c +++ b/src/xrt/targets/gui/gui_scene_calibrate.c @@ -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 }