1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
// Copyright (c) 2012-2017 VideoStitch SAS
// Copyright (c) 2018 stitchEm
#pragma once
#include <array>
#include <memory>
#include <Eigen/Dense>
#include "libvideostitch/config.hpp"
#include "libvideostitch/inputDef.hpp"
#include "boundedValue.hpp"
namespace VideoStitch {
namespace Core {
class GeometryDefinition;
class RigCameraDefinition;
} // namespace Core
namespace Calibration {
/**
Used to simulate a rig's camera.
*/
class VS_EXPORT Camera {
public:
Camera();
virtual ~Camera();
virtual Camera* clone() const = 0;
/**
@brief Setup camera instance using parameters from a camera rigcamera definition.
@note These parameters will be transformed to optimize computations
@param rigcamdef input camera definition
*/
void setupWithRigCameraDefinition(Core::RigCameraDefinition& rigcamdef);
/**
@brief Effectively lift a point on the sphere of radius sphereScale in the reference frame
@param refpt the result lifted point
@param Jhfocal jacobian of the function wrt horizontal focal
@param Jvfocal jacobian of the function wrt vertical focal
@param Jhcenter jacobian of the function wrt horizontal center
@param Jvcenter jacobian of the function wrt vertical center
@param JdistortA jacobian of the function wrt distortion param A
@param JdistortB jacobian of the function wrt distortion param B
@param JdistortC jacobian of the function wrt distortion param C
@param Jrotation jacobian of the function wrt rotation params
@param JtX jacobian of the function wrt translation X param
@param JtY jacobian of the function wrt translation Y param
@param JtZ jacobian of the function wrt translation Z param
@param impt the input image point
@param sphereScale the sphere radius in the reference frame
@return false if some numerical problem happened
*/
bool lift(Eigen::Vector3d& refpt, Eigen::Matrix<double, 3, 4>& Jhfocal, Eigen::Matrix<double, 3, 4>& Jvfocal,
Eigen::Matrix<double, 3, 4>& Jhcenter, Eigen::Matrix<double, 3, 4>& Jvcenter,
Eigen::Matrix<double, 3, 4>& JdistortA, Eigen::Matrix<double, 3, 4>& JdistortB,
Eigen::Matrix<double, 3, 4>& JdistortC, Eigen::Matrix<double, 3, 9>& Jrotation,
Eigen::Matrix<double, 3, 4>& JtX, Eigen::Matrix<double, 3, 4>& JtY, Eigen::Matrix<double, 3, 4>& JtZ,
const Eigen::Vector2d& impt, const double sphereScale);
/**
@brief Effectively lift a point on the sphere of radius sphereScale in the reference frame
@param refpt the result lifted point
@param impt the input image point
@param sphereScale the sphere radius in the reference frame
@return false if some numerical problem happened
*/
bool lift(Eigen::Vector3d& refpt, const Eigen::Vector2d& impt, const double sphereScale);
/**
@brief Effectively lift a point on the unit sphere in the camera frame
@param campt the result lifted point
@param impt the input image point
@return false if some numerical problem happened
*/
bool quicklift(Eigen::Vector3d& campt, const Eigen::Vector2d& impt);
/**
@brief Project a point on the unit sphere in the reference space into the camera plane
@param impt_pixels the result projected point
@param Jpoint jacobian of the function wrt source point
@param Jhfocal jacobian of the function wrt horizontal focal
@param Jvfocal jacobian of the function wrt vertical focal
@param Jhcenter jacobian of the function wrt horizontal center
@param Jvcenter jacobian of the function wrt vertical center
@param JdistortA jacobian of the function wrt lens distortion param A
@param JdistortB jacobian of the function wrt lens distortion param B
@param JdistortC jacobian of the function wrt lens distortion param C
@param Jrotation jacobian of the function wrt rotation params
@param JtX jacobian of the function wrt translation X param
@param JtY jacobian of the function wrt translation Y param
@param JtZ jacobian of the function wrt translation Z param
@param refpt the input point in the reference space
@return false if some numerical problem happened
*/
bool project(Eigen::Vector2d& impt_pixels, Eigen::Matrix<double, 2, 3>& Jpoint, Eigen::Matrix<double, 2, 4>& Jhfocal,
Eigen::Matrix<double, 2, 4>& Jvfocal, Eigen::Matrix<double, 2, 4>& Jhcenter,
Eigen::Matrix<double, 2, 4>& Jvcenter, Eigen::Matrix<double, 2, 4>& JdistortA,
Eigen::Matrix<double, 2, 4>& JdistortB, Eigen::Matrix<double, 2, 4>& JdistortC,
Eigen::Matrix<double, 2, 9>& Jrotation, Eigen::Matrix<double, 2, 4>& JtX,
Eigen::Matrix<double, 2, 4>& JtY, Eigen::Matrix<double, 2, 4>& JtZ, const Eigen::Vector3d& refpt);
/**
@brief Project a point on the unit sphere in the reference space into the camera plane
@param impt_pixels the result projected point
@param refpt the input point in the reference space
@return false if some numerical problem happened
*/
bool project(Eigen::Vector2d& impt_pixels, const Eigen::Vector3d& refpt);
/**
@brief Project a point on the unit sphere in the camera space into the camera plane
@param impt_pixels the result projected point
@param refpt the input point in the reference space
@return false if some numerical problem happened
*/
bool quickproject(Eigen::Vector2d& impt_pixels, const Eigen::Vector3d& campt);
/**
@brief Get point lift mean and covariance matrix
@param mean the lifted point
@param hfocal_variance the variance of horizontal focal parameter
@param vfocal_variance the variance of vertical focal parameter
@param hcenter_variance the variance of horizontal center parameter
@param vcenter_variance the variance of vertical center parameter
@param distorta_variance the variance of distortion A parameter
@param distortb_variance the variance of distortion B parameter
@param distortc_variance the variance of distortion C parameter
@param tx_variance the variance of translation X parameter
@param ty_variance the variance of translation Y parameter
@param tz_variance the variance of translation Z parameter
@param impt the original 2d point to lift
@param sphereScale the sphere radius in the reference frame
@return false if an error occured
*/
bool getLiftCovariance(Eigen::Vector3d& mean, Eigen::Matrix3d& cov, const double hfocal_variance,
const double vfocal_variance, const double hcenter_variance, const double vcenter_variance,
const double distorta_variance, const double distortb_variance, const double distortc_variance,
const double tx_variance, const double ty_variance, const double tz_variance,
const Eigen::Vector2d& impt, const double sphereScale);
/**
@brief Get point projection mean and covariance matrix
@param mean the lifted point
@param hfocal_variance the variance of horizontal focal parameter
@param vfocal_variance the variance of vertical focal parameter
@param hcenter_variance the variance of horizontal center parameter
@param vcenter_variance the variance of vertical center parameter
@param distorta_variance the variance of distortion A parameter
@param distortb_variance the variance of distortion B parameter
@param distortc_variance the variance of distortion C parameter
@param tx_variance the variance of translation X parameter
@param ty_variance the variance of translation Y parameter
@param tz_variance the variance of translation Z parameter
@param refpt the original 3d point to project
@param refpt_cov the original 2d point covariance to project
@return false if an error occured
*/
bool getProjectionCovariance(Eigen::Vector2d& mean, Eigen::Matrix2d& cov, const double hfocal_variance,
const double vfocal_variance, const double hcenter_variance,
const double vcenter_variance, const double distorta_variance,
const double distortb_variance, const double distortc_variance, const double tx_variance,
const double ty_variance, const double tz_variance, const Eigen::Vector3d& refpt,
const Eigen::Matrix3d& refpt_cov);
/**
@brief Returns whether the horizontal focal is constant
*/
bool isHorizontalFocalConstant() const;
/**
@brief Get a pointer on horizontal focal parameters vector
@return a pointer to double vector (4 elements)
*/
double* getHorizontalFocalPtr();
/**
@brief Set lens horizontal focal vector from input vector pointer
@param ptr pointer to the input data
*/
void setHorizontalFocal(const double* ptr);
/**
@brief Returns whether the vertical focal is constant
*/
bool isVerticalFocalConstant() const;
/**
@brief Get a pointer on horizontal focal parameters vector
@return a pointer to double vector (4 elements)
*/
double* getVerticalFocalPtr();
/**
@brief Set lens vertical focal vector from input vector pointer
@param ptr pointer to the input data
*/
void setVerticalFocal(const double* ptr);
/**
@brief Returns whether the horizontal center is constant
*/
bool isHorizontalCenterConstant() const;
/**
@brief Get a pointer on horizontal center parameters vector
@return a pointer to double vector (4 elements)
*/
double* getHorizontalCenterPtr();
/**
@brief Set lens horizontal center vector from input vector pointer
@param ptr pointer to the input data
*/
void setHorizontalCenter(const double* ptr);
/**
@brief Returns whether the vertical center is constant
*/
bool isVerticalCenterConstant() const;
/**
@brief Get a pointer on horizontal center parameters vector
@return a pointer to double vector (4 elements)
*/
double* getVerticalCenterPtr();
/**
@brief Set lens vertical center vector from input vector pointer
@param ptr pointer to the input data
*/
void setVerticalCenter(const double* ptr);
/**
@brief Returns whether the First distortion parameter is constant
*/
bool isDistortionAConstant() const;
/**
@brief Get a pointer on First distortion parameter parameters vector
@return a pointer to double vector (4 elements)
*/
double* getDistortionAPtr();
/**
@brief Set First distortion parameter vector from input vector pointer
@param ptr pointer to the input data
*/
void setDistortionA(const double* ptr);
/**
@brief Returns whether the Second distortion parameter is constant
*/
bool isDistortionBConstant() const;
/**
@brief Get a pointer on Second distortion parameter parameters vector
@return a pointer to double vector (4 elements)
*/
double* getDistortionBPtr();
/**
@brief Set Second distortion parameter vector from input vector pointer
@param ptr pointer to the input data
*/
void setDistortionB(const double* ptr);
/**
@brief Returns whether the Third distortion parameter is constant
*/
bool isDistortionCConstant() const;
/**
@brief Get a pointer on Third distortion parameter parameters vector
@return a pointer to double vector (4 elements)
*/
double* getDistortionCPtr();
/**
@brief Set Third distortion parameter vector from input vector pointer
@param ptr pointer to the input data
*/
void setDistortionC(const double* ptr);
/**
@brief Returns whether the camera rotation is constant
*/
bool isRotationConstant() const;
/**
@brief Get a pointer on camera rotation vector
@return a pointer to double vector (9 elements)
*/
double* getRotationPtr();
/**
@brief Set rotation vector from input vector pointer
@param ptr pointer to the input data
*/
void setRotation(const double* ptr);
/**
@brief Get rotation matrix
@return 3x3 matrix
*/
Eigen::Matrix3d getRotation() const;
/**
@brief Set rotation matrix directly
@param R the input matrix to copy
*/
void setRotationMatrix(const Eigen::Matrix3d& R);
/**
@brief Set rotation matrix from the presets
*/
void setRotationFromPresets();
/**
@brief Checks if given rotation is within presets
@param R the input matrix to check
@return boolean if rotation is within presets
*/
bool isRotationWithinPresets(const Eigen::Matrix3d& R) const;
/**
@brief Get reference pose matrix from presets
@return 3x3 matrix
*/
Eigen::Matrix3d getRotationFromPresets() const;
/**
@brief Returns whether the camera translation X is constant
*/
bool isTranslationXConstant() const;
/**
@brief Get a pointer camera translation X component
@return a pointer to double
*/
double* getTranslationXPtr();
/**
@brief Set camera translation X from input vector pointer
@param ptr pointer to the input data
*/
void setTranslationX(const double* ptr);
/**
@brief Returns whether the camera translation Y is constant
*/
bool isTranslationYConstant() const;
/**
@brief Get a pointer camera translation Y component
@return a pointer to double
*/
double* getTranslationYPtr();
/**
@brief Set camera translation Y from input vector pointer
@param ptr pointer to the input data
*/
void setTranslationY(const double* ptr);
/**
@brief Returns whether the camera translation Z is constant
*/
bool isTranslationZConstant() const;
/**
@brief Get a pointer camera translation Z component
@return a pointer to double
*/
double* getTranslationZPtr();
/**
@brief Set camera translation Z from input vector pointer
@param ptr pointer to the input data
*/
void setTranslationZ(const double* ptr);
/**
@brief Get camera translation in a single output vector
@return camera translation vector
*/
Eigen::Vector3d getTranslation() const;
/**
@brief Set camera translations from input vector
@param translation input translation vector
*/
void setTranslation(const Eigen::Vector3d& translation);
/**
@brief Fill Geometry
@param geometry the to update geometry
@param width width of the input image
@param height height of the input image
*/
void fillGeometry(Core::GeometryDefinition& geometry, int width, int height);
/**
@brief Get Image width
@return width of captured image
*/
size_t getWidth();
/**
@brief Get Image height
@return height of captured image
*/
size_t getHeight();
/**
@brief Get the rotation covariance matrix
@param cov the estimated covariance
*/
void getRotationCovarianceMatrix(Eigen::Matrix<double, 9, 9>& cov) const;
/**
@brief Get the yaw/pitch/roll covariance matrix
@param cov the covariance
*/
void getYawPitchRollCovarianceMatrix(Eigen::Matrix<double, 3, 3>& cov) const;
/**
@brief Get relative rotation
@param second_Rmean_first relative rotation mean between 2 cameras
@param second_axisAngleRCov_first relative rotation variance between 2 cameras in axis-angle representation
@param first the first camera
@param second the second camera
*/
static void getRelativeRotation(Eigen::Matrix3d& second_Rmean_first, Eigen::Matrix3d& second_axisAngleRCov_first,
const Camera& first, const Camera& second);
/*
@brief Get Format for this camera
@return format for this camera class
*/
Core::InputDefinition::Format getFormat();
/**
@brief Set Format for this camera
@param format this camera format
*/
void setFormat(Core::InputDefinition::Format format);
/**
@brief Ties the focal to the focal of another camera
@param other camera to have the focal tied to
*/
void tieFocalTo(const Camera& other);
/**
@brief Untie the focal values (i.e. will have its own values independent from other objects)
*/
void untieFocal();
protected:
/**
@brief Effectively lift a point on the sphere of radius sphereScale in the reference frame
@param refpt the result lifted point
@param Jhfocal jacobian of the function wrt horizontal focal
@param Jvfocal jacobian of the function wrt vertical focal
@param Jhcenter jacobian of the function wrt horizontal center
@param Jvcenter jacobian of the function wrt vertical center
@param JdistortA jacobian of the function wrt distortion param A
@param JdistortB jacobian of the function wrt distortion param B
@param JdistortC jacobian of the function wrt distortion param C
@param Jrotation jacobian of the function wrt lens distortion params
@param Jpose jacobian of the function wrt pose params
@param impt the input image point
@param sphereScale the sphere radius in the reference frame
@return false if some numerical problem happened
*/
bool lift_unbounded(Eigen::Vector3d& refpt, Eigen::Matrix<double, 3, 1>& Jhfocal,
Eigen::Matrix<double, 3, 1>& Jvfocal, Eigen::Matrix<double, 3, 1>& Jhcenter,
Eigen::Matrix<double, 3, 1>& Jvcenter, Eigen::Matrix<double, 3, 1>& JdistortA,
Eigen::Matrix<double, 3, 1>& JdistortB, Eigen::Matrix<double, 3, 1>& JdistortC,
Eigen::Matrix<double, 3, 9>& Jrotation, Eigen::Matrix<double, 3, 1>& JtranslationX,
Eigen::Matrix<double, 3, 1>& JtranslationY, Eigen::Matrix<double, 3, 1>& JtranslationZ,
const Eigen::Vector2d& impt, const double sphereScale);
/**
@brief Project a point on the unit sphere in the reference space into the camera plane
@param impt the result projected point
@param Jpoint jacobian of the function wrt source point
@param Jhfocal jacobian of the function wrt horizontal focal
@param Jvfocal jacobian of the function wrt vertical focal
@param Jhcenter jacobian of the function wrt horizontal center
@param Jvcenter jacobian of the function wrt vertical center
@param JdistortA jacobian of the function wrt lens distortion param A
@param JdistortB jacobian of the function wrt lens distortion param B
@param JdistortC jacobian of the function wrt lens distortion param C
@param Jrotation jacobian of the function wrt pose params
@param refpt the input point in the reference space
@return false if some numerical problem happened
*/
bool project_unbounded(Eigen::Vector2d& impt_pixels, Eigen::Matrix<double, 2, 3>& Jpoint,
Eigen::Matrix<double, 2, 1>& Jhfocal, Eigen::Matrix<double, 2, 1>& Jvfocal,
Eigen::Matrix<double, 2, 1>& Jhcenter, Eigen::Matrix<double, 2, 1>& Jvcenter,
Eigen::Matrix<double, 2, 1>& JdistortA, Eigen::Matrix<double, 2, 1>& JdistortB,
Eigen::Matrix<double, 2, 1>& JdistortC, Eigen::Matrix<double, 2, 9>& Jrotation,
Eigen::Matrix<double, 2, 1>& JtranslationX, Eigen::Matrix<double, 2, 1>& JtranslationY,
Eigen::Matrix<double, 2, 1>& JtranslationZ, const Eigen::Vector3d& refpt);
/**
@brief Backproject from image plane to unit sphere space
@param campt 3d point on the camera frame's unit sphere
@param jacobian the transformation jacobian
@param impt the input image coordinates (in meters)
@return false if some numerical problem happened
*/
virtual bool backproject(Eigen::Vector3d& campt, Eigen::Matrix<double, 3, 2>& jacobian,
const Eigen::Vector2d& impt) = 0;
/**
@brief Project from unit sphere space to image plane in meters
@param impt_meters projected point in meters
@param jacobian the transformation jacobian
@param campt the input 3d coordinates (in camera space)
@return false if some numerical problem happened
*/
virtual bool project(Eigen::Vector2d& impt_meters, Eigen::Matrix<double, 2, 3>& jacobian,
const Eigen::Vector3d& campt) = 0;
/**
@brief Undistort a point
@param impt_undistorted output undistorted
@param impt_distorted input image coordinates
*/
bool undistort(Eigen::Vector2d& impt_undistorted, const Eigen::Vector2d& impt_distorted);
/**
@brief Undistort a point
@param impt_undistorted output undistorted
@param Jundistortwrtdistorted jacobian of undistorted wrt distorted coordinates
@param JparameterA jacobian of undistorted wrt A
@param JparameterB jacobian of undistorted wrt B
@param JparameterC jacobian of undistorted wrt C
@param impt_distorted input image coordinates
*/
bool undistort(Eigen::Vector2d& impt_undistorted, Eigen::Matrix<double, 2, 2>& Jundistortwrtdistorted,
Eigen::Matrix<double, 2, 1>& JparameterA, Eigen::Matrix<double, 2, 1>& JparameterB,
Eigen::Matrix<double, 2, 1>& JparameterC, const Eigen::Vector2d& impt_distorted);
/**
@brief Undistort a point
@param impt_distorted output undistorted
@param impt_undistorted input image coordinates
*/
bool distort(Eigen::Vector2d& impt_distorted, const Eigen::Vector2d& impt_undistorted);
/**
@brief Undistort a point
@param impt_distorted output undistorted
@param Jdistortedwrtundistorted jacobian of undistorted wrt distorted coordinates
@param JparameterA jacobian of undistorted wrt A
@param JparameterB jacobian of undistorted wrt B
@param JparameterC jacobian of undistorted wrt C
@param impt_undistorted input image coordinates
*/
bool distort(Eigen::Vector2d& impt_distorted, Eigen::Matrix<double, 2, 2>& Jdistortedwrtundistorted,
Eigen::Matrix<double, 2, 1>& JparameterA, Eigen::Matrix<double, 2, 1>& JparameterB,
Eigen::Matrix<double, 2, 1>& JparameterC, const Eigen::Vector2d& impt_undistorted);
protected:
/*
WARNING: if you add a member here, do not forget to update the clone() method in all derived classes
*/
BoundedValue horizontal_focal;
BoundedValue vertical_focal;
BoundedValue horizontal_center;
BoundedValue vertical_center;
BoundedValue distort_A;
BoundedValue distort_B;
BoundedValue distort_C;
BoundedValue t_x;
BoundedValue t_y;
BoundedValue t_z;
Eigen::Vector3d yprReference;
Eigen::Matrix<double, 3, 3> yprCovariance;
Eigen::Matrix<double, 3, 3> cameraRreference;
Eigen::Matrix<double, 9, 9> cameraRreference_covariance;
std::array<double, 9> cameraR_data;
Eigen::Map<Eigen::Matrix<double, 3, 3, Eigen::RowMajor> > cameraR;
Core::InputDefinition::Format format;
size_t width;
size_t height;
};
} // namespace Calibration
} // namespace VideoStitch