1/*M///////////////////////////////////////////////////////////////////////////////////////
2//
3// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4//
5// By downloading, copying, installing or using the software you agree to this license.
6// If you do not agree to this license, do not download, install,
7// copy or use the software.
8//
9//
10// License Agreement
11// For Open Source Computer Vision Library
12//
13// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
14// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
15// Third party copyrights are property of their respective owners.
16//
17// Redistribution and use in source and binary forms, with or without modification,
18// are permitted provided that the following conditions are met:
19//
20// * Redistribution's of source code must retain the above copyright notice,
21// this list of conditions and the following disclaimer.
22//
23// * Redistribution's in binary form must reproduce the above copyright notice,
24// this list of conditions and the following disclaimer in the documentation
25// and/or other materials provided with the distribution.
26//
27// * The name of the copyright holders may not be used to endorse or promote products
28// derived from this software without specific prior written permission.
29//
30// This software is provided by the copyright holders and contributors "as is" and
31// any express or implied warranties, including, but not limited to, the implied
32// warranties of merchantability and fitness for a particular purpose are disclaimed.
33// In no event shall the Intel Corporation or contributors be liable for any direct,
34// indirect, incidental, special, exemplary, or consequential damages
35// (including, but not limited to, procurement of substitute goods or services;
36// loss of use, data, or profits; or business interruption) however caused
37// and on any theory of liability, whether in contract, strict liability,
38// or tort (including negligence or otherwise) arising in any way out of
39// the use of this software, even if advised of the possibility of such damage.
40//
41//M*/
42
43#ifndef OPENCV_STITCHING_WARPERS_INL_HPP
44#define OPENCV_STITCHING_WARPERS_INL_HPP
45
46#include "opencv2/core.hpp"
47#include "warpers.hpp" // Make your IDE see declarations
48#include <limits>
49
50//! @cond IGNORED
51
52namespace cv {
53namespace detail {
54
55template <class P>
56Point2f RotationWarperBase<P>::warpPoint(const Point2f &pt, InputArray K, InputArray R)
57{
58 projector_.setCameraParams(K, R);
59 Point2f uv;
60 projector_.mapForward(pt.x, pt.y, uv.x, uv.y);
61 return uv;
62}
63
64template <class P>
65Point2f RotationWarperBase<P>::warpPointBackward(const Point2f& pt, InputArray K, InputArray R)
66{
67 projector_.setCameraParams(K, R);
68 Point2f xy;
69 projector_.mapBackward(pt.x, pt.y, xy.x, xy.y);
70 return xy;
71}
72
73template <class P>
74Rect RotationWarperBase<P>::buildMaps(Size src_size, InputArray K, InputArray R, OutputArray _xmap, OutputArray _ymap)
75{
76 projector_.setCameraParams(K, R);
77
78 Point dst_tl, dst_br;
79 detectResultRoi(src_size, dst_tl, dst_br);
80
81 _xmap.create(rows: dst_br.y - dst_tl.y + 1, cols: dst_br.x - dst_tl.x + 1, CV_32F);
82 _ymap.create(rows: dst_br.y - dst_tl.y + 1, cols: dst_br.x - dst_tl.x + 1, CV_32F);
83
84 Mat xmap = _xmap.getMat(), ymap = _ymap.getMat();
85
86 float x, y;
87 for (int v = dst_tl.y; v <= dst_br.y; ++v)
88 {
89 for (int u = dst_tl.x; u <= dst_br.x; ++u)
90 {
91 projector_.mapBackward(static_cast<float>(u), static_cast<float>(v), x, y);
92 xmap.at<float>(i0: v - dst_tl.y, i1: u - dst_tl.x) = x;
93 ymap.at<float>(i0: v - dst_tl.y, i1: u - dst_tl.x) = y;
94 }
95 }
96
97 return Rect(dst_tl, dst_br);
98}
99
100
101template <class P>
102Point RotationWarperBase<P>::warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
103 OutputArray dst)
104{
105 UMat xmap, ymap;
106 Rect dst_roi = buildMaps(src_size: src.size(), K, R, xmap: xmap, ymap: ymap);
107
108 dst.create(rows: dst_roi.height + 1, cols: dst_roi.width + 1, type: src.type());
109 remap(src, dst, map1: xmap, map2: ymap, interpolation: interp_mode, borderMode: border_mode);
110
111 return dst_roi.tl();
112}
113
114
115template <class P>
116void RotationWarperBase<P>::warpBackward(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
117 Size dst_size, OutputArray dst)
118{
119 projector_.setCameraParams(K, R);
120
121 Point src_tl, src_br;
122 detectResultRoi(src_size: dst_size, dst_tl&: src_tl, dst_br&: src_br);
123
124 Size size = src.size();
125 CV_Assert(src_br.x - src_tl.x + 1 == size.width && src_br.y - src_tl.y + 1 == size.height);
126
127 Mat xmap(dst_size, CV_32F);
128 Mat ymap(dst_size, CV_32F);
129
130 float u, v;
131 for (int y = 0; y < dst_size.height; ++y)
132 {
133 for (int x = 0; x < dst_size.width; ++x)
134 {
135 projector_.mapForward(static_cast<float>(x), static_cast<float>(y), u, v);
136 xmap.at<float>(i0: y, i1: x) = u - src_tl.x;
137 ymap.at<float>(i0: y, i1: x) = v - src_tl.y;
138 }
139 }
140
141 dst.create(sz: dst_size, type: src.type());
142 remap(src, dst, map1: xmap, map2: ymap, interpolation: interp_mode, borderMode: border_mode);
143}
144
145
146template <class P>
147Rect RotationWarperBase<P>::warpRoi(Size src_size, InputArray K, InputArray R)
148{
149 projector_.setCameraParams(K, R);
150
151 Point dst_tl, dst_br;
152 detectResultRoi(src_size, dst_tl, dst_br);
153
154 return Rect(dst_tl, Point(dst_br.x + 1, dst_br.y + 1));
155}
156
157
158template <class P>
159void RotationWarperBase<P>::detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br)
160{
161 float tl_uf = (std::numeric_limits<float>::max)();
162 float tl_vf = (std::numeric_limits<float>::max)();
163 float br_uf = -(std::numeric_limits<float>::max)();
164 float br_vf = -(std::numeric_limits<float>::max)();
165
166 float u, v;
167 for (int y = 0; y < src_size.height; ++y)
168 {
169 for (int x = 0; x < src_size.width; ++x)
170 {
171 projector_.mapForward(static_cast<float>(x), static_cast<float>(y), u, v);
172 tl_uf = (std::min)(a: tl_uf, b: u); tl_vf = (std::min)(a: tl_vf, b: v);
173 br_uf = (std::max)(a: br_uf, b: u); br_vf = (std::max)(a: br_vf, b: v);
174 }
175 }
176
177 dst_tl.x = static_cast<int>(tl_uf);
178 dst_tl.y = static_cast<int>(tl_vf);
179 dst_br.x = static_cast<int>(br_uf);
180 dst_br.y = static_cast<int>(br_vf);
181}
182
183
184template <class P>
185void RotationWarperBase<P>::detectResultRoiByBorder(Size src_size, Point &dst_tl, Point &dst_br)
186{
187 float tl_uf = (std::numeric_limits<float>::max)();
188 float tl_vf = (std::numeric_limits<float>::max)();
189 float br_uf = -(std::numeric_limits<float>::max)();
190 float br_vf = -(std::numeric_limits<float>::max)();
191
192 float u, v;
193 for (float x = 0; x < src_size.width; ++x)
194 {
195 projector_.mapForward(static_cast<float>(x), 0, u, v);
196 tl_uf = (std::min)(a: tl_uf, b: u); tl_vf = (std::min)(a: tl_vf, b: v);
197 br_uf = (std::max)(a: br_uf, b: u); br_vf = (std::max)(a: br_vf, b: v);
198
199 projector_.mapForward(static_cast<float>(x), static_cast<float>(src_size.height - 1), u, v);
200 tl_uf = (std::min)(a: tl_uf, b: u); tl_vf = (std::min)(a: tl_vf, b: v);
201 br_uf = (std::max)(a: br_uf, b: u); br_vf = (std::max)(a: br_vf, b: v);
202 }
203 for (int y = 0; y < src_size.height; ++y)
204 {
205 projector_.mapForward(0, static_cast<float>(y), u, v);
206 tl_uf = (std::min)(a: tl_uf, b: u); tl_vf = (std::min)(a: tl_vf, b: v);
207 br_uf = (std::max)(a: br_uf, b: u); br_vf = (std::max)(a: br_vf, b: v);
208
209 projector_.mapForward(static_cast<float>(src_size.width - 1), static_cast<float>(y), u, v);
210 tl_uf = (std::min)(a: tl_uf, b: u); tl_vf = (std::min)(a: tl_vf, b: v);
211 br_uf = (std::max)(a: br_uf, b: u); br_vf = (std::max)(a: br_vf, b: v);
212 }
213
214 dst_tl.x = static_cast<int>(tl_uf);
215 dst_tl.y = static_cast<int>(tl_vf);
216 dst_br.x = static_cast<int>(br_uf);
217 dst_br.y = static_cast<int>(br_vf);
218}
219
220
221inline
222void PlaneProjector::mapForward(float x, float y, float &u, float &v)
223{
224 float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
225 float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
226 float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
227
228 x_ = t[0] + x_ / z_ * (1 - t[2]);
229 y_ = t[1] + y_ / z_ * (1 - t[2]);
230
231 u = scale * x_;
232 v = scale * y_;
233}
234
235
236inline
237void PlaneProjector::mapBackward(float u, float v, float &x, float &y)
238{
239 u = u / scale - t[0];
240 v = v / scale - t[1];
241
242 float z;
243 x = k_rinv[0] * u + k_rinv[1] * v + k_rinv[2] * (1 - t[2]);
244 y = k_rinv[3] * u + k_rinv[4] * v + k_rinv[5] * (1 - t[2]);
245 z = k_rinv[6] * u + k_rinv[7] * v + k_rinv[8] * (1 - t[2]);
246
247 x /= z;
248 y /= z;
249}
250
251
252inline
253void SphericalProjector::mapForward(float x, float y, float &u, float &v)
254{
255 float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
256 float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
257 float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
258
259 u = scale * atan2f(y: x_, x: z_);
260 float w = y_ / sqrtf(x: x_ * x_ + y_ * y_ + z_ * z_);
261 v = scale * (static_cast<float>(CV_PI) - acosf(x: w == w ? w : 0));
262}
263
264
265inline
266void SphericalProjector::mapBackward(float u, float v, float &x, float &y)
267{
268 u /= scale;
269 v /= scale;
270
271 float sinv = sinf(x: static_cast<float>(CV_PI) - v);
272 float x_ = sinv * sinf(x: u);
273 float y_ = cosf(x: static_cast<float>(CV_PI) - v);
274 float z_ = sinv * cosf(x: u);
275
276 float z;
277 x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
278 y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
279 z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
280
281 if (z > 0) { x /= z; y /= z; }
282 else x = y = -1;
283}
284
285
286inline
287void CylindricalProjector::mapForward(float x, float y, float &u, float &v)
288{
289 float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
290 float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
291 float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
292
293 u = scale * atan2f(y: x_, x: z_);
294 v = scale * y_ / sqrtf(x: x_ * x_ + z_ * z_);
295}
296
297
298inline
299void CylindricalProjector::mapBackward(float u, float v, float &x, float &y)
300{
301 u /= scale;
302 v /= scale;
303
304 float x_ = sinf(x: u);
305 float y_ = v;
306 float z_ = cosf(x: u);
307
308 float z;
309 x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
310 y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
311 z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
312
313 if (z > 0) { x /= z; y /= z; }
314 else x = y = -1;
315}
316
317inline
318void FisheyeProjector::mapForward(float x, float y, float &u, float &v)
319{
320 float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
321 float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
322 float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
323
324 float u_ = atan2f(y: x_, x: z_);
325 float v_ = (float)CV_PI - acosf(x: y_ / sqrtf(x: x_ * x_ + y_ * y_ + z_ * z_));
326
327 u = scale * v_ * cosf(x: u_);
328 v = scale * v_ * sinf(x: u_);
329}
330
331inline
332void FisheyeProjector::mapBackward(float u, float v, float &x, float &y)
333{
334 u /= scale;
335 v /= scale;
336
337 float u_ = atan2f(y: v, x: u);
338 float v_ = sqrtf(x: u*u + v*v);
339
340 float sinv = sinf(x: (float)CV_PI - v_);
341 float x_ = sinv * sinf(x: u_);
342 float y_ = cosf(x: (float)CV_PI - v_);
343 float z_ = sinv * cosf(x: u_);
344
345 float z;
346 x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
347 y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
348 z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
349
350 if (z > 0) { x /= z; y /= z; }
351 else x = y = -1;
352}
353
354inline
355void StereographicProjector::mapForward(float x, float y, float &u, float &v)
356{
357 float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
358 float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
359 float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
360
361 float u_ = atan2f(y: x_, x: z_);
362 float v_ = (float)CV_PI - acosf(x: y_ / sqrtf(x: x_ * x_ + y_ * y_ + z_ * z_));
363
364 float r = sinf(x: v_) / (1 - cosf(x: v_));
365
366 u = scale * r * std::cos(x: u_);
367 v = scale * r * std::sin(x: u_);
368}
369
370inline
371void StereographicProjector::mapBackward(float u, float v, float &x, float &y)
372{
373 u /= scale;
374 v /= scale;
375
376 float u_ = atan2f(y: v, x: u);
377 float r = sqrtf(x: u*u + v*v);
378 float v_ = 2 * atanf(x: 1.f / r);
379
380 float sinv = sinf(x: (float)CV_PI - v_);
381 float x_ = sinv * sinf(x: u_);
382 float y_ = cosf(x: (float)CV_PI - v_);
383 float z_ = sinv * cosf(x: u_);
384
385 float z;
386 x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
387 y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
388 z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
389
390 if (z > 0) { x /= z; y /= z; }
391 else x = y = -1;
392}
393
394inline
395void CompressedRectilinearProjector::mapForward(float x, float y, float &u, float &v)
396{
397 float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
398 float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
399 float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
400
401 float u_ = atan2f(y: x_, x: z_);
402 float v_ = asinf(x: y_ / sqrtf(x: x_ * x_ + y_ * y_ + z_ * z_));
403
404 u = scale * a * tanf(x: u_ / a);
405 v = scale * b * tanf(x: v_) / cosf(x: u_);
406}
407
408inline
409void CompressedRectilinearProjector::mapBackward(float u, float v, float &x, float &y)
410{
411 u /= scale;
412 v /= scale;
413
414 float aatg = a * atanf(x: u / a);
415 float u_ = aatg;
416 float v_ = atanf(x: v * cosf(x: aatg) / b);
417
418 float cosv = cosf(x: v_);
419 float x_ = cosv * sinf(x: u_);
420 float y_ = sinf(x: v_);
421 float z_ = cosv * cosf(x: u_);
422
423 float z;
424 x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
425 y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
426 z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
427
428 if (z > 0) { x /= z; y /= z; }
429 else x = y = -1;
430}
431
432inline
433void CompressedRectilinearPortraitProjector::mapForward(float x, float y, float &u, float &v)
434{
435 float y_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
436 float x_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
437 float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
438
439 float u_ = atan2f(y: x_, x: z_);
440 float v_ = asinf(x: y_ / sqrtf(x: x_ * x_ + y_ * y_ + z_ * z_));
441
442 u = - scale * a * tanf(x: u_ / a);
443 v = scale * b * tanf(x: v_) / cosf(x: u_);
444}
445
446inline
447void CompressedRectilinearPortraitProjector::mapBackward(float u, float v, float &x, float &y)
448{
449 u /= - scale;
450 v /= scale;
451
452 float aatg = a * atanf(x: u / a);
453 float u_ = aatg;
454 float v_ = atanf(x: v * cosf( x: aatg ) / b);
455
456 float cosv = cosf(x: v_);
457 float y_ = cosv * sinf(x: u_);
458 float x_ = sinf(x: v_);
459 float z_ = cosv * cosf(x: u_);
460
461 float z;
462 x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
463 y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
464 z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
465
466 if (z > 0) { x /= z; y /= z; }
467 else x = y = -1;
468}
469
470inline
471void PaniniProjector::mapForward(float x, float y, float &u, float &v)
472{
473 float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
474 float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
475 float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
476
477 float u_ = atan2f(y: x_, x: z_);
478 float v_ = asinf(x: y_ / sqrtf(x: x_ * x_ + y_ * y_ + z_ * z_));
479
480 float tg = a * tanf(x: u_ / a);
481 u = scale * tg;
482
483 float sinu = sinf(x: u_);
484 if ( fabs(x: sinu) < 1E-7 )
485 v = scale * b * tanf(x: v_);
486 else
487 v = scale * b * tg * tanf(x: v_) / sinu;
488}
489
490inline
491void PaniniProjector::mapBackward(float u, float v, float &x, float &y)
492{
493 u /= scale;
494 v /= scale;
495
496 float lamda = a * atanf(x: u / a);
497 float u_ = lamda;
498
499 float v_;
500 if ( fabs(x: lamda) > 1E-7)
501 v_ = atanf(x: v * sinf(x: lamda) / (b * a * tanf(x: lamda / a)));
502 else
503 v_ = atanf(x: v / b);
504
505 float cosv = cosf(x: v_);
506 float x_ = cosv * sinf(x: u_);
507 float y_ = sinf(x: v_);
508 float z_ = cosv * cosf(x: u_);
509
510 float z;
511 x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
512 y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
513 z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
514
515 if (z > 0) { x /= z; y /= z; }
516 else x = y = -1;
517}
518
519inline
520void PaniniPortraitProjector::mapForward(float x, float y, float &u, float &v)
521{
522 float y_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
523 float x_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
524 float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
525
526 float u_ = atan2f(y: x_, x: z_);
527 float v_ = asinf(x: y_ / sqrtf(x: x_ * x_ + y_ * y_ + z_ * z_));
528
529 float tg = a * tanf(x: u_ / a);
530 u = - scale * tg;
531
532 float sinu = sinf( x: u_ );
533 if ( fabs(x: sinu) < 1E-7 )
534 v = scale * b * tanf(x: v_);
535 else
536 v = scale * b * tg * tanf(x: v_) / sinu;
537}
538
539inline
540void PaniniPortraitProjector::mapBackward(float u, float v, float &x, float &y)
541{
542 u /= - scale;
543 v /= scale;
544
545 float lamda = a * atanf(x: u / a);
546 float u_ = lamda;
547
548 float v_;
549 if ( fabs(x: lamda) > 1E-7)
550 v_ = atanf(x: v * sinf(x: lamda) / (b * a * tanf(x: lamda/a)));
551 else
552 v_ = atanf(x: v / b);
553
554 float cosv = cosf(x: v_);
555 float y_ = cosv * sinf(x: u_);
556 float x_ = sinf(x: v_);
557 float z_ = cosv * cosf(x: u_);
558
559 float z;
560 x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
561 y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
562 z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
563
564 if (z > 0) { x /= z; y /= z; }
565 else x = y = -1;
566}
567
568inline
569void MercatorProjector::mapForward(float x, float y, float &u, float &v)
570{
571 float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
572 float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
573 float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
574
575 float u_ = atan2f(y: x_, x: z_);
576 float v_ = asinf(x: y_ / sqrtf(x: x_ * x_ + y_ * y_ + z_ * z_));
577
578 u = scale * u_;
579 v = scale * logf( x: tanf( x: (float)(CV_PI/4) + v_/2 ) );
580}
581
582inline
583void MercatorProjector::mapBackward(float u, float v, float &x, float &y)
584{
585 u /= scale;
586 v /= scale;
587
588 float v_ = atanf( x: sinhf(x: v) );
589 float u_ = u;
590
591 float cosv = cosf(x: v_);
592 float x_ = cosv * sinf(x: u_);
593 float y_ = sinf(x: v_);
594 float z_ = cosv * cosf(x: u_);
595
596 float z;
597 x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
598 y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
599 z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
600
601 if (z > 0) { x /= z; y /= z; }
602 else x = y = -1;
603}
604
605inline
606void TransverseMercatorProjector::mapForward(float x, float y, float &u, float &v)
607{
608 float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
609 float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
610 float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
611
612 float u_ = atan2f(y: x_, x: z_);
613 float v_ = asinf(x: y_ / sqrtf(x: x_ * x_ + y_ * y_ + z_ * z_));
614
615 float B = cosf(x: v_) * sinf(x: u_);
616
617 u = scale / 2 * logf( x: (1+B) / (1-B) );
618 v = scale * atan2f(y: tanf(x: v_), x: cosf(x: u_));
619}
620
621inline
622void TransverseMercatorProjector::mapBackward(float u, float v, float &x, float &y)
623{
624 u /= scale;
625 v /= scale;
626
627 float v_ = asinf( x: sinf(x: v) / coshf(x: u) );
628 float u_ = atan2f( y: sinhf(x: u), x: std::cos(x: v) );
629
630 float cosv = cosf(x: v_);
631 float x_ = cosv * sinf(x: u_);
632 float y_ = sinf(x: v_);
633 float z_ = cosv * cosf(x: u_);
634
635 float z;
636 x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
637 y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
638 z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
639
640 if (z > 0) { x /= z; y /= z; }
641 else x = y = -1;
642}
643
644inline
645void SphericalPortraitProjector::mapForward(float x, float y, float &u0, float &v0)
646{
647 float x0_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
648 float y0_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
649 float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
650
651 float x_ = y0_;
652 float y_ = x0_;
653 float u, v;
654
655 u = scale * atan2f(y: x_, x: z_);
656 v = scale * (static_cast<float>(CV_PI) - acosf(x: y_ / sqrtf(x: x_ * x_ + y_ * y_ + z_ * z_)));
657
658 u0 = -u;//v;
659 v0 = v;//u;
660}
661
662
663inline
664void SphericalPortraitProjector::mapBackward(float u0, float v0, float &x, float &y)
665{
666 float u, v;
667 u = -u0;//v0;
668 v = v0;//u0;
669
670 u /= scale;
671 v /= scale;
672
673 float sinv = sinf(x: static_cast<float>(CV_PI) - v);
674 float x0_ = sinv * sinf(x: u);
675 float y0_ = cosf(x: static_cast<float>(CV_PI) - v);
676 float z_ = sinv * cosf(x: u);
677
678 float x_ = y0_;
679 float y_ = x0_;
680
681 float z;
682 x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
683 y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
684 z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
685
686 if (z > 0) { x /= z; y /= z; }
687 else x = y = -1;
688}
689
690inline
691void CylindricalPortraitProjector::mapForward(float x, float y, float &u0, float &v0)
692{
693 float x0_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
694 float y0_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
695 float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
696
697 float x_ = y0_;
698 float y_ = x0_;
699 float u, v;
700
701 u = scale * atan2f(y: x_, x: z_);
702 v = scale * y_ / sqrtf(x: x_ * x_ + z_ * z_);
703
704 u0 = -u;//v;
705 v0 = v;//u;
706}
707
708
709inline
710void CylindricalPortraitProjector::mapBackward(float u0, float v0, float &x, float &y)
711{
712 float u, v;
713 u = -u0;//v0;
714 v = v0;//u0;
715
716 u /= scale;
717 v /= scale;
718
719 float x0_ = sinf(x: u);
720 float y0_ = v;
721 float z_ = cosf(x: u);
722
723 float x_ = y0_;
724 float y_ = x0_;
725
726 float z;
727 x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
728 y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
729 z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
730
731 if (z > 0) { x /= z; y /= z; }
732 else x = y = -1;
733}
734
735inline
736void PlanePortraitProjector::mapForward(float x, float y, float &u0, float &v0)
737{
738 float x0_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
739 float y0_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
740 float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
741
742 float x_ = y0_;
743 float y_ = x0_;
744
745 x_ = t[0] + x_ / z_ * (1 - t[2]);
746 y_ = t[1] + y_ / z_ * (1 - t[2]);
747
748 float u,v;
749 u = scale * x_;
750 v = scale * y_;
751
752 u0 = -u;
753 v0 = v;
754}
755
756
757inline
758void PlanePortraitProjector::mapBackward(float u0, float v0, float &x, float &y)
759{
760 float u, v;
761 u = -u0;
762 v = v0;
763
764 u = u / scale - t[0];
765 v = v / scale - t[1];
766
767 float z;
768 x = k_rinv[0] * v + k_rinv[1] * u + k_rinv[2] * (1 - t[2]);
769 y = k_rinv[3] * v + k_rinv[4] * u + k_rinv[5] * (1 - t[2]);
770 z = k_rinv[6] * v + k_rinv[7] * u + k_rinv[8] * (1 - t[2]);
771
772 x /= z;
773 y /= z;
774}
775
776
777} // namespace detail
778} // namespace cv
779
780//! @endcond
781
782#endif // OPENCV_STITCHING_WARPERS_INL_HPP
783

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of opencv/modules/stitching/include/opencv2/stitching/detail/warpers_inl.hpp