Blender V4.3
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
21namespace libmv {
22
23namespace {
24
25// FIXME: C++ templates limitations makes thing complicated,
26// but maybe there is a simpler method.
27struct 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
39struct 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
54namespace internal {
55
56// TODO(MatthiasF): downsample lookup
57template <typename WarpFunction>
58void 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
109template <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
129template <typename PixelType>
130void 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
160template <typename PixelType>
161void 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
174template <typename PixelType>
175void 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]
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
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)
#define NULL
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
T round(const T &a)