Blender  V2.93
camera_intrinsics_impl.h
Go to the documentation of this file.
1 // Copyright (c) 2014 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 namespace libmv {
22 
23 namespace {
24 
25 // FIXME: C++ templates limitations makes thing complicated,
26 // but maybe there is a simpler method.
27 struct ApplyIntrinsicsFunction {
28  ApplyIntrinsicsFunction(const CameraIntrinsics& intrinsics,
29  double x,
30  double y,
31  double* warp_x,
32  double* warp_y) {
33  double normalized_x, normalized_y;
34  intrinsics.ImageSpaceToNormalized(x, y, &normalized_x, &normalized_y);
35  intrinsics.ApplyIntrinsics(normalized_x, normalized_y, warp_x, warp_y);
36  }
37 };
38 
39 struct InvertIntrinsicsFunction {
40  InvertIntrinsicsFunction(const CameraIntrinsics& intrinsics,
41  double x,
42  double y,
43  double* warp_x,
44  double* warp_y) {
45  double normalized_x, normalized_y;
46  intrinsics.InvertIntrinsics(x, y, &normalized_x, &normalized_y);
47  intrinsics.NormalizedToImageSpace(
48  normalized_x, normalized_y, warp_x, warp_y);
49  }
50 };
51 
52 } // namespace
53 
54 namespace internal {
55 
56 // TODO(MatthiasF): downsample lookup
57 template <typename WarpFunction>
58 void LookupWarpGrid::Compute(const CameraIntrinsics& intrinsics,
59  int width,
60  int height,
61  double overscan) {
62  double w = (double)width / (1.0 + overscan);
63  double h = (double)height / (1.0 + overscan);
64  double aspx = (double)w / intrinsics.image_width();
65  double aspy = (double)h / intrinsics.image_height();
66 #if defined(_OPENMP)
67 # pragma omp parallel for schedule(static) \
68  num_threads(threads_) if (threads_ > 1 && height > 100)
69 #endif
70  for (int y = 0; y < height; y++) {
71  for (int x = 0; x < width; x++) {
72  double src_x = (x - 0.5 * overscan * w) / aspx,
73  src_y = (y - 0.5 * overscan * h) / aspy;
74  double warp_x, warp_y;
75  WarpFunction(intrinsics, src_x, src_y, &warp_x, &warp_y);
76  warp_x = warp_x * aspx + 0.5 * overscan * w;
77  warp_y = warp_y * aspy + 0.5 * overscan * h;
78  int ix = int(warp_x), iy = int(warp_y);
79  int fx = round((warp_x - ix) * 256), fy = round((warp_y - iy) * 256);
80  if (fx == 256) {
81  fx = 0;
82  ix++;
83  } // NOLINT
84  if (fy == 256) {
85  fy = 0;
86  iy++;
87  } // NOLINT
88  // Use nearest border pixel
89  if (ix < 0) {
90  ix = 0, fx = 0;
91  } // NOLINT
92  if (iy < 0) {
93  iy = 0, fy = 0;
94  } // NOLINT
95  if (ix >= width - 2)
96  ix = width - 2;
97  if (iy >= height - 2)
98  iy = height - 2;
99 
100  Offset offset = {(short)(ix - x),
101  (short)(iy - y),
102  (unsigned char)fx,
103  (unsigned char)fy};
104  offset_[y * width + x] = offset;
105  }
106  }
107 }
108 
109 template <typename WarpFunction>
111  int width,
112  int height,
113  double overscan) {
114  if (width_ != width || height_ != height || overscan_ != overscan) {
115  Reset();
116  }
117 
118  if (offset_ == NULL) {
119  offset_ = new Offset[width * height];
120  Compute<WarpFunction>(intrinsics, width, height, overscan);
121  }
122 
123  width_ = width;
124  height_ = height;
125  overscan_ = overscan;
126 }
127 
128 // TODO(MatthiasF): cubic B-Spline image sampling, bilinear lookup
129 template <typename PixelType>
130 void LookupWarpGrid::Apply(const PixelType* input_buffer,
131  int width,
132  int height,
133  int channels,
134  PixelType* output_buffer) {
135 #if defined(_OPENMP)
136 # pragma omp parallel for schedule(static) \
137  num_threads(threads_) if (threads_ > 1 && height > 100)
138 #endif
139  for (int y = 0; y < height; y++) {
140  for (int x = 0; x < width; x++) {
141  Offset offset = offset_[y * width + x];
142  const int pixel_index =
143  ((y + offset.iy) * width + (x + offset.ix)) * channels;
144  const PixelType* s = &input_buffer[pixel_index];
145  for (int i = 0; i < channels; i++) {
146  output_buffer[(y * width + x) * channels + i] =
147  ((s[i] * (256 - offset.fx) + s[channels + i] * offset.fx) *
148  (256 - offset.fy) +
149  (s[width * channels + i] * (256 - offset.fx) +
150  s[width * channels + channels + i] * offset.fx) *
151  offset.fy) /
152  (256 * 256);
153  }
154  }
155  }
156 }
157 
158 } // namespace internal
159 
160 template <typename PixelType>
161 void CameraIntrinsics::DistortBuffer(const PixelType* input_buffer,
162  int width,
163  int height,
164  double overscan,
165  int channels,
166  PixelType* output_buffer) {
167  assert(channels >= 1);
168  assert(channels <= 4);
169  distort_.Update<InvertIntrinsicsFunction>(*this, width, height, overscan);
170  distort_.Apply<PixelType>(
171  input_buffer, width, height, channels, output_buffer);
172 }
173 
174 template <typename PixelType>
175 void CameraIntrinsics::UndistortBuffer(const PixelType* input_buffer,
176  int width,
177  int height,
178  double overscan,
179  int channels,
180  PixelType* output_buffer) {
181  assert(channels >= 1);
182  assert(channels <= 4);
183  undistort_.Update<ApplyIntrinsicsFunction>(*this, width, height, overscan);
184 
185  undistort_.Apply<PixelType>(
186  input_buffer, width, height, channels, output_buffer);
187 }
188 
189 } // namespace libmv
typedef double(DMatrix)[4][4]
_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
_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 y
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
void DistortBuffer(const PixelType *input_buffer, int width, int height, double overscan, int channels, PixelType *output_buffer)
void UndistortBuffer(const PixelType *input_buffer, int width, int height, double overscan, int channels, PixelType *output_buffer)
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)
struct Offset Offset
Definition: msgfmt.c:181