Blender  V3.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 
29 #include "libmv/numeric/numeric.h"
31 
32 namespace libmv {
33 
34 class CameraIntrinsics;
35 class PackedIntrinsics;
36 
37 namespace 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:
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.
268  internal::LookupWarpGrid distort_;
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 
297  }
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 
359  }
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 
411  return DISTORTION_MODEL_NUKE;
412  }
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 
468  return DISTORTION_MODEL_BROWN;
469  }
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 
511 std::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_
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
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 Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input 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 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)
StackEntry * from
ListBase threads
list of all thread for every CPUDevice in cpudevices a thread exists.
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
Definition: msgfmt.c:165