• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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