1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software Foundation,
14 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 *
16 * The Original Code is Copyright (C) 2011 Blender Foundation.
17 * All rights reserved.
18 */
19
20 #include "intern/camera_intrinsics.h"
21 #include "intern/utildefines.h"
22 #include "libmv/simple_pipeline/camera_intrinsics.h"
23
24 using libmv::CameraIntrinsics;
25 using libmv::DivisionCameraIntrinsics;
26 using libmv::PolynomialCameraIntrinsics;
27 using libmv::NukeCameraIntrinsics;
28 using libmv::BrownCameraIntrinsics;
29
libmv_cameraIntrinsicsNew(const libmv_CameraIntrinsicsOptions * libmv_camera_intrinsics_options)30 libmv_CameraIntrinsics *libmv_cameraIntrinsicsNew(
31 const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options) {
32 CameraIntrinsics *camera_intrinsics =
33 libmv_cameraIntrinsicsCreateFromOptions(libmv_camera_intrinsics_options);
34 return (libmv_CameraIntrinsics *) camera_intrinsics;
35 }
36
libmv_cameraIntrinsicsCopy(const libmv_CameraIntrinsics * libmv_intrinsics)37 libmv_CameraIntrinsics *libmv_cameraIntrinsicsCopy(
38 const libmv_CameraIntrinsics* libmv_intrinsics) {
39 const CameraIntrinsics *orig_intrinsics =
40 (const CameraIntrinsics *) libmv_intrinsics;
41
42 CameraIntrinsics *new_intrinsics = NULL;
43 switch (orig_intrinsics->GetDistortionModelType()) {
44 case libmv::DISTORTION_MODEL_POLYNOMIAL:
45 {
46 const PolynomialCameraIntrinsics *polynomial_intrinsics =
47 static_cast<const PolynomialCameraIntrinsics*>(orig_intrinsics);
48 new_intrinsics = LIBMV_OBJECT_NEW(PolynomialCameraIntrinsics,
49 *polynomial_intrinsics);
50 break;
51 }
52 case libmv::DISTORTION_MODEL_DIVISION:
53 {
54 const DivisionCameraIntrinsics *division_intrinsics =
55 static_cast<const DivisionCameraIntrinsics*>(orig_intrinsics);
56 new_intrinsics = LIBMV_OBJECT_NEW(DivisionCameraIntrinsics,
57 *division_intrinsics);
58 break;
59 }
60 case libmv::DISTORTION_MODEL_NUKE:
61 {
62 const NukeCameraIntrinsics *nuke_intrinsics =
63 static_cast<const NukeCameraIntrinsics*>(orig_intrinsics);
64 new_intrinsics = LIBMV_OBJECT_NEW(NukeCameraIntrinsics,
65 *nuke_intrinsics);
66 break;
67 }
68 case libmv::DISTORTION_MODEL_BROWN:
69 {
70 const BrownCameraIntrinsics *brown_intrinsics =
71 static_cast<const BrownCameraIntrinsics*>(orig_intrinsics);
72 new_intrinsics = LIBMV_OBJECT_NEW(BrownCameraIntrinsics,
73 *brown_intrinsics);
74 break;
75 }
76 default:
77 assert(!"Unknown distortion model");
78 }
79 return (libmv_CameraIntrinsics *) new_intrinsics;
80 }
81
libmv_cameraIntrinsicsDestroy(libmv_CameraIntrinsics * libmv_intrinsics)82 void libmv_cameraIntrinsicsDestroy(libmv_CameraIntrinsics* libmv_intrinsics) {
83 LIBMV_OBJECT_DELETE(libmv_intrinsics, CameraIntrinsics);
84 }
85
libmv_cameraIntrinsicsUpdate(const libmv_CameraIntrinsicsOptions * libmv_camera_intrinsics_options,libmv_CameraIntrinsics * libmv_intrinsics)86 void libmv_cameraIntrinsicsUpdate(
87 const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options,
88 libmv_CameraIntrinsics* libmv_intrinsics) {
89 CameraIntrinsics *camera_intrinsics = (CameraIntrinsics *) libmv_intrinsics;
90
91 double focal_length = libmv_camera_intrinsics_options->focal_length;
92 double principal_x = libmv_camera_intrinsics_options->principal_point_x;
93 double principal_y = libmv_camera_intrinsics_options->principal_point_y;
94 int image_width = libmv_camera_intrinsics_options->image_width;
95 int image_height = libmv_camera_intrinsics_options->image_height;
96
97 /* Try avoid unnecessary updates, so pre-computed distortion grids
98 * are not freed.
99 */
100
101 camera_intrinsics->SetThreads(libmv_camera_intrinsics_options->num_threads);
102
103 if (camera_intrinsics->focal_length() != focal_length) {
104 camera_intrinsics->SetFocalLength(focal_length, focal_length);
105 }
106
107 if (camera_intrinsics->principal_point_x() != principal_x ||
108 camera_intrinsics->principal_point_y() != principal_y) {
109 camera_intrinsics->SetPrincipalPoint(principal_x, principal_y);
110 }
111
112 if (camera_intrinsics->image_width() != image_width ||
113 camera_intrinsics->image_height() != image_height) {
114 camera_intrinsics->SetImageSize(image_width, image_height);
115 }
116
117 switch (libmv_camera_intrinsics_options->distortion_model) {
118 case LIBMV_DISTORTION_MODEL_POLYNOMIAL:
119 {
120 assert(camera_intrinsics->GetDistortionModelType() ==
121 libmv::DISTORTION_MODEL_POLYNOMIAL);
122
123 PolynomialCameraIntrinsics *polynomial_intrinsics =
124 (PolynomialCameraIntrinsics *) camera_intrinsics;
125
126 double k1 = libmv_camera_intrinsics_options->polynomial_k1;
127 double k2 = libmv_camera_intrinsics_options->polynomial_k2;
128 double k3 = libmv_camera_intrinsics_options->polynomial_k3;
129
130 if (polynomial_intrinsics->k1() != k1 ||
131 polynomial_intrinsics->k2() != k2 ||
132 polynomial_intrinsics->k3() != k3) {
133 polynomial_intrinsics->SetRadialDistortion(k1, k2, k3);
134 }
135 break;
136 }
137
138 case LIBMV_DISTORTION_MODEL_DIVISION:
139 {
140 assert(camera_intrinsics->GetDistortionModelType() ==
141 libmv::DISTORTION_MODEL_DIVISION);
142
143 DivisionCameraIntrinsics *division_intrinsics =
144 (DivisionCameraIntrinsics *) camera_intrinsics;
145
146 double k1 = libmv_camera_intrinsics_options->division_k1;
147 double k2 = libmv_camera_intrinsics_options->division_k2;
148
149 if (division_intrinsics->k1() != k1 ||
150 division_intrinsics->k2() != k2) {
151 division_intrinsics->SetDistortion(k1, k2);
152 }
153
154 break;
155 }
156
157 case LIBMV_DISTORTION_MODEL_NUKE:
158 {
159 assert(camera_intrinsics->GetDistortionModelType() ==
160 libmv::DISTORTION_MODEL_NUKE);
161
162 NukeCameraIntrinsics *nuke_intrinsics =
163 (NukeCameraIntrinsics *) camera_intrinsics;
164
165 double k1 = libmv_camera_intrinsics_options->nuke_k1;
166 double k2 = libmv_camera_intrinsics_options->nuke_k2;
167
168 if (nuke_intrinsics->k1() != k1 ||
169 nuke_intrinsics->k2() != k2) {
170 nuke_intrinsics->SetDistortion(k1, k2);
171 }
172
173 break;
174 }
175
176 case LIBMV_DISTORTION_MODEL_BROWN:
177 {
178 assert(camera_intrinsics->GetDistortionModelType() ==
179 libmv::DISTORTION_MODEL_BROWN);
180
181 BrownCameraIntrinsics *brown_intrinsics =
182 (BrownCameraIntrinsics *) camera_intrinsics;
183
184 double k1 = libmv_camera_intrinsics_options->brown_k1;
185 double k2 = libmv_camera_intrinsics_options->brown_k2;
186 double k3 = libmv_camera_intrinsics_options->brown_k3;
187 double k4 = libmv_camera_intrinsics_options->brown_k4;
188
189 if (brown_intrinsics->k1() != k1 ||
190 brown_intrinsics->k2() != k2 ||
191 brown_intrinsics->k3() != k3 ||
192 brown_intrinsics->k4() != k4) {
193 brown_intrinsics->SetRadialDistortion(k1, k2, k3, k4);
194 }
195
196 double p1 = libmv_camera_intrinsics_options->brown_p1;
197 double p2 = libmv_camera_intrinsics_options->brown_p2;
198
199 if (brown_intrinsics->p1() != p1 || brown_intrinsics->p2() != p2) {
200 brown_intrinsics->SetTangentialDistortion(p1, p2);
201 }
202 break;
203 }
204
205 default:
206 assert(!"Unknown distortion model");
207 }
208 }
209
libmv_cameraIntrinsicsSetThreads(libmv_CameraIntrinsics * libmv_intrinsics,int threads)210 void libmv_cameraIntrinsicsSetThreads(libmv_CameraIntrinsics* libmv_intrinsics,
211 int threads) {
212 CameraIntrinsics *camera_intrinsics = (CameraIntrinsics *) libmv_intrinsics;
213 camera_intrinsics->SetThreads(threads);
214 }
215
libmv_cameraIntrinsicsExtractOptions(const libmv_CameraIntrinsics * libmv_intrinsics,libmv_CameraIntrinsicsOptions * camera_intrinsics_options)216 void libmv_cameraIntrinsicsExtractOptions(
217 const libmv_CameraIntrinsics* libmv_intrinsics,
218 libmv_CameraIntrinsicsOptions* camera_intrinsics_options) {
219 const CameraIntrinsics *camera_intrinsics =
220 (const CameraIntrinsics *) libmv_intrinsics;
221
222 // Fill in options which are common for all distortion models.
223 camera_intrinsics_options->focal_length = camera_intrinsics->focal_length();
224 camera_intrinsics_options->principal_point_x =
225 camera_intrinsics->principal_point_x();
226 camera_intrinsics_options->principal_point_y =
227 camera_intrinsics->principal_point_y();
228
229 camera_intrinsics_options->image_width = camera_intrinsics->image_width();
230 camera_intrinsics_options->image_height = camera_intrinsics->image_height();
231
232 switch (camera_intrinsics->GetDistortionModelType()) {
233 case libmv::DISTORTION_MODEL_POLYNOMIAL:
234 {
235 const PolynomialCameraIntrinsics *polynomial_intrinsics =
236 static_cast<const PolynomialCameraIntrinsics *>(camera_intrinsics);
237 camera_intrinsics_options->distortion_model =
238 LIBMV_DISTORTION_MODEL_POLYNOMIAL;
239 camera_intrinsics_options->polynomial_k1 = polynomial_intrinsics->k1();
240 camera_intrinsics_options->polynomial_k2 = polynomial_intrinsics->k2();
241 camera_intrinsics_options->polynomial_k3 = polynomial_intrinsics->k3();
242 camera_intrinsics_options->polynomial_p1 = polynomial_intrinsics->p1();
243 camera_intrinsics_options->polynomial_p2 = polynomial_intrinsics->p2();
244 break;
245 }
246
247 case libmv::DISTORTION_MODEL_DIVISION:
248 {
249 const DivisionCameraIntrinsics *division_intrinsics =
250 static_cast<const DivisionCameraIntrinsics *>(camera_intrinsics);
251 camera_intrinsics_options->distortion_model =
252 LIBMV_DISTORTION_MODEL_DIVISION;
253 camera_intrinsics_options->division_k1 = division_intrinsics->k1();
254 camera_intrinsics_options->division_k2 = division_intrinsics->k2();
255 break;
256 }
257
258 case libmv::DISTORTION_MODEL_NUKE:
259 {
260 const NukeCameraIntrinsics *nuke_intrinsics =
261 static_cast<const NukeCameraIntrinsics *>(camera_intrinsics);
262 camera_intrinsics_options->distortion_model =
263 LIBMV_DISTORTION_MODEL_NUKE;
264 camera_intrinsics_options->nuke_k1 = nuke_intrinsics->k1();
265 camera_intrinsics_options->nuke_k2 = nuke_intrinsics->k2();
266 break;
267 }
268
269 case libmv::DISTORTION_MODEL_BROWN:
270 {
271 const BrownCameraIntrinsics *brown_intrinsics =
272 static_cast<const BrownCameraIntrinsics *>(camera_intrinsics);
273 camera_intrinsics_options->distortion_model =
274 LIBMV_DISTORTION_MODEL_BROWN;
275 camera_intrinsics_options->brown_k1 = brown_intrinsics->k1();
276 camera_intrinsics_options->brown_k2 = brown_intrinsics->k2();
277 camera_intrinsics_options->brown_k3 = brown_intrinsics->k3();
278 camera_intrinsics_options->brown_k4 = brown_intrinsics->k4();
279 camera_intrinsics_options->brown_p1 = brown_intrinsics->p1();
280 camera_intrinsics_options->brown_p2 = brown_intrinsics->p2();
281 break;
282 }
283
284 default:
285 assert(!"Unknown distortion model");
286 }
287 }
288
libmv_cameraIntrinsicsUndistortByte(const libmv_CameraIntrinsics * libmv_intrinsics,const unsigned char * source_image,int width,int height,float overscan,int channels,unsigned char * destination_image)289 void libmv_cameraIntrinsicsUndistortByte(
290 const libmv_CameraIntrinsics* libmv_intrinsics,
291 const unsigned char *source_image,
292 int width,
293 int height,
294 float overscan,
295 int channels,
296 unsigned char* destination_image) {
297 CameraIntrinsics *camera_intrinsics = (CameraIntrinsics *) libmv_intrinsics;
298 camera_intrinsics->UndistortBuffer(source_image,
299 width, height,
300 overscan,
301 channels,
302 destination_image);
303 }
304
libmv_cameraIntrinsicsUndistortFloat(const libmv_CameraIntrinsics * libmv_intrinsics,const float * source_image,int width,int height,float overscan,int channels,float * destination_image)305 void libmv_cameraIntrinsicsUndistortFloat(
306 const libmv_CameraIntrinsics* libmv_intrinsics,
307 const float* source_image,
308 int width,
309 int height,
310 float overscan,
311 int channels,
312 float* destination_image) {
313 CameraIntrinsics *intrinsics = (CameraIntrinsics *) libmv_intrinsics;
314 intrinsics->UndistortBuffer(source_image,
315 width, height,
316 overscan,
317 channels,
318 destination_image);
319 }
320
libmv_cameraIntrinsicsDistortByte(const struct libmv_CameraIntrinsics * libmv_intrinsics,const unsigned char * source_image,int width,int height,float overscan,int channels,unsigned char * destination_image)321 void libmv_cameraIntrinsicsDistortByte(
322 const struct libmv_CameraIntrinsics* libmv_intrinsics,
323 const unsigned char *source_image,
324 int width,
325 int height,
326 float overscan,
327 int channels,
328 unsigned char *destination_image) {
329 CameraIntrinsics *intrinsics = (CameraIntrinsics *) libmv_intrinsics;
330 intrinsics->DistortBuffer(source_image,
331 width, height,
332 overscan,
333 channels,
334 destination_image);
335 }
336
libmv_cameraIntrinsicsDistortFloat(const libmv_CameraIntrinsics * libmv_intrinsics,float * source_image,int width,int height,float overscan,int channels,float * destination_image)337 void libmv_cameraIntrinsicsDistortFloat(
338 const libmv_CameraIntrinsics* libmv_intrinsics,
339 float* source_image,
340 int width,
341 int height,
342 float overscan,
343 int channels,
344 float* destination_image) {
345 CameraIntrinsics *intrinsics = (CameraIntrinsics *) libmv_intrinsics;
346 intrinsics->DistortBuffer(source_image,
347 width, height,
348 overscan,
349 channels,
350 destination_image);
351 }
352
libmv_cameraIntrinsicsApply(const struct libmv_CameraIntrinsics * libmv_intrinsics,double x,double y,double * x1,double * y1)353 void libmv_cameraIntrinsicsApply(
354 const struct libmv_CameraIntrinsics* libmv_intrinsics,
355 double x,
356 double y,
357 double* x1,
358 double* y1) {
359 CameraIntrinsics *intrinsics = (CameraIntrinsics *) libmv_intrinsics;
360 intrinsics->ApplyIntrinsics(x, y, x1, y1);
361 }
362
libmv_cameraIntrinsicsInvert(const struct libmv_CameraIntrinsics * libmv_intrinsics,double x,double y,double * x1,double * y1)363 void libmv_cameraIntrinsicsInvert(
364 const struct libmv_CameraIntrinsics* libmv_intrinsics,
365 double x,
366 double y,
367 double* x1,
368 double* y1) {
369 CameraIntrinsics *intrinsics = (CameraIntrinsics *) libmv_intrinsics;
370 intrinsics->InvertIntrinsics(x, y, x1, y1);
371 }
372
libmv_cameraIntrinsicsFillFromOptions(const libmv_CameraIntrinsicsOptions * camera_intrinsics_options,CameraIntrinsics * camera_intrinsics)373 static void libmv_cameraIntrinsicsFillFromOptions(
374 const libmv_CameraIntrinsicsOptions* camera_intrinsics_options,
375 CameraIntrinsics* camera_intrinsics) {
376 camera_intrinsics->SetFocalLength(camera_intrinsics_options->focal_length,
377 camera_intrinsics_options->focal_length);
378
379 camera_intrinsics->SetPrincipalPoint(
380 camera_intrinsics_options->principal_point_x,
381 camera_intrinsics_options->principal_point_y);
382
383 camera_intrinsics->SetImageSize(camera_intrinsics_options->image_width,
384 camera_intrinsics_options->image_height);
385
386 switch (camera_intrinsics_options->distortion_model) {
387 case LIBMV_DISTORTION_MODEL_POLYNOMIAL:
388 {
389 PolynomialCameraIntrinsics *polynomial_intrinsics =
390 static_cast<PolynomialCameraIntrinsics*>(camera_intrinsics);
391
392 polynomial_intrinsics->SetRadialDistortion(
393 camera_intrinsics_options->polynomial_k1,
394 camera_intrinsics_options->polynomial_k2,
395 camera_intrinsics_options->polynomial_k3);
396
397 break;
398 }
399
400 case LIBMV_DISTORTION_MODEL_DIVISION:
401 {
402 DivisionCameraIntrinsics *division_intrinsics =
403 static_cast<DivisionCameraIntrinsics*>(camera_intrinsics);
404
405 division_intrinsics->SetDistortion(
406 camera_intrinsics_options->division_k1,
407 camera_intrinsics_options->division_k2);
408 break;
409 }
410
411 case LIBMV_DISTORTION_MODEL_NUKE:
412 {
413 NukeCameraIntrinsics *nuke_intrinsics =
414 static_cast<NukeCameraIntrinsics*>(camera_intrinsics);
415
416 nuke_intrinsics->SetDistortion(
417 camera_intrinsics_options->nuke_k1,
418 camera_intrinsics_options->nuke_k2);
419 break;
420 }
421
422 case LIBMV_DISTORTION_MODEL_BROWN:
423 {
424 BrownCameraIntrinsics *brown_intrinsics =
425 static_cast<BrownCameraIntrinsics*>(camera_intrinsics);
426
427 brown_intrinsics->SetRadialDistortion(
428 camera_intrinsics_options->brown_k1,
429 camera_intrinsics_options->brown_k2,
430 camera_intrinsics_options->brown_k3,
431 camera_intrinsics_options->brown_k4);
432 brown_intrinsics->SetTangentialDistortion(
433 camera_intrinsics_options->brown_p1,
434 camera_intrinsics_options->brown_p2);
435
436 break;
437 }
438
439 default:
440 assert(!"Unknown distortion model");
441 }
442 }
443
libmv_cameraIntrinsicsCreateFromOptions(const libmv_CameraIntrinsicsOptions * camera_intrinsics_options)444 CameraIntrinsics* libmv_cameraIntrinsicsCreateFromOptions(
445 const libmv_CameraIntrinsicsOptions* camera_intrinsics_options) {
446 CameraIntrinsics *camera_intrinsics = NULL;
447 switch (camera_intrinsics_options->distortion_model) {
448 case LIBMV_DISTORTION_MODEL_POLYNOMIAL:
449 camera_intrinsics = LIBMV_OBJECT_NEW(PolynomialCameraIntrinsics);
450 break;
451 case LIBMV_DISTORTION_MODEL_DIVISION:
452 camera_intrinsics = LIBMV_OBJECT_NEW(DivisionCameraIntrinsics);
453 break;
454 case LIBMV_DISTORTION_MODEL_NUKE:
455 camera_intrinsics = LIBMV_OBJECT_NEW(NukeCameraIntrinsics);
456 break;
457 case LIBMV_DISTORTION_MODEL_BROWN:
458 camera_intrinsics = LIBMV_OBJECT_NEW(BrownCameraIntrinsics);
459 break;
460 default:
461 assert(!"Unknown distortion model");
462 }
463 libmv_cameraIntrinsicsFillFromOptions(camera_intrinsics_options,
464 camera_intrinsics);
465 return camera_intrinsics;
466 }
467