Blender V4.3
libmv/simple_pipeline/camera_intrinsics.cc
Go to the documentation of this file.
1// Copyright (c) 2011 libmv authors.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy
4// of this software and associated documentation files (the "Software"), to
5// deal in the Software without restriction, including without limitation the
6// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7// sell copies of the Software, and to permit persons to whom the Software is
8// furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in
11// all copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19// IN THE SOFTWARE.
20
22
26
27namespace libmv {
28
29namespace internal {
30
32 : offset_(NULL), width_(0), height_(0), overscan_(0.0), threads_(1) {
33}
34
36 : offset_(NULL),
37 width_(from.width_),
38 height_(from.height_),
39 overscan_(from.overscan_),
40 threads_(from.threads_) {
41 if (from.offset_) {
42 offset_ = new Offset[width_ * height_];
43 memcpy(offset_, from.offset_, sizeof(Offset) * width_ * height_);
44 }
45}
46
48 delete[] offset_;
49}
50
52 delete[] offset_;
53 offset_ = NULL;
54}
55
56// Set number of threads used for threaded buffer distortion/undistortion.
57void LookupWarpGrid::SetThreads(int threads) {
58 threads_ = threads;
59}
60
61} // namespace internal
62
64 : image_width_(0), image_height_(0), K_(Mat3::Identity()) {
65}
66
68 : image_width_(from.image_width_),
69 image_height_(from.image_height_),
70 K_(from.K_),
71 distort_(from.distort_),
72 undistort_(from.undistort_) {
73}
74
75// Set the image size in pixels.
76void CameraIntrinsics::SetImageSize(int width, int height) {
77 image_width_ = width;
78 image_height_ = height;
80}
81
82// Set the entire calibration matrix at once.
83void CameraIntrinsics::SetK(const Mat3 new_k) {
84 K_ = new_k;
86}
87
88// Set both x and y focal length in pixels.
89void CameraIntrinsics::SetFocalLength(double focal_x, double focal_y) {
90 K_(0, 0) = focal_x;
91 K_(1, 1) = focal_y;
93}
94
95// Set principal point in pixels.
96void CameraIntrinsics::SetPrincipalPoint(double cx, double cy) {
97 K_(0, 2) = cx;
98 K_(1, 2) = cy;
100}
101
102// Set number of threads used for threaded buffer distortion/undistortion.
104 distort_.SetThreads(threads);
105 undistort_.SetThreads(threads);
106}
107
109 double image_y,
110 double* normalized_x,
111 double* normalized_y) const {
112 *normalized_x = (image_x - principal_point_x()) / focal_length_x();
113 *normalized_y = (image_y - principal_point_y()) / focal_length_y();
114}
115
117 double normalized_y,
118 double* image_x,
119 double* image_y) const {
120 *image_x = normalized_x * focal_length_x() + principal_point_x();
121 *image_y = normalized_y * focal_length_y() + principal_point_y();
122}
123
124// Reset lookup grids after changing the distortion model.
126 distort_.Reset();
127 undistort_.Reset();
128}
129
130void CameraIntrinsics::Pack(PackedIntrinsics* packed_intrinsics) const {
131 packed_intrinsics->SetFocalLength(focal_length());
132 packed_intrinsics->SetPrincipalPoint(principal_point_x(),
134}
135
136void CameraIntrinsics::Unpack(const PackedIntrinsics& packed_intrinsics) {
137 SetFocalLength(packed_intrinsics.GetFocalLength(),
138 packed_intrinsics.GetFocalLength());
139
140 SetPrincipalPoint(packed_intrinsics.GetPrincipalPointX(),
141 packed_intrinsics.GetPrincipalPointY());
142}
143
144// Polynomial model.
145
150
152 const PolynomialCameraIntrinsics& from)
153 : CameraIntrinsics(from) {
154 SetRadialDistortion(from.k1(), from.k2(), from.k3());
155 SetTangentialDistortion(from.p1(), from.p2());
156}
157
159 double k2,
160 double k3) {
161 parameters_[OFFSET_K1] = k1;
162 parameters_[OFFSET_K2] = k2;
163 parameters_[OFFSET_K3] = k3;
165}
166
168 parameters_[OFFSET_P1] = p1;
169 parameters_[OFFSET_P2] = p2;
171}
172
174 double normalized_y,
175 double* image_x,
176 double* image_y) const {
181 k1(),
182 k2(),
183 k3(),
184 p1(),
185 p2(),
186 normalized_x,
187 normalized_y,
188 image_x,
189 image_y);
190}
191
193 double image_y,
194 double* normalized_x,
195 double* normalized_y) const {
200 k1(),
201 k2(),
202 k3(),
203 p1(),
204 p2(),
205 image_x,
206 image_y,
207 normalized_x,
208 normalized_y);
209}
210
212 PackedIntrinsics* packed_intrinsics) const {
213 CameraIntrinsics::Pack(packed_intrinsics);
214
215 packed_intrinsics->SetK1(k1());
216 packed_intrinsics->SetK2(k2());
217 packed_intrinsics->SetK3(k3());
218
219 packed_intrinsics->SetP1(p1());
220 packed_intrinsics->SetP2(p2());
221}
222
224 const PackedIntrinsics& packed_intrinsics) {
225 CameraIntrinsics::Unpack(packed_intrinsics);
226
227 SetRadialDistortion(packed_intrinsics.GetK1(),
228 packed_intrinsics.GetK2(),
229 packed_intrinsics.GetK3());
230
231 SetTangentialDistortion(packed_intrinsics.GetP1(), packed_intrinsics.GetP2());
232}
233
234// Division model.
235
239
245
246void DivisionCameraIntrinsics::SetDistortion(double k1, double k2) {
247 parameters_[OFFSET_K1] = k1;
248 parameters_[OFFSET_K2] = k2;
250}
251
253 double normalized_y,
254 double* image_x,
255 double* image_y) const {
260 k1(),
261 k2(),
262 normalized_x,
263 normalized_y,
264 image_x,
265 image_y);
266}
267
269 double image_y,
270 double* normalized_x,
271 double* normalized_y) const {
276 k1(),
277 k2(),
278 image_x,
279 image_y,
280 normalized_x,
281 normalized_y);
282}
283
284void DivisionCameraIntrinsics::Pack(PackedIntrinsics* packed_intrinsics) const {
285 CameraIntrinsics::Pack(packed_intrinsics);
286
287 packed_intrinsics->SetK1(k1());
288 packed_intrinsics->SetK2(k2());
289}
290
292 const PackedIntrinsics& packed_intrinsics) {
293 CameraIntrinsics::Unpack(packed_intrinsics);
294
295 SetDistortion(packed_intrinsics.GetK1(), packed_intrinsics.GetK2());
296}
297
298// Nuke model.
299
303
308
309void NukeCameraIntrinsics::SetDistortion(double k1, double k2) {
310 parameters_[OFFSET_K1] = k1;
311 parameters_[OFFSET_K2] = k2;
313}
314
316 double normalized_y,
317 double* image_x,
318 double* image_y) const {
323 image_width(),
324 image_height(),
325 k1(),
326 k2(),
327 normalized_x,
328 normalized_y,
329 image_x,
330 image_y);
331}
332
334 double image_y,
335 double* normalized_x,
336 double* normalized_y) const {
341 image_width(),
342 image_height(),
343 k1(),
344 k2(),
345 image_x,
346 image_y,
347 normalized_x,
348 normalized_y);
349}
350
351void NukeCameraIntrinsics::Pack(PackedIntrinsics* packed_intrinsics) const {
352 CameraIntrinsics::Pack(packed_intrinsics);
353
354 packed_intrinsics->SetK1(k1());
355 packed_intrinsics->SetK2(k2());
356}
357
358void NukeCameraIntrinsics::Unpack(const PackedIntrinsics& packed_intrinsics) {
359 CameraIntrinsics::Unpack(packed_intrinsics);
360
361 SetDistortion(packed_intrinsics.GetK1(), packed_intrinsics.GetK2());
362}
363
364// Brown model.
365
370
372 : CameraIntrinsics(from) {
373 SetRadialDistortion(from.k1(), from.k2(), from.k3(), from.k4());
374 SetTangentialDistortion(from.p1(), from.p2());
375}
376
378 double k2,
379 double k3,
380 double k4) {
381 parameters_[OFFSET_K1] = k1;
382 parameters_[OFFSET_K2] = k2;
383 parameters_[OFFSET_K3] = k3;
384 parameters_[OFFSET_K4] = k4;
386}
387
389 parameters_[OFFSET_P1] = p1;
390 parameters_[OFFSET_P2] = p2;
392}
393
395 double normalized_y,
396 double* image_x,
397 double* image_y) const {
402 k1(),
403 k2(),
404 k3(),
405 k4(),
406 p1(),
407 p2(),
408 normalized_x,
409 normalized_y,
410 image_x,
411 image_y);
412}
413
415 double image_y,
416 double* normalized_x,
417 double* normalized_y) const {
422 k1(),
423 k2(),
424 k3(),
425 k4(),
426 p1(),
427 p2(),
428 image_x,
429 image_y,
430 normalized_x,
431 normalized_y);
432}
433
434void BrownCameraIntrinsics::Pack(PackedIntrinsics* packed_intrinsics) const {
435 CameraIntrinsics::Pack(packed_intrinsics);
436
437 packed_intrinsics->SetK1(k1());
438 packed_intrinsics->SetK2(k2());
439 packed_intrinsics->SetK3(k3());
440 packed_intrinsics->SetK4(k4());
441
442 packed_intrinsics->SetP1(p1());
443 packed_intrinsics->SetP2(p2());
444}
445
446void BrownCameraIntrinsics::Unpack(const PackedIntrinsics& packed_intrinsics) {
447 CameraIntrinsics::Unpack(packed_intrinsics);
448
449 SetRadialDistortion(packed_intrinsics.GetK1(),
450 packed_intrinsics.GetK2(),
451 packed_intrinsics.GetK3(),
452 packed_intrinsics.GetK4());
453
454 SetTangentialDistortion(packed_intrinsics.GetP1(), packed_intrinsics.GetP2());
455}
456
457std::ostream& operator<<(std::ostream& os, const CameraIntrinsics& intrinsics) {
458 if (intrinsics.focal_length_x() == intrinsics.focal_length_x()) {
459 os << "f=" << intrinsics.focal_length();
460 } else {
461 os << "fx=" << intrinsics.focal_length_x()
462 << " fy=" << intrinsics.focal_length_y();
463 }
464 os << " cx=" << intrinsics.principal_point_x()
465 << " cy=" << intrinsics.principal_point_y()
466 << " w=" << intrinsics.image_width() << " h=" << intrinsics.image_height();
467
468#define PRINT_NONZERO_COEFFICIENT(intrinsics, coeff) \
469 { \
470 if (intrinsics->coeff() != 0.0) { \
471 os << " " #coeff "=" << intrinsics->coeff(); \
472 } \
473 } \
474 (void)0
475
476 switch (intrinsics.GetDistortionModelType()) {
478 const PolynomialCameraIntrinsics* polynomial_intrinsics =
479 static_cast<const PolynomialCameraIntrinsics*>(&intrinsics);
480 PRINT_NONZERO_COEFFICIENT(polynomial_intrinsics, k1);
481 PRINT_NONZERO_COEFFICIENT(polynomial_intrinsics, k2);
482 PRINT_NONZERO_COEFFICIENT(polynomial_intrinsics, k3);
483 PRINT_NONZERO_COEFFICIENT(polynomial_intrinsics, p1);
484 PRINT_NONZERO_COEFFICIENT(polynomial_intrinsics, p2);
485 break;
486 }
488 const DivisionCameraIntrinsics* division_intrinsics =
489 static_cast<const DivisionCameraIntrinsics*>(&intrinsics);
490 PRINT_NONZERO_COEFFICIENT(division_intrinsics, k1);
491 PRINT_NONZERO_COEFFICIENT(division_intrinsics, k2);
492 break;
493 }
495 const NukeCameraIntrinsics* nuke_intrinsics =
496 static_cast<const NukeCameraIntrinsics*>(&intrinsics);
497 PRINT_NONZERO_COEFFICIENT(nuke_intrinsics, k1);
498 PRINT_NONZERO_COEFFICIENT(nuke_intrinsics, k2);
499 break;
500 }
502 const BrownCameraIntrinsics* brown_intrinsics =
503 static_cast<const BrownCameraIntrinsics*>(&intrinsics);
504 PRINT_NONZERO_COEFFICIENT(brown_intrinsics, k1);
505 PRINT_NONZERO_COEFFICIENT(brown_intrinsics, k2);
506 PRINT_NONZERO_COEFFICIENT(brown_intrinsics, k3);
507 PRINT_NONZERO_COEFFICIENT(brown_intrinsics, k4);
508 PRINT_NONZERO_COEFFICIENT(brown_intrinsics, p1);
509 PRINT_NONZERO_COEFFICIENT(brown_intrinsics, p2);
510 break;
511 }
512 default: LOG(FATAL) << "Unknown distortion model.";
513 }
514
515#undef PRINT_NONZERO_COEFFICIENT
516
517 return os;
518}
519
520} // namespace libmv
void ApplyIntrinsics(double normalized_x, double normalized_y, double *image_x, double *image_y) const override
virtual void Unpack(const PackedIntrinsics &packed_intrinsics) override
virtual void Pack(PackedIntrinsics *packed_intrinsics) const override
void SetRadialDistortion(double k1, double k2, double k3, double k4)
void InvertIntrinsics(double image_x, double image_y, double *normalized_x, double *normalized_y) const override
void SetFocalLength(double focal_x, double focal_y)
void NormalizedToImageSpace(double normalized_x, double normalized_y, double *image_x, double *image_y) const
virtual void Unpack(const PackedIntrinsics &packed_intrinsics)
virtual void Pack(PackedIntrinsics *packed_intrinsics) const
virtual DistortionModelType GetDistortionModelType() const =0
void ImageSpaceToNormalized(double image_x, double image_y, double *normalized_x, double *normalized_y) const
virtual void Unpack(const PackedIntrinsics &packed_intrinsics) override
virtual void Pack(PackedIntrinsics *packed_intrinsics) const override
void InvertIntrinsics(double image_x, double image_y, double *normalized_x, double *normalized_y) const override
void ApplyIntrinsics(double normalized_x, double normalized_y, double *image_x, double *image_y) const override
virtual void Pack(PackedIntrinsics *packed_intrinsics) const override
void InvertIntrinsics(double image_x, double image_y, double *normalized_x, double *normalized_y) const override
virtual void Unpack(const PackedIntrinsics &packed_intrinsics) override
void ApplyIntrinsics(double normalized_x, double normalized_y, double *image_x, double *image_y) const override
double GetPrincipalPointY() const
void SetFocalLength(double focal_length)
double GetPrincipalPointX() const
void SetPrincipalPoint(double x, double y)
virtual void Pack(PackedIntrinsics *packed_intrinsics) const override
void InvertIntrinsics(double image_x, double image_y, double *normalized_x, double *normalized_y) const override
virtual void Unpack(const PackedIntrinsics &packed_intrinsics) override
void SetRadialDistortion(double k1, double k2, double k3)
void ApplyIntrinsics(double normalized_x, double normalized_y, double *image_x, double *image_y) const override
#define NULL
#define PRINT_NONZERO_COEFFICIENT(intrinsics, coeff)
#define LOG(severity)
Definition log.h:33
void InvertNukeDistortionModel(const T &focal_length_x, const T &focal_length_y, const T &principal_point_x, const T &principal_point_y, const int image_width, const int image_height, const T &k1, const T &k2, const T &image_x, const T &image_y, T *normalized_x, T *normalized_y)
std::ostream & operator<<(std::ostream &os, const CameraIntrinsics &intrinsics)
A human-readable representation of the camera intrinsic parameters.
void InvertPolynomialDistortionModel(const double focal_length_x, const double focal_length_y, const double principal_point_x, const double principal_point_y, const double k1, const double k2, const double k3, const double p1, const double p2, const double image_x, const double image_y, double *normalized_x, double *normalized_y)
void ApplyPolynomialDistortionModel(const T &focal_length_x, const T &focal_length_y, const T &principal_point_x, const T &principal_point_y, const T &k1, const T &k2, const T &k3, const T &p1, const T &p2, const T &normalized_x, const T &normalized_y, T *image_x, T *image_y)
Eigen::Matrix< double, 3, 3 > Mat3
Definition numeric.h:72
void ApplyDivisionDistortionModel(const T &focal_length_x, const T &focal_length_y, const T &principal_point_x, const T &principal_point_y, const T &k1, const T &k2, const T &normalized_x, const T &normalized_y, T *image_x, T *image_y)
void ApplyNukeDistortionModel(const double focal_length_x, const double focal_length_y, const double principal_point_x, const double principal_point_y, const int image_width, const int image_height, const double k1, const double k2, const double normalized_x, const double normalized_y, double *image_x, double *image_y)
void InvertBrownDistortionModel(const double focal_length_x, const double focal_length_y, const double principal_point_x, const double principal_point_y, const double k1, const double k2, const double k3, const double k4, const double p1, const double p2, const double image_x, const double image_y, double *normalized_x, double *normalized_y)
void InvertDivisionDistortionModel(const double focal_length_x, const double focal_length_y, const double principal_point_x, const double principal_point_y, const double k1, const double k2, const double image_x, const double image_y, double *normalized_x, double *normalized_y)
@ DISTORTION_MODEL_POLYNOMIAL
@ DISTORTION_MODEL_DIVISION
@ DISTORTION_MODEL_BROWN
@ DISTORTION_MODEL_NUKE
void ApplyBrownDistortionModel(const T &focal_length_x, const T &focal_length_y, const T &principal_point_x, const T &principal_point_y, const T &k1, const T &k2, const T &k3, const T &k4, const T &p1, const T &p2, const T &normalized_x, const T &normalized_y, T *image_x, T *image_y)