Blender V4.3
libmv/simple_pipeline/camera_intrinsics.h
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
21#ifndef LIBMV_SIMPLE_PIPELINE_CAMERA_INTRINSICS_H_
22#define LIBMV_SIMPLE_PIPELINE_CAMERA_INTRINSICS_H_
23
24#include <iostream>
25#include <string>
26
27#include <Eigen/Core>
28
31
32namespace libmv {
33
36
37namespace internal {
38
39// This class is responsible to store a lookup grid to perform
40// image warping using this lookup grid. Such a magic is needed
41// to make (un)distortion as fast as possible in cases multiple
42// images are to be processed.
44 public:
46 LookupWarpGrid(const LookupWarpGrid& from);
48
49 // Width and height og the image, measured in pixels.
50 int width() const { return width_; }
51 int height() const { return height_; }
52
53 // Overscan factor of the image, so that
54 // - 0.0 is overscan of 0 pixels,
55 // - 1.0 is overscan of image weight pixels in horizontal direction
56 // and image height pixels in vertical direction.
57 double overscan() const { return overscan_; }
58
59 // Update lookup grid in order to be sure it's calculated for
60 // given image width, height and overscan.
61 //
62 // See comment for CameraIntrinsics::DistortBuffer to get more
63 // details about what overscan is.
64 template <typename WarpFunction>
65 void Update(const CameraIntrinsics& intrinsics,
66 int width,
67 int height,
68 double overscan);
69
70 // Apply coordinate lookup grid on a giver input buffer.
71 //
72 // See comment for CameraIntrinsics::DistortBuffer to get more
73 // details about template type.
74 template <typename PixelType>
75 void Apply(const PixelType* input_buffer,
76 int width,
77 int height,
78 int channels,
79 PixelType* output_buffer);
80
81 // Reset lookup grids.
82 // This will tag the grid for update without re-computing it.
83 void Reset();
84
85 // Set number of threads used for threaded buffer distortion/undistortion.
86 void SetThreads(int threads);
87
88 private:
89 // This structure contains an offset in both x,y directions
90 // in an optimized way sawing some bytes per pixel in the memory.
91 //
92 // TODO(sergey): This is rather questionable optimizations, memory
93 // is cheap nowadays and storing offset in such a way implies much
94 // more operations comparing to using bare floats.
95 struct Offset {
96 // Integer part of the offset.
97 short ix, iy;
98
99 // Float part of an offset, to get a real float value divide this
100 // value by 255.
101 unsigned char fx, fy;
102 };
103
104 // Compute coordinate lookup grid using a giver warp functor.
105 //
106 // width and height corresponds to a size of buffer which will
107 // be warped later.
108 template <typename WarpFunction>
109 void Compute(const CameraIntrinsics& intrinsics,
110 int width,
111 int height,
112 double overscan);
113
114 // This is a buffer which contains per-pixel offset of the
115 // pixels from input buffer to correspond the warping function.
116 Offset* offset_;
117
118 // Dimensions of the image this lookup grid processes.
119 int width_, height_;
120
121 // Overscan of the image being processed by this grid.
122 double overscan_;
123
124 // Number of threads which will be used for buffer istortion/undistortion.
125 int threads_;
126};
127
128} // namespace internal
129
131 public:
134 virtual ~CameraIntrinsics() {}
135
137
138 int image_width() const { return image_width_; }
139 int image_height() const { return image_height_; }
140
141 const Mat3& K() const { return K_; }
142
143 double focal_length() const { return K_(0, 0); }
144 double focal_length_x() const { return K_(0, 0); }
145 double focal_length_y() const { return K_(1, 1); }
146
147 double principal_point_x() const { return K_(0, 2); }
148 double principal_point_y() const { return K_(1, 2); }
149
150 // Set the image size in pixels.
151 // Image is the size of image camera intrinsics were calibrated with.
152 void SetImageSize(int width, int height);
153
154 // Set the entire calibration matrix at once.
155 void SetK(const Mat3 new_k);
156
157 // Set both x and y focal length in pixels.
158 void SetFocalLength(double focal_x, double focal_y);
159
160 // Set principal point in pixels.
161 void SetPrincipalPoint(double cx, double cy);
162
163 // Set number of threads used for threaded buffer distortion/undistortion.
164 void SetThreads(int threads);
165
166 // Convert image space coordinates to normalized.
167 void ImageSpaceToNormalized(double image_x,
168 double image_y,
169 double* normalized_x,
170 double* normalized_y) const;
171
172 // Convert normalized coordinates to image space.
173 void NormalizedToImageSpace(double normalized_x,
174 double normalized_y,
175 double* image_x,
176 double* image_y) const;
177
178 // Apply camera intrinsics to the normalized point to get image coordinates.
179 //
180 // This applies the lens distortion to a point which is in normalized
181 // camera coordinates (i.e. the principal point is at (0, 0)) to get image
182 // coordinates in pixels.
183 virtual void ApplyIntrinsics(double normalized_x,
184 double normalized_y,
185 double* image_x,
186 double* image_y) const = 0;
187
188 // Invert camera intrinsics on the image point to get normalized coordinates.
189 //
190 // This reverses the effect of lens distortion on a point which is in image
191 // coordinates to get normalized camera coordinates.
192 virtual void InvertIntrinsics(double image_x,
193 double image_y,
194 double* normalized_x,
195 double* normalized_y) const = 0;
196
197 virtual void Pack(PackedIntrinsics* packed_intrinsics) const;
198 virtual void Unpack(const PackedIntrinsics& packed_intrinsics);
199
200 // Distort an image using the current camera instrinsics
201 //
202 // The distorted image is computed in output_buffer using samples from
203 // input_buffer. Both buffers should be width x height x channels sized.
204 //
205 // Overscan is a percentage value of how much overcan the image have.
206 // For example overscal value of 0.2 means 20% of overscan in the
207 // buffers.
208 //
209 // Overscan is usually used in cases when one need to distort an image
210 // and don't have a barrel in the distorted buffer. For example, when
211 // one need to render properly distorted FullHD frame without barrel
212 // visible. For such cases renderers usually renders bigger images and
213 // crops them after the distortion.
214 //
215 // This method is templated to be able to distort byte and float buffers
216 // without having separate methods for this two types. So basically only
217 //
218 // But in fact PixelType might be any type for which multiplication by
219 // a scalar and addition are implemented. For example PixelType might be
220 // Vec3 as well.
221 template <typename PixelType>
222 void DistortBuffer(const PixelType* input_buffer,
223 int width,
224 int height,
225 double overscan,
226 int channels,
227 PixelType* output_buffer);
228
229 // Undistort an image using the current camera instrinsics
230 //
231 // The undistorted image is computed in output_buffer using samples from
232 // input_buffer. Both buffers should be width x height x channels sized.
233 //
234 // Overscan is a percentage value of how much overcan the image have.
235 // For example overscal value of 0.2 means 20% of overscan in the
236 // buffers.
237 //
238 // Overscan is usually used in cases when one need to distort an image
239 // and don't have a barrel in the distorted buffer. For example, when
240 // one need to render properly distorted FullHD frame without barrel
241 // visible. For such cases renderers usually renders bigger images and
242 // crops them after the distortion.
243 //
244 // This method is templated to be able to distort byte and float buffers
245 // without having separate methods for this two types. So basically only
246 //
247 // But in fact PixelType might be any type for which multiplication by
248 // a scalar and addition are implemented. For example PixelType might be
249 // Vec3 as well.
250 template <typename PixelType>
251 void UndistortBuffer(const PixelType* input_buffer,
252 int width,
253 int height,
254 double overscan,
255 int channels,
256 PixelType* output_buffer);
257
258 private:
259 // This is the size of the image. This is necessary to, for example, handle
260 // the case of processing a scaled image.
261 int image_width_;
262 int image_height_;
263
264 // The traditional intrinsics matrix from x = K[R|t]X.
265 Mat3 K_;
266
267 // Coordinate lookup grids for distortion and undistortion.
269 internal::LookupWarpGrid undistort_;
270
271 protected:
272 // Reset lookup grids after changing the distortion model.
273 void ResetLookupGrids();
274};
275
277 public:
278 // This constants defines an offset of corresponding coefficients
279 // in the parameters_ array.
280 enum {
286
287 // This defines the size of array which we need to have in order
288 // to store all the coefficients.
290 };
291
294
298
299 double k1() const { return parameters_[OFFSET_K1]; }
300 double k2() const { return parameters_[OFFSET_K2]; }
301 double k3() const { return parameters_[OFFSET_K3]; }
302 double p1() const { return parameters_[OFFSET_P1]; }
303 double p2() const { return parameters_[OFFSET_P2]; }
304
305 // Set radial distortion coeffcients.
306 void SetRadialDistortion(double k1, double k2, double k3);
307
308 // Set tangential distortion coeffcients.
309 void SetTangentialDistortion(double p1, double p2);
310
311 // Apply camera intrinsics to the normalized point to get image coordinates.
312 //
313 // This applies the lens distortion to a point which is in normalized
314 // camera coordinates (i.e. the principal point is at (0, 0)) to get image
315 // coordinates in pixels.
316 void ApplyIntrinsics(double normalized_x,
317 double normalized_y,
318 double* image_x,
319 double* image_y) const override;
320
321 // Invert camera intrinsics on the image point to get normalized coordinates.
322 //
323 // This reverses the effect of lens distortion on a point which is in image
324 // coordinates to get normalized camera coordinates.
325 void InvertIntrinsics(double image_x,
326 double image_y,
327 double* normalized_x,
328 double* normalized_y) const override;
329
330 virtual void Pack(PackedIntrinsics* packed_intrinsics) const override;
331 virtual void Unpack(const PackedIntrinsics& packed_intrinsics) override;
332
333 private:
334 // OpenCV's distortion model with third order polynomial radial distortion
335 // terms and second order tangential distortion. The distortion is applied to
336 // the normalized coordinates before the focal length, which makes them
337 // independent of image size.
338 double parameters_[NUM_PARAMETERS];
339};
340
342 public:
343 // This constants defines an offset of corresponding coefficients
344 // in the parameters_ array.
345 enum {
348
349 // This defines the size of array which we need to have in order
350 // to store all the coefficients.
352 };
353
356
360
361 double k1() const { return parameters_[OFFSET_K1]; }
362 double k2() const { return parameters_[OFFSET_K2]; }
363
364 // Set radial distortion coeffcients.
365 void SetDistortion(double k1, double k2);
366
367 // Apply camera intrinsics to the normalized point to get image coordinates.
368 //
369 // This applies the lens distortion to a point which is in normalized
370 // camera coordinates (i.e. the principal point is at (0, 0)) to get image
371 // coordinates in pixels.
372 void ApplyIntrinsics(double normalized_x,
373 double normalized_y,
374 double* image_x,
375 double* image_y) const override;
376
377 // Invert camera intrinsics on the image point to get normalized coordinates.
378 //
379 // This reverses the effect of lens distortion on a point which is in image
380 // coordinates to get normalized camera coordinates.
381 void InvertIntrinsics(double image_x,
382 double image_y,
383 double* normalized_x,
384 double* normalized_y) const override;
385
386 virtual void Pack(PackedIntrinsics* packed_intrinsics) const override;
387 virtual void Unpack(const PackedIntrinsics& packed_intrinsics) override;
388
389 private:
390 // Double-parameter division distortion model.
391 double parameters_[NUM_PARAMETERS];
392};
393
395 public:
396 // This constants defines an offset of corresponding coefficients
397 // in the parameters_ array.
398 enum {
401
402 // This defines the size of array which we need to have in order
403 // to store all the coefficients.
405 };
406
409
413
414 double k1() const { return parameters_[OFFSET_K1]; }
415 double k2() const { return parameters_[OFFSET_K2]; }
416
417 // Set radial distortion coeffcients.
418 void SetDistortion(double k1, double k2);
419
420 // Apply camera intrinsics to the normalized point to get image coordinates.
421 //
422 // This applies the lens distortion to a point which is in normalized
423 // camera coordinates (i.e. the principal point is at (0, 0)) to get image
424 // coordinates in pixels.
425 void ApplyIntrinsics(double normalized_x,
426 double normalized_y,
427 double* image_x,
428 double* image_y) const override;
429
430 // Invert camera intrinsics on the image point to get normalized coordinates.
431 //
432 // This reverses the effect of lens distortion on a point which is in image
433 // coordinates to get normalized camera coordinates.
434 void InvertIntrinsics(double image_x,
435 double image_y,
436 double* normalized_x,
437 double* normalized_y) const override;
438
439 virtual void Pack(PackedIntrinsics* packed_intrinsics) const override;
440 virtual void Unpack(const PackedIntrinsics& packed_intrinsics) override;
441
442 private:
443 // Double-parameter division distortion model.
444 double parameters_[NUM_PARAMETERS];
445};
446
448 public:
449 // This constants defines an offset of corresponding coefficients
450 // in the parameters_ array.
451 enum {
458
459 // This defines the size of array which we need to have in order
460 // to store all the coefficients.
462 };
463
466
470
471 double k1() const { return parameters_[OFFSET_K1]; }
472 double k2() const { return parameters_[OFFSET_K2]; }
473 double k3() const { return parameters_[OFFSET_K3]; }
474 double k4() const { return parameters_[OFFSET_K4]; }
475 double p1() const { return parameters_[OFFSET_P1]; }
476 double p2() const { return parameters_[OFFSET_P2]; }
477
478 // Set radial distortion coeffcients.
479 void SetRadialDistortion(double k1, double k2, double k3, double k4);
480
481 // Set tangential distortion coeffcients.
482 void SetTangentialDistortion(double p1, double p2);
483
484 // Apply camera intrinsics to the normalized point to get image coordinates.
485 //
486 // This applies the lens distortion to a point which is in normalized
487 // camera coordinates (i.e. the principal point is at (0, 0)) to get image
488 // coordinates in pixels.
489 void ApplyIntrinsics(double normalized_x,
490 double normalized_y,
491 double* image_x,
492 double* image_y) const override;
493
494 // Invert camera intrinsics on the image point to get normalized coordinates.
495 //
496 // This reverses the effect of lens distortion on a point which is in image
497 // coordinates to get normalized camera coordinates.
498 void InvertIntrinsics(double image_x,
499 double image_y,
500 double* normalized_x,
501 double* normalized_y) const override;
502
503 virtual void Pack(PackedIntrinsics* packed_intrinsics) const override;
504 virtual void Unpack(const PackedIntrinsics& packed_intrinsics) override;
505
506 private:
507 double parameters_[NUM_PARAMETERS];
508};
509
511std::ostream& operator<<(std::ostream& os, const CameraIntrinsics& intrinsics);
512
513} // namespace libmv
514
515// Include implementation of all templated methods here,
516// so they're visible to the compiler.
518
519#endif // LIBMV_SIMPLE_PIPELINE_CAMERA_INTRINSICS_H_
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Brightness Control the brightness and contrast of the input color Vector Map input vector components with curves Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert Invert a producing a negative Combine Generate a color from its and blue channels(Deprecated)") DefNode(ShaderNode
DistortionModelType GetDistortionModelType() const override
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
virtual void ApplyIntrinsics(double normalized_x, double normalized_y, double *image_x, double *image_y) const =0
void DistortBuffer(const PixelType *input_buffer, int width, int height, double overscan, int channels, PixelType *output_buffer)
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 InvertIntrinsics(double image_x, double image_y, double *normalized_x, double *normalized_y) const =0
virtual void Unpack(const PackedIntrinsics &packed_intrinsics)
virtual void Pack(PackedIntrinsics *packed_intrinsics) const
void UndistortBuffer(const PixelType *input_buffer, int width, int height, double overscan, int channels, PixelType *output_buffer)
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
DistortionModelType GetDistortionModelType() 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
DistortionModelType GetDistortionModelType() 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
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
DistortionModelType GetDistortionModelType() const override
void Apply(const PixelType *input_buffer, int width, int height, int channels, PixelType *output_buffer)
void Update(const CameraIntrinsics &intrinsics, int width, int height, double overscan)
std::ostream & operator<<(std::ostream &os, const CameraIntrinsics &intrinsics)
A human-readable representation of the camera intrinsic parameters.
Eigen::Matrix< double, 3, 3 > Mat3
Definition numeric.h:72
@ DISTORTION_MODEL_POLYNOMIAL
@ DISTORTION_MODEL_DIVISION
@ DISTORTION_MODEL_BROWN
@ DISTORTION_MODEL_NUKE