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
52 namespace cv {
53 namespace detail {
54
55 template <class P>
warpPoint(const Point2f & pt,InputArray K,InputArray R)56 Point2f 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
64
65 template <class P>
buildMaps(Size src_size,InputArray K,InputArray R,OutputArray _xmap,OutputArray _ymap)66 Rect RotationWarperBase<P>::buildMaps(Size src_size, InputArray K, InputArray R, OutputArray _xmap, OutputArray _ymap)
67 {
68 projector_.setCameraParams(K, R);
69
70 Point dst_tl, dst_br;
71 detectResultRoi(src_size, dst_tl, dst_br);
72
73 _xmap.create(dst_br.y - dst_tl.y + 1, dst_br.x - dst_tl.x + 1, CV_32F);
74 _ymap.create(dst_br.y - dst_tl.y + 1, dst_br.x - dst_tl.x + 1, CV_32F);
75
76 Mat xmap = _xmap.getMat(), ymap = _ymap.getMat();
77
78 float x, y;
79 for (int v = dst_tl.y; v <= dst_br.y; ++v)
80 {
81 for (int u = dst_tl.x; u <= dst_br.x; ++u)
82 {
83 projector_.mapBackward(static_cast<float>(u), static_cast<float>(v), x, y);
84 xmap.at<float>(v - dst_tl.y, u - dst_tl.x) = x;
85 ymap.at<float>(v - dst_tl.y, u - dst_tl.x) = y;
86 }
87 }
88
89 return Rect(dst_tl, dst_br);
90 }
91
92
93 template <class P>
warp(InputArray src,InputArray K,InputArray R,int interp_mode,int border_mode,OutputArray dst)94 Point RotationWarperBase<P>::warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
95 OutputArray dst)
96 {
97 UMat xmap, ymap;
98 Rect dst_roi = buildMaps(src.size(), K, R, xmap, ymap);
99
100 dst.create(dst_roi.height + 1, dst_roi.width + 1, src.type());
101 remap(src, dst, xmap, ymap, interp_mode, border_mode);
102
103 return dst_roi.tl();
104 }
105
106
107 template <class P>
warpBackward(InputArray src,InputArray K,InputArray R,int interp_mode,int border_mode,Size dst_size,OutputArray dst)108 void RotationWarperBase<P>::warpBackward(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
109 Size dst_size, OutputArray dst)
110 {
111 projector_.setCameraParams(K, R);
112
113 Point src_tl, src_br;
114 detectResultRoi(dst_size, src_tl, src_br);
115
116 Size size = src.size();
117 CV_Assert(src_br.x - src_tl.x + 1 == size.width && src_br.y - src_tl.y + 1 == size.height);
118
119 Mat xmap(dst_size, CV_32F);
120 Mat ymap(dst_size, CV_32F);
121
122 float u, v;
123 for (int y = 0; y < dst_size.height; ++y)
124 {
125 for (int x = 0; x < dst_size.width; ++x)
126 {
127 projector_.mapForward(static_cast<float>(x), static_cast<float>(y), u, v);
128 xmap.at<float>(y, x) = u - src_tl.x;
129 ymap.at<float>(y, x) = v - src_tl.y;
130 }
131 }
132
133 dst.create(dst_size, src.type());
134 remap(src, dst, xmap, ymap, interp_mode, border_mode);
135 }
136
137
138 template <class P>
warpRoi(Size src_size,InputArray K,InputArray R)139 Rect RotationWarperBase<P>::warpRoi(Size src_size, InputArray K, InputArray R)
140 {
141 projector_.setCameraParams(K, R);
142
143 Point dst_tl, dst_br;
144 detectResultRoi(src_size, dst_tl, dst_br);
145
146 return Rect(dst_tl, Point(dst_br.x + 1, dst_br.y + 1));
147 }
148
149
150 template <class P>
detectResultRoi(Size src_size,Point & dst_tl,Point & dst_br)151 void RotationWarperBase<P>::detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br)
152 {
153 float tl_uf = std::numeric_limits<float>::max();
154 float tl_vf = std::numeric_limits<float>::max();
155 float br_uf = -std::numeric_limits<float>::max();
156 float br_vf = -std::numeric_limits<float>::max();
157
158 float u, v;
159 for (int y = 0; y < src_size.height; ++y)
160 {
161 for (int x = 0; x < src_size.width; ++x)
162 {
163 projector_.mapForward(static_cast<float>(x), static_cast<float>(y), u, v);
164 tl_uf = std::min(tl_uf, u); tl_vf = std::min(tl_vf, v);
165 br_uf = std::max(br_uf, u); br_vf = std::max(br_vf, v);
166 }
167 }
168
169 dst_tl.x = static_cast<int>(tl_uf);
170 dst_tl.y = static_cast<int>(tl_vf);
171 dst_br.x = static_cast<int>(br_uf);
172 dst_br.y = static_cast<int>(br_vf);
173 }
174
175
176 template <class P>
detectResultRoiByBorder(Size src_size,Point & dst_tl,Point & dst_br)177 void RotationWarperBase<P>::detectResultRoiByBorder(Size src_size, Point &dst_tl, Point &dst_br)
178 {
179 float tl_uf = std::numeric_limits<float>::max();
180 float tl_vf = std::numeric_limits<float>::max();
181 float br_uf = -std::numeric_limits<float>::max();
182 float br_vf = -std::numeric_limits<float>::max();
183
184 float u, v;
185 for (float x = 0; x < src_size.width; ++x)
186 {
187 projector_.mapForward(static_cast<float>(x), 0, u, v);
188 tl_uf = std::min(tl_uf, u); tl_vf = std::min(tl_vf, v);
189 br_uf = std::max(br_uf, u); br_vf = std::max(br_vf, v);
190
191 projector_.mapForward(static_cast<float>(x), static_cast<float>(src_size.height - 1), u, v);
192 tl_uf = std::min(tl_uf, u); tl_vf = std::min(tl_vf, v);
193 br_uf = std::max(br_uf, u); br_vf = std::max(br_vf, v);
194 }
195 for (int y = 0; y < src_size.height; ++y)
196 {
197 projector_.mapForward(0, static_cast<float>(y), u, v);
198 tl_uf = std::min(tl_uf, u); tl_vf = std::min(tl_vf, v);
199 br_uf = std::max(br_uf, u); br_vf = std::max(br_vf, v);
200
201 projector_.mapForward(static_cast<float>(src_size.width - 1), static_cast<float>(y), u, v);
202 tl_uf = std::min(tl_uf, u); tl_vf = std::min(tl_vf, v);
203 br_uf = std::max(br_uf, u); br_vf = std::max(br_vf, v);
204 }
205
206 dst_tl.x = static_cast<int>(tl_uf);
207 dst_tl.y = static_cast<int>(tl_vf);
208 dst_br.x = static_cast<int>(br_uf);
209 dst_br.y = static_cast<int>(br_vf);
210 }
211
212
213 inline
mapForward(float x,float y,float & u,float & v)214 void PlaneProjector::mapForward(float x, float y, float &u, float &v)
215 {
216 float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
217 float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
218 float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
219
220 x_ = t[0] + x_ / z_ * (1 - t[2]);
221 y_ = t[1] + y_ / z_ * (1 - t[2]);
222
223 u = scale * x_;
224 v = scale * y_;
225 }
226
227
228 inline
mapBackward(float u,float v,float & x,float & y)229 void PlaneProjector::mapBackward(float u, float v, float &x, float &y)
230 {
231 u = u / scale - t[0];
232 v = v / scale - t[1];
233
234 float z;
235 x = k_rinv[0] * u + k_rinv[1] * v + k_rinv[2] * (1 - t[2]);
236 y = k_rinv[3] * u + k_rinv[4] * v + k_rinv[5] * (1 - t[2]);
237 z = k_rinv[6] * u + k_rinv[7] * v + k_rinv[8] * (1 - t[2]);
238
239 x /= z;
240 y /= z;
241 }
242
243
244 inline
mapForward(float x,float y,float & u,float & v)245 void SphericalProjector::mapForward(float x, float y, float &u, float &v)
246 {
247 float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
248 float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
249 float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
250
251 u = scale * atan2f(x_, z_);
252 float w = y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_);
253 v = scale * (static_cast<float>(CV_PI) - acosf(w == w ? w : 0));
254 }
255
256
257 inline
mapBackward(float u,float v,float & x,float & y)258 void SphericalProjector::mapBackward(float u, float v, float &x, float &y)
259 {
260 u /= scale;
261 v /= scale;
262
263 float sinv = sinf(static_cast<float>(CV_PI) - v);
264 float x_ = sinv * sinf(u);
265 float y_ = cosf(static_cast<float>(CV_PI) - v);
266 float z_ = sinv * cosf(u);
267
268 float z;
269 x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
270 y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
271 z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
272
273 if (z > 0) { x /= z; y /= z; }
274 else x = y = -1;
275 }
276
277
278 inline
mapForward(float x,float y,float & u,float & v)279 void CylindricalProjector::mapForward(float x, float y, float &u, float &v)
280 {
281 float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
282 float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
283 float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
284
285 u = scale * atan2f(x_, z_);
286 v = scale * y_ / sqrtf(x_ * x_ + z_ * z_);
287 }
288
289
290 inline
mapBackward(float u,float v,float & x,float & y)291 void CylindricalProjector::mapBackward(float u, float v, float &x, float &y)
292 {
293 u /= scale;
294 v /= scale;
295
296 float x_ = sinf(u);
297 float y_ = v;
298 float z_ = cosf(u);
299
300 float z;
301 x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
302 y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
303 z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
304
305 if (z > 0) { x /= z; y /= z; }
306 else x = y = -1;
307 }
308
309 inline
mapForward(float x,float y,float & u,float & v)310 void FisheyeProjector::mapForward(float x, float y, float &u, float &v)
311 {
312 float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
313 float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
314 float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
315
316 float u_ = atan2f(x_, z_);
317 float v_ = (float)CV_PI - acosf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
318
319 u = scale * v_ * cosf(u_);
320 v = scale * v_ * sinf(u_);
321 }
322
323 inline
mapBackward(float u,float v,float & x,float & y)324 void FisheyeProjector::mapBackward(float u, float v, float &x, float &y)
325 {
326 u /= scale;
327 v /= scale;
328
329 float u_ = atan2f(v, u);
330 float v_ = sqrtf(u*u + v*v);
331
332 float sinv = sinf((float)CV_PI - v_);
333 float x_ = sinv * sinf(u_);
334 float y_ = cosf((float)CV_PI - v_);
335 float z_ = sinv * cosf(u_);
336
337 float z;
338 x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
339 y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
340 z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
341
342 if (z > 0) { x /= z; y /= z; }
343 else x = y = -1;
344 }
345
346 inline
mapForward(float x,float y,float & u,float & v)347 void StereographicProjector::mapForward(float x, float y, float &u, float &v)
348 {
349 float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
350 float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
351 float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
352
353 float u_ = atan2f(x_, z_);
354 float v_ = (float)CV_PI - acosf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
355
356 float r = sinf(v_) / (1 - cosf(v_));
357
358 u = scale * r * cos(u_);
359 v = scale * r * sin(u_);
360 }
361
362 inline
mapBackward(float u,float v,float & x,float & y)363 void StereographicProjector::mapBackward(float u, float v, float &x, float &y)
364 {
365 u /= scale;
366 v /= scale;
367
368 float u_ = atan2f(v, u);
369 float r = sqrtf(u*u + v*v);
370 float v_ = 2 * atanf(1.f / r);
371
372 float sinv = sinf((float)CV_PI - v_);
373 float x_ = sinv * sinf(u_);
374 float y_ = cosf((float)CV_PI - v_);
375 float z_ = sinv * cosf(u_);
376
377 float z;
378 x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
379 y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
380 z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
381
382 if (z > 0) { x /= z; y /= z; }
383 else x = y = -1;
384 }
385
386 inline
mapForward(float x,float y,float & u,float & v)387 void CompressedRectilinearProjector::mapForward(float x, float y, float &u, float &v)
388 {
389 float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
390 float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
391 float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
392
393 float u_ = atan2f(x_, z_);
394 float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
395
396 u = scale * a * tanf(u_ / a);
397 v = scale * b * tanf(v_) / cosf(u_);
398 }
399
400 inline
mapBackward(float u,float v,float & x,float & y)401 void CompressedRectilinearProjector::mapBackward(float u, float v, float &x, float &y)
402 {
403 u /= scale;
404 v /= scale;
405
406 float aatg = a * atanf(u / a);
407 float u_ = aatg;
408 float v_ = atanf(v * cosf(aatg) / b);
409
410 float cosv = cosf(v_);
411 float x_ = cosv * sinf(u_);
412 float y_ = sinf(v_);
413 float z_ = cosv * cosf(u_);
414
415 float z;
416 x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
417 y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
418 z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
419
420 if (z > 0) { x /= z; y /= z; }
421 else x = y = -1;
422 }
423
424 inline
mapForward(float x,float y,float & u,float & v)425 void CompressedRectilinearPortraitProjector::mapForward(float x, float y, float &u, float &v)
426 {
427 float y_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
428 float x_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
429 float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
430
431 float u_ = atan2f(x_, z_);
432 float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
433
434 u = - scale * a * tanf(u_ / a);
435 v = scale * b * tanf(v_) / cosf(u_);
436 }
437
438 inline
mapBackward(float u,float v,float & x,float & y)439 void CompressedRectilinearPortraitProjector::mapBackward(float u, float v, float &x, float &y)
440 {
441 u /= - scale;
442 v /= scale;
443
444 float aatg = a * atanf(u / a);
445 float u_ = aatg;
446 float v_ = atanf(v * cosf( aatg ) / b);
447
448 float cosv = cosf(v_);
449 float y_ = cosv * sinf(u_);
450 float x_ = sinf(v_);
451 float z_ = cosv * cosf(u_);
452
453 float z;
454 x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
455 y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
456 z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
457
458 if (z > 0) { x /= z; y /= z; }
459 else x = y = -1;
460 }
461
462 inline
mapForward(float x,float y,float & u,float & v)463 void PaniniProjector::mapForward(float x, float y, float &u, float &v)
464 {
465 float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
466 float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
467 float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
468
469 float u_ = atan2f(x_, z_);
470 float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
471
472 float tg = a * tanf(u_ / a);
473 u = scale * tg;
474
475 float sinu = sinf(u_);
476 if ( fabs(sinu) < 1E-7 )
477 v = scale * b * tanf(v_);
478 else
479 v = scale * b * tg * tanf(v_) / sinu;
480 }
481
482 inline
mapBackward(float u,float v,float & x,float & y)483 void PaniniProjector::mapBackward(float u, float v, float &x, float &y)
484 {
485 u /= scale;
486 v /= scale;
487
488 float lamda = a * atanf(u / a);
489 float u_ = lamda;
490
491 float v_;
492 if ( fabs(lamda) > 1E-7)
493 v_ = atanf(v * sinf(lamda) / (b * a * tanf(lamda / a)));
494 else
495 v_ = atanf(v / b);
496
497 float cosv = cosf(v_);
498 float x_ = cosv * sinf(u_);
499 float y_ = sinf(v_);
500 float z_ = cosv * cosf(u_);
501
502 float z;
503 x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
504 y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
505 z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
506
507 if (z > 0) { x /= z; y /= z; }
508 else x = y = -1;
509 }
510
511 inline
mapForward(float x,float y,float & u,float & v)512 void PaniniPortraitProjector::mapForward(float x, float y, float &u, float &v)
513 {
514 float y_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
515 float x_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
516 float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
517
518 float u_ = atan2f(x_, z_);
519 float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
520
521 float tg = a * tanf(u_ / a);
522 u = - scale * tg;
523
524 float sinu = sinf( u_ );
525 if ( fabs(sinu) < 1E-7 )
526 v = scale * b * tanf(v_);
527 else
528 v = scale * b * tg * tanf(v_) / sinu;
529 }
530
531 inline
mapBackward(float u,float v,float & x,float & y)532 void PaniniPortraitProjector::mapBackward(float u, float v, float &x, float &y)
533 {
534 u /= - scale;
535 v /= scale;
536
537 float lamda = a * atanf(u / a);
538 float u_ = lamda;
539
540 float v_;
541 if ( fabs(lamda) > 1E-7)
542 v_ = atanf(v * sinf(lamda) / (b * a * tanf(lamda/a)));
543 else
544 v_ = atanf(v / b);
545
546 float cosv = cosf(v_);
547 float y_ = cosv * sinf(u_);
548 float x_ = sinf(v_);
549 float z_ = cosv * cosf(u_);
550
551 float z;
552 x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
553 y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
554 z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
555
556 if (z > 0) { x /= z; y /= z; }
557 else x = y = -1;
558 }
559
560 inline
mapForward(float x,float y,float & u,float & v)561 void MercatorProjector::mapForward(float x, float y, float &u, float &v)
562 {
563 float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
564 float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
565 float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
566
567 float u_ = atan2f(x_, z_);
568 float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
569
570 u = scale * u_;
571 v = scale * logf( tanf( (float)(CV_PI/4) + v_/2 ) );
572 }
573
574 inline
mapBackward(float u,float v,float & x,float & y)575 void MercatorProjector::mapBackward(float u, float v, float &x, float &y)
576 {
577 u /= scale;
578 v /= scale;
579
580 float v_ = atanf( sinhf(v) );
581 float u_ = u;
582
583 float cosv = cosf(v_);
584 float x_ = cosv * sinf(u_);
585 float y_ = sinf(v_);
586 float z_ = cosv * cosf(u_);
587
588 float z;
589 x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
590 y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
591 z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
592
593 if (z > 0) { x /= z; y /= z; }
594 else x = y = -1;
595 }
596
597 inline
mapForward(float x,float y,float & u,float & v)598 void TransverseMercatorProjector::mapForward(float x, float y, float &u, float &v)
599 {
600 float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
601 float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
602 float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
603
604 float u_ = atan2f(x_, z_);
605 float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
606
607 float B = cosf(v_) * sinf(u_);
608
609 u = scale / 2 * logf( (1+B) / (1-B) );
610 v = scale * atan2f(tanf(v_), cosf(u_));
611 }
612
613 inline
mapBackward(float u,float v,float & x,float & y)614 void TransverseMercatorProjector::mapBackward(float u, float v, float &x, float &y)
615 {
616 u /= scale;
617 v /= scale;
618
619 float v_ = asinf( sinf(v) / coshf(u) );
620 float u_ = atan2f( sinhf(u), cos(v) );
621
622 float cosv = cosf(v_);
623 float x_ = cosv * sinf(u_);
624 float y_ = sinf(v_);
625 float z_ = cosv * cosf(u_);
626
627 float z;
628 x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
629 y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
630 z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
631
632 if (z > 0) { x /= z; y /= z; }
633 else x = y = -1;
634 }
635
636 inline
mapForward(float x,float y,float & u0,float & v0)637 void SphericalPortraitProjector::mapForward(float x, float y, float &u0, float &v0)
638 {
639 float x0_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
640 float y0_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
641 float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
642
643 float x_ = y0_;
644 float y_ = x0_;
645 float u, v;
646
647 u = scale * atan2f(x_, z_);
648 v = scale * (static_cast<float>(CV_PI) - acosf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_)));
649
650 u0 = -u;//v;
651 v0 = v;//u;
652 }
653
654
655 inline
mapBackward(float u0,float v0,float & x,float & y)656 void SphericalPortraitProjector::mapBackward(float u0, float v0, float &x, float &y)
657 {
658 float u, v;
659 u = -u0;//v0;
660 v = v0;//u0;
661
662 u /= scale;
663 v /= scale;
664
665 float sinv = sinf(static_cast<float>(CV_PI) - v);
666 float x0_ = sinv * sinf(u);
667 float y0_ = cosf(static_cast<float>(CV_PI) - v);
668 float z_ = sinv * cosf(u);
669
670 float x_ = y0_;
671 float y_ = x0_;
672
673 float z;
674 x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
675 y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
676 z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
677
678 if (z > 0) { x /= z; y /= z; }
679 else x = y = -1;
680 }
681
682 inline
mapForward(float x,float y,float & u0,float & v0)683 void CylindricalPortraitProjector::mapForward(float x, float y, float &u0, float &v0)
684 {
685 float x0_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
686 float y0_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
687 float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
688
689 float x_ = y0_;
690 float y_ = x0_;
691 float u, v;
692
693 u = scale * atan2f(x_, z_);
694 v = scale * y_ / sqrtf(x_ * x_ + z_ * z_);
695
696 u0 = -u;//v;
697 v0 = v;//u;
698 }
699
700
701 inline
mapBackward(float u0,float v0,float & x,float & y)702 void CylindricalPortraitProjector::mapBackward(float u0, float v0, float &x, float &y)
703 {
704 float u, v;
705 u = -u0;//v0;
706 v = v0;//u0;
707
708 u /= scale;
709 v /= scale;
710
711 float x0_ = sinf(u);
712 float y0_ = v;
713 float z_ = cosf(u);
714
715 float x_ = y0_;
716 float y_ = x0_;
717
718 float z;
719 x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
720 y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
721 z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
722
723 if (z > 0) { x /= z; y /= z; }
724 else x = y = -1;
725 }
726
727 inline
mapForward(float x,float y,float & u0,float & v0)728 void PlanePortraitProjector::mapForward(float x, float y, float &u0, float &v0)
729 {
730 float x0_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
731 float y0_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
732 float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
733
734 float x_ = y0_;
735 float y_ = x0_;
736
737 x_ = t[0] + x_ / z_ * (1 - t[2]);
738 y_ = t[1] + y_ / z_ * (1 - t[2]);
739
740 float u,v;
741 u = scale * x_;
742 v = scale * y_;
743
744 u0 = -u;
745 v0 = v;
746 }
747
748
749 inline
mapBackward(float u0,float v0,float & x,float & y)750 void PlanePortraitProjector::mapBackward(float u0, float v0, float &x, float &y)
751 {
752 float u, v;
753 u = -u0;
754 v = v0;
755
756 u = u / scale - t[0];
757 v = v / scale - t[1];
758
759 float z;
760 x = k_rinv[0] * v + k_rinv[1] * u + k_rinv[2] * (1 - t[2]);
761 y = k_rinv[3] * v + k_rinv[4] * u + k_rinv[5] * (1 - t[2]);
762 z = k_rinv[6] * v + k_rinv[7] * u + k_rinv[8] * (1 - t[2]);
763
764 x /= z;
765 y /= z;
766 }
767
768
769 } // namespace detail
770 } // namespace cv
771
772 //! @endcond
773
774 #endif // __OPENCV_STITCHING_WARPERS_INL_HPP__
775