Monado OpenXR Runtime
t_tracking.h
Go to the documentation of this file.
1 // Copyright 2019-2020, Collabora, Ltd.
2 // SPDX-License-Identifier: BSL-1.0
3 /*!
4  * @file
5  * @brief Tracking API interface.
6  * @author Pete Black <pblack@collabora.com>
7  * @author Jakob Bornecrantz <jakob@collabora.com>
8  * @author Ryan Pavlik <ryan.pavlik@collabora.com>
9  * @ingroup aux_tracking
10  */
11 
12 #pragma once
13 
14 #include "xrt/xrt_frame.h"
15 #include "util/u_misc.h"
16 
17 #include <stdio.h>
18 
19 
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23 
24 
25 /*!
26  * @defgroup aux_tracking Tracking
27  * @ingroup aux
28  * @brief Trackers, filters and associated helper code.
29  *
30  *
31  * ### Coordinate system
32  *
33  * Right now there is no specific convention on where a tracking systems
34  * coordinate system is centered, and is something we probably need to figure
35  * out. Right now the stereo based tracking system used by the PSVR and PSMV
36  * tracking system is centered on the camera that OpenCV decided is origin.
37  *
38  * To go a bit further on the PSVR/PSMV case. Think about a idealized start up
39  * case, the user is wearing the HMD headset and holding two PSMV controllers.
40  * The HMD's coordinate system axis are perfectly parallel with the user
41  * coordinate with the user's coordinate system. Where -Z is forward. The user
42  * holds the controllers with the ball pointing up and the buttons on the back
43  * pointing forward. Which if you read the documentation of @ref psmv_device
44  * will that the axis of the PSMV are also perfectly aligned with the users
45  * coordinate system. So everything "attached" to the user have it's coordinate
46  * system parallel to the user's.
47  *
48  * The camera on the other hand is looking directly at the user, it's Z-axis and
49  * X-axis is flipped in relation to the user's. So to compare what is sees to
50  * what the user sees, everything is rotated 180° around the Y-axis.
51  */
52 
53 /*!
54  * @dir auxiliary/tracking
55  * @ingroup aux
56  *
57  * @brief Trackers, filters and associated helper code.
58  */
59 
60 /*!
61  * @ingroup aux_tracking
62  * @{
63  */
64 
65 
66 /*
67  *
68  * Pre-declare
69  *
70  */
71 
72 struct xrt_tracked_psmv;
73 struct xrt_tracked_psvr;
74 
75 
76 /*
77  *
78  * Calibration data.
79  *
80  */
81 
82 //! Maximum size of rectilinear distortion coefficient array
83 #define XRT_DISTORTION_MAX_DIM (5)
84 
85 /*!
86  * @brief Essential calibration data for a single camera, or single lens/sensor
87  * of a stereo camera.
88  */
90 {
91  //! Source image size
93 
94  //! Camera intrinsics matrix
95  double intrinsics[3][3];
96 
97  //! Rectilinear distortion coefficients: k1, k2, p1, p2[, k3[, k4, k5,
98  //! k6[, s1, s2, s3, s4]]
100 
101  //! Fisheye camera distortion coefficients
103 
104  //! Is the camera fisheye?
106 };
107 
108 /*!
109  * Stereo camera calibration data to be given to trackers.
110  */
112 {
113  //! Ref counting
114  struct xrt_reference reference;
115 
116  //! Calibration of individual views/sensor
117  struct t_camera_calibration view[2];
118 
119  //! Translation from first to second in the stereo pair.
120  double camera_translation[3];
121  //! Rotation matrix from first to second in the stereo pair.
122  double camera_rotation[3][3];
123 
124  //! Essential matrix.
125  double camera_essential[3][3];
126  //! Fundamental matrix.
127  double camera_fundamental[3][3];
128 };
129 
130 /*!
131  * Allocates a new stereo calibration data, unreferences the old @p calib.
132  */
133 void
135 
136 /*!
137  * Only to be called by @p t_stereo_camera_calibration_reference.
138  */
139 void
141 
142 /*!
143  * Update the reference counts on a stereo calibration data(s).
144  *
145  * @param dst Pointer to a object reference, if the object reference is
146  * non-null will decrement it's counter. The reference that
147  * @p dst points to will be set to @p src.
148  * @param[in] src Object to be have it's refcount increased @p dst is set to
149  * this.
150  */
151 static inline void
152 t_stereo_camera_calibration_reference(struct t_stereo_camera_calibration **dst,
153  struct t_stereo_camera_calibration *src)
154 {
155  struct t_stereo_camera_calibration *old_dst = *dst;
156 
157  if (old_dst == src) {
158  return;
159  }
160 
161  if (src) {
162  xrt_reference_inc(&src->reference);
163  }
164 
165  *dst = src;
166 
167  if (old_dst) {
168  if (xrt_reference_dec(&old_dst->reference)) {
170  }
171  }
172 }
173 
174 /*!
175  * Load stereo calibration data from a given file.
176  */
177 bool
179  FILE *calib_file, struct t_stereo_camera_calibration **out_data);
180 
181 /*!
182  * Save the given stereo calibration data to the given file.
183  */
184 bool
185 t_stereo_camera_calibration_save_v1(FILE *calib_file,
186  struct t_stereo_camera_calibration *data);
187 
188 
189 /*
190  *
191  * Conversion functions.
192  *
193  */
194 
196 {
197  uint8_t v[256][256][256][3];
198 };
199 
200 void
202 
203 void
205 
206 void
208 
209 void
211 
212 void
214  uint32_t height,
215  size_t stride,
216  void *data_ptr);
217 
218 void
220  uint32_t height,
221  size_t stride,
222  void *data_ptr);
223 
224 void
226  uint32_t height,
227  size_t stride,
228  void *data_ptr);
229 
230 
231 /*
232  *
233  * Filter functions.
234  *
235  */
236 
237 #define T_HSV_SIZE 32
238 #define T_HSV_STEP (256 / T_HSV_SIZE)
239 
240 #define T_HSV_DEFAULT_PARAMS() \
241  { \
242  { \
243  {165, 30, 160, 100}, \
244  {135, 30, 160, 100}, \
245  {95, 30, 160, 100}, \
246  }, \
247  {128, 80}, \
248  }
249 
251 {
252  uint8_t hue_min;
253  uint8_t hue_range;
254 
255  uint8_t s_min;
256 
257  uint8_t v_min;
258 };
259 
261 {
262  struct t_hsv_filter_color color[3];
263 
264  struct
265  {
266  uint8_t s_max;
267  uint8_t v_min;
268  } white;
269 };
270 
272 {
273  uint8_t v[256][256][256];
274 };
275 
277 {
279 };
280 
281 void
283  struct t_convert_table *t);
284 
285 void
287  struct t_hsv_filter_large_table *t);
288 
289 void
291  struct t_hsv_filter_optimized_table *t);
292 
293 static inline uint8_t
294 t_hsv_filter_sample(struct t_hsv_filter_optimized_table *t,
295  uint32_t y,
296  uint32_t u,
297  uint32_t v)
298 {
299  return t->v[y / T_HSV_STEP][u / T_HSV_STEP][v / T_HSV_STEP];
300 }
301 
302 int
304  struct t_hsv_filter_params *params,
305  struct xrt_frame_sink *sinks[4],
306  struct xrt_frame_sink **out_sink);
307 
308 
309 /*
310  *
311  * Tracker code.
312  *
313  */
314 
315 int
316 t_psmv_start(struct xrt_tracked_psmv *xtmv);
317 
318 int
319 t_psmv_create(struct xrt_frame_context *xfctx,
320  struct xrt_colour_rgb_f32 *rgb,
321  struct t_stereo_camera_calibration *data,
322  struct xrt_tracked_psmv **out_xtmv,
323  struct xrt_frame_sink **out_sink);
324 
325 int
326 t_psvr_start(struct xrt_tracked_psvr *xtvr);
327 
328 int
329 t_psvr_create(struct xrt_frame_context *xfctx,
330  struct t_stereo_camera_calibration *data,
331  struct xrt_tracked_psvr **out_xtvr,
332  struct xrt_frame_sink **out_sink);
333 
334 
335 /*
336  *
337  * Camera calibration
338  *
339  */
340 
341 /*!
342  * Board pattern type.
343  */
345 {
349 };
350 
352 {
353  //! Is calibration finished?
354  bool finished;
355  //! Was the target found this frame?
356  bool found;
357  //! Number of frames collected
359  //! Number of moving frames before another capture
360  int cooldown;
361  //! Number of non-moving frames before capture.
363  //! Stereo calibration data that was produced.
365 };
366 
368 {
369  //! Should we use fisheye version of the calibration functions.
371  //! Is the camera a stereo sbs camera, mostly for image loading.
373  //! What type of pattern are we using for calibration.
374  enum t_board_pattern pattern;
375 
376  struct
377  {
378  int cols;
379  int rows;
380  float size_meters;
381 
384  } checkers;
385 
386  struct
387  {
388  int cols;
389  int rows;
391  } circles;
392 
393  struct
394  {
395  int cols;
396  int rows;
398  } asymmetric_circles;
399 
400  struct
401  {
402  bool enabled;
404  } load;
405 
410 
411  /*!
412  * Should we mirror the RGB image?
413  *
414  * Before text is written out, has no effect on actual image capture.
415  */
417 
419 };
420 
421 /*!
422  * Sets the calibration parameters to the their default values.
423  */
424 static inline void
425 t_calibration_params_default(struct t_calibration_params *p)
426 {
427  // Camera config.
428  p->use_fisheye = false;
429  p->stereo_sbs = true;
430 
431  // Which board should we calibrate against.
433 
434  // Checker board.
435  p->checkers.cols = 9;
436  p->checkers.rows = 7;
437  p->checkers.size_meters = 0.025f;
438  p->checkers.subpixel_enable = true;
439  p->checkers.subpixel_size = 5;
440 
441  // Symmetrical circles.
442  p->circles.cols = 9;
443  p->circles.rows = 7;
444  p->circles.distance_meters = 0.025f;
445 
446  // Asymmetrical circles.
447  p->asymmetric_circles.cols = 5;
448  p->asymmetric_circles.rows = 17;
450 
451  // Loading of images.
452  p->load.enabled = false;
453  p->load.num_images = 20;
454 
455  // Frame collection info.
456  p->num_cooldown_frames = 20;
457  p->num_wait_for = 5;
458  p->num_collect_total = 20;
459  p->num_collect_restart = 1;
460 
461  // Misc.
462  p->mirror_rgb_image = false;
463  p->save_images = true;
464 }
465 
466 /*!
467  * @brief Create the camera calibration frame sink.
468  *
469  * @param xfctx Context for frame transport.
470  * @param params Parameters to use during calibration. Values copied, pointer
471  * not retained.
472  * @param status Optional pointer to structure for status information. Pointer
473  * retained, and pointed-to struct modified.
474  * @param gui Frame sink
475  * @param out_sink Output: created frame sink.
476  */
477 int
479  const struct t_calibration_params *params,
480  struct t_calibration_status *status,
481  struct xrt_frame_sink *gui,
482  struct xrt_frame_sink **out_sink);
483 
484 
485 /*
486  *
487  * Sink creation functions.
488  *
489  */
490 
491 int
493  struct xrt_frame_sink **out_sink);
494 
495 
496 
497 int
499  struct xrt_frame_sink *passthrough,
500  struct xrt_frame_sink **out_sink);
501 
502 int
504  struct xrt_frame_sink *passthrough,
505  struct xrt_frame_sink **out_sink);
506 
507 int
509  struct xrt_frame_sink *passthrough,
510  struct xrt_frame_sink **out_sink);
511 
512 /*!
513  * @}
514  */
515 
516 
517 #ifdef __cplusplus
518 }
519 #endif
int subpixel_size
Definition: t_tracking.h:383
uint8_t hue_min
Definition: t_tracking.h:252
int num_collect_restart
Definition: t_tracking.h:409
struct t_stereo_camera_calibration * stereo_data
Stereo calibration data that was produced.
Definition: t_tracking.h:364
int t_hsv_filter_create(struct xrt_frame_context *xfctx, struct t_hsv_filter_params *params, struct xrt_frame_sink *sinks[4], struct xrt_frame_sink **out_sink)
Definition: t_hsv_filter.c:339
int t_psmv_start(struct xrt_tracked_psmv *xtmv)
Definition: t_tracker_psmv.cpp:521
#define T_HSV_STEP
Definition: t_tracking.h:238
void t_hsv_build_large_table(struct t_hsv_filter_params *params, struct t_hsv_filter_large_table *t)
Definition: t_hsv_filter.c:62
double distortion[XRT_DISTORTION_MAX_DIM]
Rectilinear distortion coefficients: k1, k2, p1, p2[, k3[, k4, k5, k6[, s1, s2, s3, s4]].
Definition: t_tracking.h:99
struct t_calibration_params::@11 circles
t_board_pattern
Board pattern type.
Definition: t_tracking.h:344
uint8_t s_max
Definition: t_tracking.h:266
bool stereo_sbs
Is the camera a stereo sbs camera, mostly for image loading.
Definition: t_tracking.h:372
Essential calibration data for a single camera, or single lens/sensor of a stereo camera...
Definition: t_tracking.h:89
float distance_meters
Definition: t_tracking.h:390
bool mirror_rgb_image
Should we mirror the RGB image?
Definition: t_tracking.h:416
int t_convert_yuv_or_yuyv_create(struct xrt_frame_sink *next, struct xrt_frame_sink **out_sink)
int num_collected
Number of frames collected.
Definition: t_tracking.h:358
Definition: t_tracking.h:367
uint8_t hue_range
Definition: t_tracking.h:253
int t_debug_hsv_picker_create(struct xrt_frame_context *xfctx, struct xrt_frame_sink *passthrough, struct xrt_frame_sink **out_sink)
Definition: t_debug_hsv_picker.cpp:216
float diagonal_distance_meters
Definition: t_tracking.h:397
Definition: t_tracking.h:260
void t_convert_make_h8s8v8_to_r8g8b8(struct t_convert_table *t)
Definition: t_convert.cpp:57
int t_psvr_create(struct xrt_frame_context *xfctx, struct t_stereo_camera_calibration *data, struct xrt_tracked_psvr **out_xtvr, struct xrt_frame_sink **out_sink)
Definition: t_tracker_psvr.cpp:263
void t_hsv_build_convert_table(struct t_hsv_filter_params *params, struct t_convert_table *t)
Definition: t_hsv_filter.c:35
int t_debug_hsv_viewer_create(struct xrt_frame_context *xfctx, struct xrt_frame_sink *passthrough, struct xrt_frame_sink **out_sink)
Definition: t_debug_hsv_viewer.cpp:172
A object that is sent frames.
Definition: xrt_frame.h:51
float size_meters
Definition: t_tracking.h:380
int num_images
Definition: t_tracking.h:403
Definition: t_tracking.h:347
struct t_calibration_params::@10 checkers
Definition: t_tracking.h:271
uint8_t s_min
Definition: t_tracking.h:255
double distortion_fisheye[4]
Fisheye camera distortion coefficients.
Definition: t_tracking.h:102
bool t_stereo_camera_calibration_save_v1(FILE *calib_file, struct t_stereo_camera_calibration *data)
Save the given stereo calibration data to the given file.
Definition: t_file.cpp:268
int rows
Definition: t_tracking.h:379
Definition: t_tracking.h:250
bool enabled
Definition: t_tracking.h:402
int t_psvr_start(struct xrt_tracked_psvr *xtvr)
Definition: t_tracker_psvr.cpp:249
Stereo camera calibration data to be given to trackers.
Definition: t_tracking.h:111
uint8_t v[T_HSV_SIZE][T_HSV_SIZE][T_HSV_SIZE]
Definition: t_tracking.h:278
void t_convert_in_place_y8u8v8_to_r8g8b8(uint32_t width, uint32_t height, size_t stride, void *data_ptr)
Definition: t_convert.cpp:66
Image size.
Definition: xrt_defines.h:218
bool save_images
Definition: t_tracking.h:418
void t_stereo_camera_calibration_destroy(struct t_stereo_camera_calibration *c)
Only to be called by t_stereo_camera_calibration_reference.
Definition: t_data_utils.c:25
#define XRT_DISTORTION_MAX_DIM
Maximum size of rectilinear distortion coefficient array.
Definition: t_tracking.h:83
bool use_fisheye
Should we use fisheye version of the calibration functions.
Definition: t_tracking.h:370
int t_debug_hsv_filter_create(struct xrt_frame_context *xfctx, struct xrt_frame_sink *passthrough, struct xrt_frame_sink **out_sink)
Definition: t_debug_hsv_filter.cpp:101
Definition: t_tracking.h:276
struct t_calibration_params::@12 asymmetric_circles
bool found
Was the target found this frame?
Definition: t_tracking.h:356
double intrinsics[3][3]
Camera intrinsics matrix.
Definition: t_tracking.h:95
Definition: t_tracking.h:348
int num_wait_for
Definition: t_tracking.h:407
Object used to track all sinks and frame producers in a graph.
Definition: xrt_frame.h:87
Definition: t_tracking.h:195
void t_convert_fill_table(struct t_convert_table *t)
Definition: t_convert.cpp:22
struct t_calibration_params::@13 load
void t_convert_make_y8u8v8_to_r8g8b8(struct t_convert_table *t)
Definition: t_convert.cpp:39
enum t_board_pattern pattern
What type of pattern are we using for calibration.
Definition: t_tracking.h:374
Definition: t_tracking.h:351
uint8_t v_min
Definition: t_tracking.h:267
Data frame header.
bool use_fisheye
Is the camera fisheye?
Definition: t_tracking.h:105
int cols
Definition: t_tracking.h:378
int t_calibration_stereo_create(struct xrt_frame_context *xfctx, const struct t_calibration_params *params, struct t_calibration_status *status, struct xrt_frame_sink *gui, struct xrt_frame_sink **out_sink)
Create the camera calibration frame sink.
Definition: t_calibration.cpp:1241
A 3 element colour with floating point channels.
Definition: xrt_defines.h:193
void t_convert_in_place_y8u8v8_to_h8s8v8(uint32_t width, uint32_t height, size_t stride, void *data_ptr)
Definition: t_convert.cpp:76
A base class for reference counted objects.
Definition: xrt_defines.h:25
int num_cooldown_frames
Definition: t_tracking.h:406
A tracked PSVR headset.
Definition: xrt_tracking.h:147
bool t_stereo_camera_calibration_load_v1(FILE *calib_file, struct t_stereo_camera_calibration **out_data)
Load stereo calibration data from a given file.
Definition: t_file.cpp:187
Very small misc utils.
A single tracked PS Move controller, camera and ball are not synced.
Definition: xrt_tracking.h:105
void t_hsv_build_optimized_table(struct t_hsv_filter_params *params, struct t_hsv_filter_optimized_table *t)
Definition: t_hsv_filter.c:96
int cooldown
Number of moving frames before another capture.
Definition: t_tracking.h:360
int t_psmv_create(struct xrt_frame_context *xfctx, struct xrt_colour_rgb_f32 *rgb, struct t_stereo_camera_calibration *data, struct xrt_tracked_psmv **out_xtmv, struct xrt_frame_sink **out_sink)
Definition: t_tracker_psmv.cpp:528
int waits_remaining
Number of non-moving frames before capture.
Definition: t_tracking.h:362
void t_convert_make_y8u8v8_to_h8s8v8(struct t_convert_table *t)
Definition: t_convert.cpp:48
bool subpixel_enable
Definition: t_tracking.h:382
void t_stereo_camera_calibration_alloc(struct t_stereo_camera_calibration **calib)
Allocates a new stereo calibration data, unreferences the old calib.
Definition: t_data_utils.c:17
uint8_t v_min
Definition: t_tracking.h:257
void t_convert_in_place_h8s8v8_to_r8g8b8(uint32_t width, uint32_t height, size_t stride, void *data_ptr)
Definition: t_convert.cpp:88
struct xrt_size image_size_pixels
Source image size.
Definition: t_tracking.h:92
int num_collect_total
Definition: t_tracking.h:408
bool finished
Is calibration finished?
Definition: t_tracking.h:354
Definition: t_tracking.h:346
struct xrt_reference reference
Ref counting.
Definition: t_tracking.h:114
#define T_HSV_SIZE
Definition: t_tracking.h:237