LibMultiSense
LibMultiSense Documentation
calibration_test.cc
Go to the documentation of this file.
1 
37 #include <gtest/gtest.h>
38 
39 #include <details/legacy/calibration.hh>
40 
41 using namespace multisense::legacy;
42 
43 crl::multisense::details::wire::CameraCalData create_valid_wire_cal(float fx, float fy, float cx, float cy, float tx)
44 {
45  using namespace crl::multisense::details;
46 
48  memset(&cal.M[0][0], 0, sizeof(float) * 9);
49  memset(&cal.R[0][0], 0, sizeof(float) * 9);
50  memset(&cal.P[0][0], 0, sizeof(float) * 12);
51  memset(&cal.D[0], 0, sizeof(float) * 8);
52 
53  cal.M[0][0] = fx;
54  cal.M[0][2] = cx;
55  cal.M[1][1] = fy;
56  cal.M[1][2] = cy;
57  cal.M[2][2] = 1.0;
58 
59  cal.R[0][0] = 1.0;
60  cal.R[1][1] = 1.0;
61  cal.R[2][2] = 1.0;
62 
63  cal.D[0] = -1.0;
64  cal.D[1] = 0.1;
65  cal.D[2] = -0.02;
66  cal.D[3] = 2.0;
67  cal.D[5] = -3.0;
68  cal.D[6] = 3.0;
69  cal.D[7] = -3.0;
70 
71  cal.P[0][0] = fx;
72  cal.P[0][2] = cx;
73  cal.P[0][2] = fx * tx;
74  cal.P[1][1] = fy;
75  cal.P[1][2] = cy;
76  cal.P[2][2] = 1.0;
77 
78  return cal;
79 }
80 
82 {
83  using namespace crl::multisense::details;
84 
86  memset(&cal.M[0][0], 0, sizeof(float) * 9);
87  memset(&cal.R[0][0], 0, sizeof(float) * 9);
88  memset(&cal.P[0][0], 0, sizeof(float) * 12);
89  memset(&cal.D[0], 0, sizeof(float) * 8);
90 
91  return cal;
92 }
93 
94 multisense::CameraCalibration create_valid_cal(float fx, float fy, float cx, float cy, float tx)
95 {
97 
98  cal.K = {{{fx, 0.0, cx}, {0.0, fy, cy}, {0.0, 0.0, 1.0}}};
99  cal.R = {{{1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}}};
100  cal.P = {{{fx, 0.0, cx, fx * tx}, {0.0, fy, cy, 0.0}, {0.0, 0.0, 1.0, 0.0}}};
101 
103  cal.D = {1.0, 0.1, 0.2, 0.3, 0.4, 5.1, 6.2, 7.3};
104 
105  return cal;
106 }
107 
109 {
110  for (size_t h = 0 ; h < 3 ; ++h)
111  {
112  for (size_t w = 0 ; w < 3 ; ++w)
113  {
114  ASSERT_FLOAT_EQ(wire.M[h][w], cal.K[h][w]);
115  ASSERT_FLOAT_EQ(wire.R[h][w], cal.R[h][w]);
116  }
117  }
118 
119  for (size_t h = 0 ; h < 3 ; ++h)
120  {
121  for (size_t w = 0 ; w < 4 ; ++w)
122  {
123  ASSERT_FLOAT_EQ(wire.P[h][w], cal.P[h][w]);
124  }
125  }
126 
127  for (size_t i = 0 ; i < cal.D.size() ; ++i)
128  {
129  ASSERT_FLOAT_EQ(wire.D[i], cal.D[i]);
130  }
131 }
132 
134 {
135  for (size_t h = 0 ; h < 3 ; ++h)
136  {
137  for (size_t w = 0 ; w < 3 ; ++w)
138  {
139  ASSERT_FLOAT_EQ(lhs.K[h][w], rhs.K[h][w]);
140  ASSERT_FLOAT_EQ(lhs.R[h][w], rhs.R[h][w]);
141  }
142  }
143 
144  for (size_t h = 0 ; h < 3 ; ++h)
145  {
146  for (size_t w = 0 ; w < 4 ; ++w)
147  {
148  ASSERT_FLOAT_EQ(lhs.P[h][w], rhs.P[h][w]);
149  }
150  }
151 
152  for (size_t i = 0 ; i < rhs.D.size() ; ++i)
153  {
154  ASSERT_FLOAT_EQ(lhs.D[i], rhs.D[i]);
155  }
156 }
157 
158 
159 TEST(is_valid, invalid)
160 {
161  using namespace crl::multisense::details;
162 
164  memset(cal.M, 0, sizeof(float) * 9);
165  memset(cal.D, 0, sizeof(float) * 8);
166  memset(cal.R, 0, sizeof(float) * 9);
167  memset(cal.P, 0, sizeof(float) * 12);
168 
169  ASSERT_FALSE(is_valid(cal));
170 }
171 
172 TEST(is_valid, valid)
173 {
174  using namespace crl::multisense::details;
175 
176  ASSERT_TRUE(is_valid(create_valid_wire_cal(800.0, 800.0, 400.0, 200.0, 0.2)));
177 }
178 
179 TEST(convert, cal_to_wire)
180 {
181  const auto cal = create_valid_cal(800.0, 800.0, 400.0, 200.0, -0.2);
182 
183  check_equal(convert(cal), cal);
184 }
185 
186 TEST(convert, wire_to_cal)
187 {
188  const auto cal = create_valid_wire_cal(800.0, 800.0, 400.0, 200.0, -0.2);
189 
190  check_equal(cal, convert(cal));
191 }
192 
193 TEST(convert, wire_to_stereo_valid_axu)
194 {
195  using namespace crl::multisense::details;
196 
198  wire.left = create_valid_wire_cal(800.0, 8001.0, 300.0, 200.0, -0.2);
199  wire.right = create_valid_wire_cal(801.0, 8001.0, 300.0, 200.0, -0.2);
200  wire.aux = create_valid_wire_cal(802.0, 8001.0, 300.0, 200.0, -0.2);
201 
202  auto stereo = convert(wire);
203 
204  check_equal(wire.left, stereo.left);
205  check_equal(wire.right, stereo.right);
206 
207  ASSERT_TRUE(static_cast<bool>(stereo.aux));
208  check_equal(wire.aux, stereo.aux.value());
209 }
210 
211 TEST(convert, wire_to_stereo_invalid_axu)
212 {
213  using namespace crl::multisense::details;
214 
216  wire.left = create_valid_wire_cal(800.0, 8001.0, 300.0, 200.0, -0.2);
217  wire.right = create_valid_wire_cal(801.0, 8001.0, 300.0, 200.0, -0.2);
218  wire.aux = create_invalid_wire_cal();
219 
220  auto stereo = convert(wire);
221 
222  check_equal(wire.left, stereo.left);
223  check_equal(wire.right, stereo.right);
224 
225  ASSERT_FALSE(static_cast<bool>(stereo.aux));
226 }
227 
228 TEST(convert, stereo_to_wire_valid_axu)
229 {
230  using namespace crl::multisense::details;
231 
232  const multisense::StereoCalibration cal{create_valid_cal(800.0, 8001.0, 300.0, 200.0, -0.2),
233  create_valid_cal(801.0, 8001.0, 300.0, 200.0, -0.2),
234  create_valid_cal(802.0, 8001.0, 300.0, 200.0, -0.2)};
235 
236  auto wire = convert(cal);
237 
238  check_equal(wire.left, cal.left);
239  check_equal(wire.right, cal.right);
240  check_equal(wire.aux, cal.aux.value());
241 }
242 
243 TEST(convert, stereo_to_wire_invalid_aux)
244 {
245  using namespace crl::multisense::details;
246 
247  const multisense::StereoCalibration cal{create_valid_cal(800.0, 8001.0, 300.0, 200.0, -0.2),
248  create_valid_cal(801.0, 8001.0, 300.0, 200.0, -0.2),
249  std::nullopt};
250 
251  auto wire = convert(cal);
252 
253  check_equal(wire.left, cal.left);
254  check_equal(wire.right, cal.right);
255 }
256 
257 TEST(convert, select_calibration_valid_aux)
258 {
259  using namespace multisense;
260 
261  const multisense::StereoCalibration cal{create_valid_cal(800.0, 8001.0, 300.0, 200.0, -0.2),
262  create_valid_cal(801.0, 8001.0, 300.0, 200.0, -0.2),
263  create_valid_cal(802.0, 8001.0, 300.0, 200.0, -0.2)};
264 
265  const auto left_sources = {DataSource::LEFT_MONO_RAW,
272 
273  const auto right_sources = {DataSource::RIGHT_MONO_RAW,
277 
278  const auto aux_sources = {DataSource::AUX_COMPRESSED,
284 
285  for (const auto &left: left_sources)
286  {
287  const auto cam_cal = select_calibration(cal, left);
288  check_equal(cam_cal, cal.left);
289  }
290 
291  for (const auto &right: right_sources)
292  {
293  const auto cam_cal = select_calibration(cal, right);
294  check_equal(cam_cal, cal.right);
295  }
296 
297  for (const auto &aux: aux_sources)
298  {
299  const auto cam_cal = select_calibration(cal, aux);
300  check_equal(cam_cal, cal.aux.value());
301  }
302 }
303 
304 TEST(convert, select_calibration_invalid_aux)
305 {
306  using namespace multisense;
307 
308  const multisense::StereoCalibration cal{create_valid_cal(800.0, 8001.0, 300.0, 200.0, -0.2),
309  create_valid_cal(801.0, 8001.0, 300.0, 200.0, -0.2),
310  std::nullopt};
311 
312  const auto left_sources = {DataSource::LEFT_MONO_RAW,
319 
320  const auto right_sources = {DataSource::RIGHT_MONO_RAW,
324 
325  const auto aux_sources = {DataSource::AUX_COMPRESSED,
331 
332  for (const auto &left: left_sources)
333  {
334  const auto cam_cal = select_calibration(cal, left);
335  check_equal(cam_cal, cal.left);
336  }
337 
338  for (const auto &right: right_sources)
339  {
340  const auto cam_cal = select_calibration(cal, right);
341  check_equal(cam_cal, cal.right);
342  }
343 
344  for (const auto &aux: aux_sources)
345  {
346  ASSERT_THROW(select_calibration(cal, aux), std::exception);
347  }
348 }
349 
350 TEST(scale_calibration, scale)
351 {
352  const auto cal = create_valid_cal(800.0, 8001.0, 300.0, 200.0, -0.2);
353  const auto scaled = scale_calibration(cal, 0.1, 0.2);
354 
355  check_equal(scaled, create_valid_cal(80.0, 1600.2, 30.0, 40.0, -0.2));
356 }
357 
358 TEST(scale_calibration, round_trip)
359 {
360  const auto cal = create_valid_cal(800.0, 8001.0, 300.0, 200.0, -0.2);
361 
362  check_equal(cal, scale_calibration(scale_calibration(cal, 0.25, 0.1), 4.0, 10.0));
363 }
364 
365 TEST(scale_calibration, scale_valid_aux)
366 {
367  const multisense::StereoCalibration cal{create_valid_cal(800.0, 8001.0, 300.0, 200.0, -0.2),
368  create_valid_cal(801.0, 8001.0, 300.0, 200.0, -0.2),
369  create_valid_cal(802.0, 8001.0, 300.0, 200.0, -0.2)};
370 
371  const auto scaled = scale_calibration(cal, 0.1, 0.2);
372 
373  check_equal(scaled.left, create_valid_cal(80.0, 1600.2, 30.0, 40.0, -0.2));
374  check_equal(scaled.right, create_valid_cal(80.1, 1600.2, 30.0, 40.0, -0.2));
375  ASSERT_TRUE(static_cast<bool>(scaled.aux));
376  check_equal(scaled.aux.value(), create_valid_cal(80.2, 1600.2, 30.0, 40.0, -0.2));
377 }
378 
379 TEST(scale_calibration, round_trip_valid_aux)
380 {
381  const multisense::StereoCalibration cal{create_valid_cal(800.0, 8001.0, 300.0, 200.0, -0.2),
382  create_valid_cal(801.0, 8001.0, 300.0, 200.0, -0.2),
383  std::nullopt};
384 
385  const auto scaled = scale_calibration(cal, 0.1, 0.2);
386 
387  check_equal(scaled.left, create_valid_cal(80.0, 1600.2, 30.0, 40.0, -0.2));
388  check_equal(scaled.right, create_valid_cal(80.1, 1600.2, 30.0, 40.0, -0.2));
389  ASSERT_FALSE(static_cast<bool>(scaled.aux));
390 }
391 
392 TEST(scale_calibration, scale_invalid_aux)
393 {
394  const multisense::StereoCalibration cal{create_valid_cal(800.0, 8001.0, 300.0, 200.0, -0.2),
395  create_valid_cal(801.0, 8001.0, 300.0, 200.0, -0.2),
396  create_valid_cal(802.0, 8001.0, 300.0, 200.0, -0.2)};
397 
398  const auto round_trip = scale_calibration(scale_calibration(cal, 0.1, 0.2), 10.0, 5.0);
399 
400  check_equal(round_trip.left, cal.left);
401  check_equal(round_trip.right, cal.right);
402  ASSERT_TRUE(static_cast<bool>(round_trip.aux));
403  check_equal(round_trip.aux.value(), cal.aux.value());
404 }
405 
406 TEST(scale_calibration, round_trip_invalid_aux)
407 {
408  const multisense::StereoCalibration cal{create_valid_cal(800.0, 8001.0, 300.0, 200.0, -0.2),
409  create_valid_cal(801.0, 8001.0, 300.0, 200.0, -0.2),
410  std::nullopt};
411 
412  const auto round_trip = scale_calibration(scale_calibration(cal, 0.1, 0.2), 10.0, 5.0);
413 
414  check_equal(round_trip.left, cal.left);
415  check_equal(round_trip.right, cal.right);
416  ASSERT_FALSE(static_cast<bool>(round_trip.aux));
417 }
multisense::DataSource::RIGHT_RECTIFIED_COMPRESSED
@ RIGHT_RECTIFIED_COMPRESSED
multisense::DataSource::RIGHT_MONO_COMPRESSED
@ RIGHT_MONO_COMPRESSED
crl::multisense::details
Definition: BufferStream.hh:53
crl::multisense::details::wire::SysCameraCalibration::aux
CameraCalData aux
Definition: SysCameraCalibrationMessage.hh:77
check_equal
void check_equal(const crl::multisense::details::wire::CameraCalData &wire, const multisense::CameraCalibration &cal)
Definition: calibration_test.cc:108
multisense::CameraCalibration::distortion_type
DistortionType distortion_type
The type of the distortion model used for the unrectified camera.
Definition: MultiSenseTypes.hh:147
multisense::CameraCalibration::D
std::vector< float > D
Coefficients for the distortion model.
Definition: MultiSenseTypes.hh:152
multisense::DataSource::AUX_COMPRESSED
@ AUX_COMPRESSED
create_valid_cal
multisense::CameraCalibration create_valid_cal(float fx, float fy, float cx, float cy, float tx)
Definition: calibration_test.cc:94
multisense::DataSource::LEFT_RECTIFIED_RAW
@ LEFT_RECTIFIED_RAW
multisense::DataSource::AUX_LUMA_RAW
@ AUX_LUMA_RAW
crl::multisense::details::wire::CameraCalData::R
float R[3][3]
Definition: SysCameraCalibrationMessage.hh:55
crl::multisense::details::wire::CameraCalData::D
float D[8]
Definition: SysCameraCalibrationMessage.hh:54
multisense::DataSource::LEFT_DISPARITY_COMPRESSED
@ LEFT_DISPARITY_COMPRESSED
multisense::DataSource::AUX_LUMA_RECTIFIED_RAW
@ AUX_LUMA_RECTIFIED_RAW
multisense::DataSource::RIGHT_MONO_RAW
@ RIGHT_MONO_RAW
multisense::DataSource::LEFT_MONO_RAW
@ LEFT_MONO_RAW
crl::multisense::details::wire::CameraCalData::M
float M[3][3]
Definition: SysCameraCalibrationMessage.hh:53
crl::multisense::details::wire::CameraCalData::P
float P[3][4]
Definition: SysCameraCalibrationMessage.hh:56
multisense::DataSource::COST_RAW
@ COST_RAW
multisense::StereoCalibration
Definition: MultiSenseTypes.hh:166
multisense::DataSource::LEFT_MONO_COMPRESSED
@ LEFT_MONO_COMPRESSED
multisense::CameraCalibration::R
std::array< std::array< float, 3 >, 3 > R
Rotation matrix which takes points in the unrectified camera frame and transform them in to the recti...
Definition: MultiSenseTypes.hh:136
multisense::DataSource::AUX_CHROMA_RECTIFIED_RAW
@ AUX_CHROMA_RECTIFIED_RAW
crl::multisense::details::wire::SysCameraCalibration::right
CameraCalData right
Definition: SysCameraCalibrationMessage.hh:76
multisense
Definition: MultiSenseChannel.hh:44
create_invalid_wire_cal
crl::multisense::details::wire::CameraCalData create_invalid_wire_cal()
Definition: calibration_test.cc:81
multisense::DataSource::RIGHT_RECTIFIED_RAW
@ RIGHT_RECTIFIED_RAW
multisense::DataSource::AUX_CHROMA_RAW
@ AUX_CHROMA_RAW
crl::multisense::details::wire::CameraCalData
Definition: SysCameraCalibrationMessage.hh:49
multisense::DataSource::AUX_RECTIFIED_COMPRESSED
@ AUX_RECTIFIED_COMPRESSED
multisense::CameraCalibration
Definition: MultiSenseTypes.hh:115
crl::multisense::details::wire::SysCameraCalibration
Definition: SysCameraCalibrationMessage.hh:70
multisense::CameraCalibration::DistortionType::RATIONAL_POLYNOMIAL
@ RATIONAL_POLYNOMIAL
TEST
TEST(is_valid, invalid)
Definition: calibration_test.cc:159
multisense::CameraCalibration::K
std::array< std::array< float, 3 >, 3 > K
Unrectified camera projection matrix stored in row-major ordering.
Definition: MultiSenseTypes.hh:130
multisense::CameraCalibration::P
std::array< std::array< float, 4 >, 3 > P
Rectified projection matrix which takes points in the origin camera coordinate frame and projects the...
Definition: MultiSenseTypes.hh:142
create_valid_wire_cal
crl::multisense::details::wire::CameraCalData create_valid_wire_cal(float fx, float fy, float cx, float cy, float tx)
Definition: calibration_test.cc:43
crl::multisense::details::wire::SysCameraCalibration::left
CameraCalData left
Definition: SysCameraCalibrationMessage.hh:75
multisense::DataSource::LEFT_RECTIFIED_COMPRESSED
@ LEFT_RECTIFIED_COMPRESSED
multisense::DataSource::LEFT_DISPARITY_RAW
@ LEFT_DISPARITY_RAW