Blender V4.3
camera_intrinsics_test.cc
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
22
23#include <iostream>
24
25#include "libmv/image/image.h"
28#include "testing/testing.h"
29
30namespace libmv {
31
32TEST(PolynomialCameraIntrinsics2, ApplyOnFocalCenter) {
34 intrinsics.SetFocalLength(1300.0, 1300.0);
35 intrinsics.SetPrincipalPoint(640.0, 540.0);
36 intrinsics.SetRadialDistortion(-0.2, -0.1, -0.05);
37
38 double distorted_x, distorted_y;
39 intrinsics.ApplyIntrinsics(0.0, 0.0, &distorted_x, &distorted_y);
40
41 EXPECT_NEAR(640.0, distorted_x, 1e-8);
42 EXPECT_NEAR(540.0, distorted_y, 1e-8);
43}
44
45TEST(PolynomialCameraIntrinsics, InvertOnFocalCenter) {
47 intrinsics.SetFocalLength(1300.0, 1300.0);
48 intrinsics.SetPrincipalPoint(640.0, 540.0);
49 intrinsics.SetRadialDistortion(-0.2, -0.1, -0.05);
50
51 double normalized_x, normalized_y;
52 intrinsics.InvertIntrinsics(640.0, 540.0, &normalized_x, &normalized_y);
53
54 EXPECT_NEAR(0.0, normalized_x, 1e-8);
55 EXPECT_NEAR(0.0, normalized_y, 1e-8);
56}
57
59 const int N = 5;
60
61 double expected[N][N][2] = {
62 {{75.312500, -24.687500},
63 {338.982239, -62.035522},
64 {640.000000, -72.929688},
65 {941.017761, -62.035522},
66 {1204.687500, -24.687500}},
67
68 {{37.964478, 238.982239},
69 {323.664551, 223.664551},
70 {640.000000, 219.193420},
71 {956.335449, 223.664551},
72 {1242.035522, 238.982239}},
73
74 {{27.070312, 540.000000},
75 {319.193420, 540.000000},
76 {640.000000, 540.000000},
77 {960.806580, 540.000000},
78 {1252.929688, 540.000000}},
79
80 {{37.964478, 841.017761},
81 {323.664551, 856.335449},
82 {640.000000, 860.806580},
83 {956.335449, 856.335449},
84 {1242.035522, 841.017761}},
85
86 {{75.312500, 1104.687500},
87 {338.982239, 1142.035522},
88 {640.000000, 1152.929688},
89 {941.017761, 1142.035522},
90 {1204.687500, 1104.687500}},
91 };
92
94 intrinsics.SetFocalLength(1300.0, 1300.0);
95 intrinsics.SetPrincipalPoint(640.0, 540.0);
96 intrinsics.SetRadialDistortion(-0.2, -0.1, -0.05);
97
98 double step = 1.0 / (N - 1);
99
100 for (int i = 0; i < N; i++) {
101 for (int j = 0; j < N; j++) {
102 double normalized_x = j * step - 0.5, normalized_y = i * step - 0.5;
103
104 double distorted_x, distorted_y;
105 intrinsics.ApplyIntrinsics(
106 normalized_x, normalized_y, &distorted_x, &distorted_y);
107
108 EXPECT_NEAR(expected[i][j][0], distorted_x, 1e-6);
109 EXPECT_NEAR(expected[i][j][1], distorted_y, 1e-6);
110 }
111 }
112}
113
115 const int N = 5;
116
117 double expected[N][N][2] = {
118 {{-0.524482, -0.437069},
119 {-0.226237, -0.403994},
120 {0.031876, -0.398446},
121 {0.293917, -0.408218},
122 {0.632438, -0.465028}},
123
124 {{-0.493496, -0.189173},
125 {-0.219052, -0.179936},
126 {0.030975, -0.178107},
127 {0.283742, -0.181280},
128 {0.574557, -0.194335}},
129
130 {{-0.488013, 0.032534},
131 {-0.217537, 0.031077},
132 {0.030781, 0.030781},
133 {0.281635, 0.031293},
134 {0.566344, 0.033314}},
135
136 {{-0.498696, 0.257660},
137 {-0.220424, 0.244041},
138 {0.031150, 0.241409},
139 {0.285660, 0.245985},
140 {0.582670, 0.265629}},
141
142 {{-0.550617, 0.532263},
143 {-0.230399, 0.477255},
144 {0.032380, 0.469510},
145 {0.299986, 0.483311},
146 {0.684740, 0.584043}},
147 };
148
150 intrinsics.SetFocalLength(1300.0, 1300.0);
151 intrinsics.SetPrincipalPoint(600.0, 500.0);
152 intrinsics.SetRadialDistortion(-0.2, -0.1, -0.05);
153
154 double step_x = 1280.0 / (N - 1), step_y = 1080.0 / (N - 1);
155
156 for (int i = 0; i < N; i++) {
157 for (int j = 0; j < N; j++) {
158 double distorted_x = j * step_x, distorted_y = i * step_y;
159
160 double normalized_x, normalized_y;
161 intrinsics.InvertIntrinsics(
162 distorted_x, distorted_y, &normalized_x, &normalized_y);
163
164 EXPECT_NEAR(expected[i][j][0], normalized_x, 1e-6);
165 EXPECT_NEAR(expected[i][j][1], normalized_y, 1e-6);
166 }
167 }
168}
169
170TEST(PolynomialCameraIntrinsics, ApplyIsInvertibleSimple) {
172 intrinsics.SetFocalLength(1300.0, 1300.0);
173 intrinsics.SetPrincipalPoint(640.0, 540.0);
174 intrinsics.SetRadialDistortion(-0.2, -0.1, -0.05);
175
176 // Scan over image coordinates, invert the intrinsics, then re-apply them to
177 // make sure the cycle gets back where it started.
178 for (double y = 0; y < 1000; y += 100) {
179 for (double x = 0; x < 1000; x += 100) {
180 double normalized_x, normalized_y;
181 intrinsics.InvertIntrinsics(x, y, &normalized_x, &normalized_y);
182
183 double xp, yp;
184 intrinsics.ApplyIntrinsics(normalized_x, normalized_y, &xp, &yp);
185
186 EXPECT_NEAR(x, xp, 1e-8) << "y: " << y;
187 EXPECT_NEAR(y, yp, 1e-8) << "x: " << x;
188 LG << "Error x: " << (x - xp);
189 LG << "Error y: " << (y - yp);
190 }
191 }
192}
193
194TEST(PolynomialCameraIntrinsics, IdentityDistortBuffer) {
195 const int w = 101, h = 101;
196 FloatImage image(h, w);
197 image.Fill(0);
198
199 DrawLine(0.0, h / 2.0, w - 1, h / 2.0, 1.0, &image);
200 DrawLine(0.0, h / 4.0, w - 1, h / 4.0, 1.0, &image);
201 DrawLine(0.0, h / 4.0 * 3.0, w - 1.0, h / 4.0 * 3.0, 1.0, &image);
202 DrawLine(w / 2.0, 0.0, w / 2.0, h - 1.0, 1.0, &image);
203 DrawLine(w / 4.0, 0.0, w / 4.0, h - 1.0, 1.0, &image);
204 DrawLine(w / 4.0 * 3.0, 0.0, w / 4.0 * 3.0, h - 1.0, 1.0, &image);
205
207 FloatImage distorted_image(h, w);
208 intrinsics.SetImageSize(w, h);
209 intrinsics.SetFocalLength(10.0, 10.0);
210 intrinsics.SetPrincipalPoint((double)w / 2.0, (double)h / 2.0);
211 intrinsics.SetRadialDistortion(0.0, 0.0, 0.0);
212 intrinsics.DistortBuffer(image.Data(),
213 image.Width(),
214 image.Height(),
215 0.0,
216 image.Depth(),
217 distorted_image.Data());
218
219 for (int x = 0; x < image.Width(); ++x) {
220 for (int y = 0; y < image.Height(); ++y) {
221 EXPECT_EQ(image(y, x), distorted_image(y, x));
222 }
223 }
224}
225
226TEST(PolynomialCameraIntrinsics, IdentityUndistortBuffer) {
227 const int w = 101, h = 101;
228 FloatImage image(h, w);
229 image.Fill(0);
230
231 DrawLine(0.0, h / 2.0, w - 1, h / 2.0, 1.0, &image);
232 DrawLine(0.0, h / 4.0, w - 1, h / 4.0, 1.0, &image);
233 DrawLine(0.0, h / 4.0 * 3.0, w - 1.0, h / 4.0 * 3.0, 1.0, &image);
234 DrawLine(w / 2.0, 0.0, w / 2.0, h - 1.0, 1.0, &image);
235 DrawLine(w / 4.0, 0.0, w / 4.0, h - 1.0, 1.0, &image);
236 DrawLine(w / 4.0 * 3.0, 0.0, w / 4.0 * 3.0, h - 1.0, 1.0, &image);
237
239 FloatImage distorted_image(h, w);
240 intrinsics.SetImageSize(w, h);
241 intrinsics.SetFocalLength(10.0, 10.0);
242 intrinsics.SetPrincipalPoint((double)w / 2.0, (double)h / 2.0);
243 intrinsics.SetRadialDistortion(0.0, 0.0, 0.0);
244 intrinsics.UndistortBuffer(image.Data(),
245 image.Width(),
246 image.Height(),
247 0.0,
248 image.Depth(),
249 distorted_image.Data());
250
251 for (int x = 0; x < image.Width(); ++x) {
252 for (int y = 0; y < image.Height(); ++y) {
253 EXPECT_EQ(image(y, x), distorted_image(y, x));
254 }
255 }
256}
257
258} // namespace libmv
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition btQuadWord.h:119
3D array (row, column, channel).
Definition array_nd.h:332
T * Data()
Pointer to the first element of the array.
Definition array_nd.h:187
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 UndistortBuffer(const PixelType *input_buffer, int width, int height, double overscan, int channels, PixelType *output_buffer)
void InvertIntrinsics(double image_x, double image_y, double *normalized_x, double *normalized_y) const 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
input_tx image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "preview_img") .compute_source("compositor_compute_preview.glsl") .do_static_compilation(true)
#define LG
#define N
TEST(PolynomialCameraIntrinsics2, ApplyOnFocalCenter)
void DrawLine(int xa, int ya, int xb, int yb, const Color &col, Image *pim)