···11-// Copyright 2019-2021, Collabora, Ltd.
11+// Copyright 2019-2023, Collabora, Ltd.
22// SPDX-License-Identifier: BSL-1.0
33/*!
44 * @file
···66 * @author Pete Black <pblack@collabora.com>
77 * @author Jakob Bornecrantz <jakob@collabora.com>
88 * @author Ryan Pavlik <ryan.pavlik@collabora.com>
99+ * @author Moses Turner <moses@collabora.com>
910 * @ingroup aux_tracking
1011 */
1112···5253#define XRT_DISTORTION_MAX_DIM (14)
53545455/*!
5656+ * @brief The distortion model this camera calibration falls under.
5757+ * @todo Add RiftS's Fisheye62 to this enumerator once we have native support for it in our hand tracking and SLAM.
5858+ * @todo Feel free to add support for T_DISTORTION_OPENCV_RADTAN_4 or T_DISTORTION_OPENCV_RADTAN_12 whenever you have a
5959+ * camera that uses those.
6060+ */
6161+enum t_camera_distortion_model
6262+{
6363+ /*!
6464+ * OpenCV's radial-tangential distortion model. Exactly equivalent to the distortion model from OpenCV's calib3d
6565+ * module with just the first five parameters. This may be reinterpreted as RT8 with the last three parameters
6666+ * zeroed out, which is 100% valid and results in exactly equivalent (un)projections.
6767+ *
6868+ * Parameters:
6969+ *
7070+ * \f[(k_1, k_2, p_1, p_2, k_3)\f]
7171+ */
7272+ T_DISTORTION_OPENCV_RADTAN_5,
7373+7474+ /*!
7575+ * OpenCV's radial-tangential distortion model. Exactly equivalent to the distortion model from OpenCV's calib3d
7676+ * module, with just the first 8 parameters.
7777+ * Parameters:
7878+ *
7979+ * \f[(k_1, k_2, p_1, p_2, k_3, k_4, k_5, k_6)\f]
8080+ */
8181+ T_DISTORTION_OPENCV_RADTAN_8,
8282+8383+ /*!
8484+ * OpenCV's radial-tangential distortion model. Exactly equivalent to the distortion model from OpenCV's calib3d
8585+ * module, with all 14 parameters.
8686+ *
8787+ * In practice this is reinterpreted as RT8 because the last 6 parameters are almost always approximately 0.
8888+ *
8989+ * @todo Feel free to implement RT14 (un)projection functions if you have a camera that actually has a tilted
9090+ * sensor.
9191+ *
9292+ * Parameters:
9393+ *
9494+ * \f[(k_1, k_2, p_1, p_2, k_3, k_4, k_5, k_6, s_1, s_2, s_3, s_4, \tau_x, \tau_y)\f]
9595+ *
9696+ * All known factory-calibrated Luxonis cameras use this distortion model, and in all known cases their last 6
9797+ * parameters are approximately 0.
9898+ *
9999+ */
100100+ T_DISTORTION_OPENCV_RADTAN_14,
101101+102102+ /*!
103103+ * Juho Kannalla and Sami Sebastian Brandt's fisheye distortion model. Exactly equivalent to the distortion
104104+ * model from OpenCV's calib3d/fisheye module.
105105+ *
106106+ * Parameters:
107107+ *
108108+ * \f[(k_1, k_2, k_3, k_4)\f]
109109+ *
110110+ * Many cameras use this model. Here's a non-exhaustive list of cameras Monado knows about that fall under this
111111+ * model:
112112+ * * Intel T265
113113+ * * Valve Index
114114+ */
115115+ T_DISTORTION_FISHEYE_KB4,
116116+117117+ /*!
118118+ * Windows Mixed Reality headsets' camera model.
119119+ *
120120+ * The model is listed as CALIBRATION_LensDistortionModelRational6KT in the WMR json files, which seems to be
121121+ * equivalent to Azure-Kinect-Sensor-SDK's K4A_CALIBRATION_LENS_DISTORTION_MODEL_RATIONAL_6KT.
122122+ *
123123+ * The only difference between this model and RT8 are codx, cody, and the way p1 and p2 are interpreted. In
124124+ * practice we reinterpret this as RT8 because those values are almost always approximately 0 for WMR headsets.
125125+ *
126126+ * Parameters:
127127+ *
128128+ * \f[(k_1, k_2, p_1, p_2, k_3, k_4, k_5, k_6, cod_x, cod_y, rpmax)\f]
129129+ */
130130+ T_DISTORTION_WMR,
131131+};
132132+133133+134134+/*!
135135+ * Stringifies a @ref enum t_camera_distortion_model
136136+ * @param model The distortion model to be stringified
137137+ * @return The distortion model as a string
138138+ */
139139+static inline const char *
140140+t_stringify_camera_distortion_model(const enum t_camera_distortion_model model)
141141+{
142142+ switch (model) {
143143+ case T_DISTORTION_OPENCV_RADTAN_5: return "T_DISTORTION_OPENCV_RADTAN_5"; break;
144144+ case T_DISTORTION_OPENCV_RADTAN_8: return "T_DISTORTION_OPENCV_RADTAN_8"; break;
145145+ case T_DISTORTION_OPENCV_RADTAN_14: return "T_DISTORTION_OPENCV_RADTAN_14"; break;
146146+ case T_DISTORTION_WMR: return "T_DISTORTION_WMR"; break;
147147+ case T_DISTORTION_FISHEYE_KB4: return "T_DISTORTION_FISHEYE_KB4"; break;
148148+ default: U_LOG_E("Invalid distortion_model! %d", model); return "INVALID";
149149+ }
150150+}
151151+152152+/*!
153153+ * Returns the number of parameters needed for this @ref enum t_camera_distortion_model to be held by an OpenCV Mat and
154154+ * correctly interpreted by OpenCV's (un)projection functions.
155155+ *
156156+ * @param model The distortion model in question
157157+ * @return The number of distortion coefficients, or 0 if this model cannot be represented inside OpenCV.
158158+ */
159159+static inline size_t
160160+t_num_params_from_distortion_model(const enum t_camera_distortion_model model)
161161+{
162162+ switch (model) {
163163+ case T_DISTORTION_OPENCV_RADTAN_5: return 5; break;
164164+ case T_DISTORTION_OPENCV_RADTAN_8: return 8; break;
165165+ case T_DISTORTION_OPENCV_RADTAN_14: return 14; break;
166166+ case T_DISTORTION_WMR: return 11; break;
167167+ case T_DISTORTION_FISHEYE_KB4: return 4; break;
168168+ default: U_LOG_E("Invalid distortion_model! %d", model); return 0;
169169+ }
170170+}
171171+172172+/*!
173173+ * Parameters for @ref T_DISTORTION_OPENCV_RADTAN_5
174174+ * @ingroup aux_tracking
175175+ */
176176+struct t_camera_calibration_rt5_params
177177+{
178178+ double k1, k2, p1, p2, k3;
179179+};
180180+181181+/*!
182182+ * Parameters for @ref T_DISTORTION_OPENCV_RADTAN_8
183183+ * @ingroup aux_tracking
184184+ */
185185+struct t_camera_calibration_rt8_params
186186+{
187187+ double k1, k2, p1, p2, k3, k4, k5, k6;
188188+};
189189+190190+/*!
191191+ * Parameters for @ref T_DISTORTION_OPENCV_RADTAN_14
192192+ * @ingroup aux_tracking
193193+ */
194194+struct t_camera_calibration_rt14_params
195195+{
196196+ double k1, k2, p1, p2, k3, k4, k5, k6, s1, s2, s3, s4, tx, ty;
197197+};
198198+199199+/*!
200200+ * Parameters for @ref T_DISTORTION_FISHEYE_KB4
201201+ * @ingroup aux_tracking
202202+ */
203203+struct t_camera_calibration_kb4_params
204204+{
205205+ double k1, k2, k3, k4;
206206+};
207207+208208+/*!
209209+ * Parameters for @ref T_DISTORTION_WMR
210210+ * @ingroup aux_tracking
211211+ */
212212+struct t_camera_calibration_wmr_params
213213+{
214214+ double k1, k2, p1, p2, k3, k4, k5, k6, codx, cody, rpmax;
215215+};
216216+217217+/*!
55218 * @brief Essential calibration data for a single camera, or single lens/sensor
56219 * of a stereo camera.
57220 */
···63226 //! Camera intrinsics matrix
64227 double intrinsics[3][3];
652286666- //! Number of distortion parameters (non-fisheye).
6767- size_t distortion_num;
229229+ union {
230230+ struct t_camera_calibration_rt5_params rt5;
231231+ struct t_camera_calibration_rt8_params rt8;
232232+ struct t_camera_calibration_rt14_params rt14;
233233+ struct t_camera_calibration_kb4_params kb4;
234234+ struct t_camera_calibration_wmr_params wmr;
235235+ double distortion_parameters_as_array[XRT_DISTORTION_MAX_DIM];
236236+ };
682376969- //! Rectilinear distortion coefficients: k1, k2, p1, p2[, k3[, k4, k5, k6[, s1, s2, s3, s4[, Tx, Ty]]]]
7070- double distortion[XRT_DISTORTION_MAX_DIM];
7171-7272- //! Fisheye camera distortion coefficients
7373- double distortion_fisheye[4];
742387575- //! Is the camera fisheye?
7676- bool use_fisheye;
239239+ //! Distortion model that this camera uses.
240240+ enum t_camera_distortion_model distortion_model;
77241};
7824279243/*!
···101265/*!
102266 * Allocates a new stereo calibration data, unreferences the old data pointed to by @p out_c.
103267 *
104104- * Also initializes t_camera_calibration::distortion_num in t_stereo_camera_calibration::view, only 5 and 14 is
105105- * accepted.
106106- *
107268 * @public @memberof t_stereo_camera_calibration
108269 */
109270void
110110-t_stereo_camera_calibration_alloc(struct t_stereo_camera_calibration **out_c, uint32_t distortion_num);
271271+t_stereo_camera_calibration_alloc(struct t_stereo_camera_calibration **out_c,
272272+ const enum t_camera_distortion_model distortion_model);
111273112274/*!
113275 * Only to be called by @p t_stereo_camera_calibration_reference.
···452614 {
453615 double frequency; //!< Camera FPS
454616 struct xrt_matrix_4x4 T_imu_cam; //!< Transform IMU to camera. Column major.
455455- float rpmax; //!< Used for rt8 calibrations. Rpmax or "metric_radius" property.
456617 } cams[2];
457618};
458619