LibMultiSense
LibMultiSense Documentation
Loading...
Searching...
No Matches
calibration_test.cc
Go to the documentation of this file.
1
37#include <gtest/gtest.h>
38
39#include <details/legacy/calibration.hh>
40
41using namespace multisense::legacy;
42
43crl::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
94multisense::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
159TEST(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
172TEST(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
179TEST(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
186TEST(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
193TEST(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
211TEST(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);
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
228TEST(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
243TEST(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
257TEST(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,
266 DataSource::LEFT_MONO_COMPRESSED,
267 DataSource::LEFT_RECTIFIED_RAW,
268 DataSource::LEFT_RECTIFIED_COMPRESSED,
269 DataSource::LEFT_DISPARITY_RAW,
270 DataSource::LEFT_DISPARITY_COMPRESSED,
271 DataSource::COST_RAW};
272
273 const auto right_sources = {DataSource::RIGHT_MONO_RAW,
274 DataSource::RIGHT_MONO_COMPRESSED,
275 DataSource::RIGHT_RECTIFIED_RAW,
276 DataSource::RIGHT_RECTIFIED_COMPRESSED};
277
278 const auto aux_sources = {DataSource::AUX_COMPRESSED,
279 DataSource::AUX_RECTIFIED_COMPRESSED,
280 DataSource::AUX_LUMA_RAW,
281 DataSource::AUX_LUMA_RECTIFIED_RAW,
282 DataSource::AUX_CHROMA_RAW,
283 DataSource::AUX_CHROMA_RECTIFIED_RAW};
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
304TEST(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,
313 DataSource::LEFT_MONO_COMPRESSED,
314 DataSource::LEFT_RECTIFIED_RAW,
315 DataSource::LEFT_RECTIFIED_COMPRESSED,
316 DataSource::LEFT_DISPARITY_RAW,
317 DataSource::LEFT_DISPARITY_COMPRESSED,
318 DataSource::COST_RAW};
319
320 const auto right_sources = {DataSource::RIGHT_MONO_RAW,
321 DataSource::RIGHT_MONO_COMPRESSED,
322 DataSource::RIGHT_RECTIFIED_RAW,
323 DataSource::RIGHT_RECTIFIED_COMPRESSED};
324
325 const auto aux_sources = {DataSource::AUX_COMPRESSED,
326 DataSource::AUX_RECTIFIED_COMPRESSED,
327 DataSource::AUX_LUMA_RAW,
328 DataSource::AUX_LUMA_RECTIFIED_RAW,
329 DataSource::AUX_CHROMA_RAW,
330 DataSource::AUX_CHROMA_RECTIFIED_RAW};
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
350TEST(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
358TEST(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
365TEST(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
379TEST(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
392TEST(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
406TEST(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::CameraCalibration create_valid_cal(float fx, float fy, float cx, float cy, float tx)
crl::multisense::details::wire::CameraCalData create_invalid_wire_cal()
TEST(is_valid, invalid)
crl::multisense::details::wire::CameraCalData create_valid_wire_cal(float fx, float fy, float cx, float cy, float tx)
void check_equal(const crl::multisense::details::wire::CameraCalData &wire, const multisense::CameraCalibration &cal)
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...
std::array< std::array< float, 3 >, 3 > K
Unrectified camera projection matrix stored in row-major ordering.
DistortionType distortion_type
The type of the distortion model used for the unrectified camera.
std::vector< float > D
Coefficients for the distortion model.
std::array< std::array< float, 4 >, 3 > P
Rectified projection matrix which takes points in the origin camera coordinate frame and projects the...