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