Renesas / opencv-lib

Dependents:   RZ_A2M_Mbed_samples

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers warpers_inl.hpp Source File

warpers_inl.hpp

00001 /*M///////////////////////////////////////////////////////////////////////////////////////
00002 //
00003 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
00004 //
00005 //  By downloading, copying, installing or using the software you agree to this license.
00006 //  If you do not agree to this license, do not download, install,
00007 //  copy or use the software.
00008 //
00009 //
00010 //                          License Agreement
00011 //                For Open Source Computer Vision Library
00012 //
00013 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
00014 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
00015 // Third party copyrights are property of their respective owners.
00016 //
00017 // Redistribution and use in source and binary forms, with or without modification,
00018 // are permitted provided that the following conditions are met:
00019 //
00020 //   * Redistribution's of source code must retain the above copyright notice,
00021 //     this list of conditions and the following disclaimer.
00022 //
00023 //   * Redistribution's in binary form must reproduce the above copyright notice,
00024 //     this list of conditions and the following disclaimer in the documentation
00025 //     and/or other materials provided with the distribution.
00026 //
00027 //   * The name of the copyright holders may not be used to endorse or promote products
00028 //     derived from this software without specific prior written permission.
00029 //
00030 // This software is provided by the copyright holders and contributors "as is" and
00031 // any express or implied warranties, including, but not limited to, the implied
00032 // warranties of merchantability and fitness for a particular purpose are disclaimed.
00033 // In no event shall the Intel Corporation or contributors be liable for any direct,
00034 // indirect, incidental, special, exemplary, or consequential damages
00035 // (including, but not limited to, procurement of substitute goods or services;
00036 // loss of use, data, or profits; or business interruption) however caused
00037 // and on any theory of liability, whether in contract, strict liability,
00038 // or tort (including negligence or otherwise) arising in any way out of
00039 // the use of this software, even if advised of the possibility of such damage.
00040 //
00041 //M*/
00042 
00043 #ifndef OPENCV_STITCHING_WARPERS_INL_HPP
00044 #define OPENCV_STITCHING_WARPERS_INL_HPP
00045 
00046 #include "opencv2/core.hpp"
00047 #include "warpers.hpp" // Make your IDE see declarations
00048 #include <limits>
00049 
00050 //! @cond IGNORED
00051 
00052 namespace cv {
00053 namespace detail {
00054 
00055 template <class P>
00056 Point2f RotationWarperBase<P>::warpPoint(const Point2f &pt, InputArray K, InputArray R)
00057 {
00058     projector_.setCameraParams(K, R);
00059     Point2f uv;
00060     projector_.mapForward(pt.x, pt.y, uv.x, uv.y);
00061     return uv;
00062 }
00063 
00064 
00065 template <class P>
00066 Rect RotationWarperBase<P>::buildMaps(Size src_size, InputArray K, InputArray R, OutputArray _xmap, OutputArray _ymap)
00067 {
00068     projector_.setCameraParams(K, R);
00069 
00070     Point dst_tl, dst_br;
00071     detectResultRoi(src_size, dst_tl, dst_br);
00072 
00073     _xmap.create(dst_br.y - dst_tl.y + 1, dst_br.x - dst_tl.x + 1, CV_32F);
00074     _ymap.create(dst_br.y - dst_tl.y + 1, dst_br.x - dst_tl.x + 1, CV_32F);
00075 
00076     Mat xmap = _xmap.getMat(), ymap = _ymap.getMat();
00077 
00078     float x, y;
00079     for (int v = dst_tl.y; v <= dst_br.y; ++v)
00080     {
00081         for (int u = dst_tl.x; u <= dst_br.x; ++u)
00082         {
00083             projector_.mapBackward(static_cast<float>(u), static_cast<float>(v), x, y);
00084             xmap.at<float>(v - dst_tl.y, u - dst_tl.x) = x;
00085             ymap.at<float>(v - dst_tl.y, u - dst_tl.x) = y;
00086         }
00087     }
00088 
00089     return Rect(dst_tl, dst_br);
00090 }
00091 
00092 
00093 template <class P>
00094 Point RotationWarperBase<P>::warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
00095                                   OutputArray dst)
00096 {
00097     UMat xmap, ymap;
00098     Rect dst_roi = buildMaps(src.size(), K, R, xmap, ymap);
00099 
00100     dst.create(dst_roi.height + 1, dst_roi.width + 1, src.type());
00101     remap(src, dst, xmap, ymap, interp_mode, border_mode);
00102 
00103     return dst_roi.tl();
00104 }
00105 
00106 
00107 template <class P>
00108 void RotationWarperBase<P>::warpBackward(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
00109                                          Size dst_size, OutputArray dst)
00110 {
00111     projector_.setCameraParams(K, R);
00112 
00113     Point src_tl, src_br;
00114     detectResultRoi(dst_size, src_tl, src_br);
00115 
00116     Size size = src.size();
00117     CV_Assert(src_br.x - src_tl.x + 1 == size.width && src_br.y - src_tl.y + 1 == size.height);
00118 
00119     Mat xmap(dst_size, CV_32F);
00120     Mat ymap(dst_size, CV_32F);
00121 
00122     float u, v;
00123     for (int y = 0; y < dst_size.height; ++y)
00124     {
00125         for (int x = 0; x < dst_size.width; ++x)
00126         {
00127             projector_.mapForward(static_cast<float>(x), static_cast<float>(y), u, v);
00128             xmap.at<float>(y, x) = u - src_tl.x;
00129             ymap.at<float>(y, x) = v - src_tl.y;
00130         }
00131     }
00132 
00133     dst.create(dst_size, src.type());
00134     remap(src, dst, xmap, ymap, interp_mode, border_mode);
00135 }
00136 
00137 
00138 template <class P>
00139 Rect RotationWarperBase<P>::warpRoi (Size src_size, InputArray K, InputArray R)
00140 {
00141     projector_.setCameraParams(K, R);
00142 
00143     Point dst_tl, dst_br;
00144     detectResultRoi(src_size, dst_tl, dst_br);
00145 
00146     return Rect(dst_tl, Point(dst_br.x + 1, dst_br.y + 1));
00147 }
00148 
00149 
00150 template <class P>
00151 void RotationWarperBase<P>::detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br)
00152 {
00153     float tl_uf = (std::numeric_limits<float>::max)();
00154     float tl_vf = (std::numeric_limits<float>::max)();
00155     float br_uf = -(std::numeric_limits<float>::max)();
00156     float br_vf = -(std::numeric_limits<float>::max)();
00157 
00158     float u, v;
00159     for (int y = 0; y < src_size.height; ++y)
00160     {
00161         for (int x = 0; x < src_size.width; ++x)
00162         {
00163             projector_.mapForward(static_cast<float>(x), static_cast<float>(y), u, v);
00164             tl_uf = (std::min)(tl_uf, u); tl_vf = (std::min)(tl_vf, v);
00165             br_uf = (std::max)(br_uf, u); br_vf = (std::max)(br_vf, v);
00166         }
00167     }
00168 
00169     dst_tl.x = static_cast<int>(tl_uf);
00170     dst_tl.y = static_cast<int>(tl_vf);
00171     dst_br.x = static_cast<int>(br_uf);
00172     dst_br.y = static_cast<int>(br_vf);
00173 }
00174 
00175 
00176 template <class P>
00177 void RotationWarperBase<P>::detectResultRoiByBorder(Size src_size, Point &dst_tl, Point &dst_br)
00178 {
00179     float tl_uf = (std::numeric_limits<float>::max)();
00180     float tl_vf = (std::numeric_limits<float>::max)();
00181     float br_uf = -(std::numeric_limits<float>::max)();
00182     float br_vf = -(std::numeric_limits<float>::max)();
00183 
00184     float u, v;
00185     for (float x = 0; x < src_size.width; ++x)
00186     {
00187         projector_.mapForward(static_cast<float>(x), 0, u, v);
00188         tl_uf = (std::min)(tl_uf, u); tl_vf = (std::min)(tl_vf, v);
00189         br_uf = (std::max)(br_uf, u); br_vf = (std::max)(br_vf, v);
00190 
00191         projector_.mapForward(static_cast<float>(x), static_cast<float>(src_size.height - 1), u, v);
00192         tl_uf = (std::min)(tl_uf, u); tl_vf = (std::min)(tl_vf, v);
00193         br_uf = (std::max)(br_uf, u); br_vf = (std::max)(br_vf, v);
00194     }
00195     for (int y = 0; y < src_size.height; ++y)
00196     {
00197         projector_.mapForward(0, static_cast<float>(y), u, v);
00198         tl_uf = (std::min)(tl_uf, u); tl_vf = (std::min)(tl_vf, v);
00199         br_uf = (std::max)(br_uf, u); br_vf = (std::max)(br_vf, v);
00200 
00201         projector_.mapForward(static_cast<float>(src_size.width - 1), static_cast<float>(y), u, v);
00202         tl_uf = (std::min)(tl_uf, u); tl_vf = (std::min)(tl_vf, v);
00203         br_uf = (std::max)(br_uf, u); br_vf = (std::max)(br_vf, v);
00204     }
00205 
00206     dst_tl.x = static_cast<int>(tl_uf);
00207     dst_tl.y = static_cast<int>(tl_vf);
00208     dst_br.x = static_cast<int>(br_uf);
00209     dst_br.y = static_cast<int>(br_vf);
00210 }
00211 
00212 
00213 inline
00214 void PlaneProjector::mapForward(float x, float y, float &u, float &v)
00215 {
00216     float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
00217     float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
00218     float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
00219 
00220     x_ = t[0] + x_ / z_ * (1 - t[2]);
00221     y_ = t[1] + y_ / z_ * (1 - t[2]);
00222 
00223     u = scale * x_;
00224     v = scale * y_;
00225 }
00226 
00227 
00228 inline
00229 void PlaneProjector::mapBackward(float u, float v, float &x, float &y)
00230 {
00231     u = u / scale - t[0];
00232     v = v / scale - t[1];
00233 
00234     float z;
00235     x = k_rinv[0] * u + k_rinv[1] * v + k_rinv[2] * (1 - t[2]);
00236     y = k_rinv[3] * u + k_rinv[4] * v + k_rinv[5] * (1 - t[2]);
00237     z = k_rinv[6] * u + k_rinv[7] * v + k_rinv[8] * (1 - t[2]);
00238 
00239     x /= z;
00240     y /= z;
00241 }
00242 
00243 
00244 inline
00245 void SphericalProjector::mapForward(float x, float y, float &u, float &v)
00246 {
00247     float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
00248     float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
00249     float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
00250 
00251     u = scale * atan2f(x_, z_);
00252     float w = y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_);
00253     v = scale * (static_cast<float>(CV_PI) - acosf(w == w ? w : 0));
00254 }
00255 
00256 
00257 inline
00258 void SphericalProjector::mapBackward(float u, float v, float &x, float &y)
00259 {
00260     u /= scale;
00261     v /= scale;
00262 
00263     float sinv = sinf(static_cast<float>(CV_PI) - v);
00264     float x_ = sinv * sinf(u);
00265     float y_ = cosf(static_cast<float>(CV_PI) - v);
00266     float z_ = sinv * cosf(u);
00267 
00268     float z;
00269     x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
00270     y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
00271     z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
00272 
00273     if (z > 0) { x /= z; y /= z; }
00274     else x = y = -1;
00275 }
00276 
00277 
00278 inline
00279 void CylindricalProjector::mapForward(float x, float y, float &u, float &v)
00280 {
00281     float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
00282     float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
00283     float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
00284 
00285     u = scale * atan2f(x_, z_);
00286     v = scale * y_ / sqrtf(x_ * x_ + z_ * z_);
00287 }
00288 
00289 
00290 inline
00291 void CylindricalProjector::mapBackward(float u, float v, float &x, float &y)
00292 {
00293     u /= scale;
00294     v /= scale;
00295 
00296     float x_ = sinf(u);
00297     float y_ = v;
00298     float z_ = cosf(u);
00299 
00300     float z;
00301     x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
00302     y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
00303     z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
00304 
00305     if (z > 0) { x /= z; y /= z; }
00306     else x = y = -1;
00307 }
00308 
00309 inline
00310 void FisheyeProjector::mapForward(float x, float y, float &u, float &v)
00311 {
00312     float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
00313     float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
00314     float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
00315 
00316     float u_ = atan2f(x_, z_);
00317     float v_ = (float)CV_PI - acosf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
00318 
00319     u = scale * v_ * cosf(u_);
00320     v = scale * v_ * sinf(u_);
00321 }
00322 
00323 inline
00324 void FisheyeProjector::mapBackward(float u, float v, float &x, float &y)
00325 {
00326     u /= scale;
00327     v /= scale;
00328 
00329     float u_ = atan2f(v, u);
00330     float v_ = sqrtf(u*u + v*v);
00331 
00332     float sinv = sinf((float)CV_PI - v_);
00333     float x_ = sinv * sinf(u_);
00334     float y_ = cosf((float)CV_PI - v_);
00335     float z_ = sinv * cosf(u_);
00336 
00337     float z;
00338     x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
00339     y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
00340     z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
00341 
00342     if (z > 0) { x /= z; y /= z; }
00343     else x = y = -1;
00344 }
00345 
00346 inline
00347 void StereographicProjector::mapForward(float x, float y, float &u, float &v)
00348 {
00349     float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
00350     float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
00351     float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
00352 
00353     float u_ = atan2f(x_, z_);
00354     float v_ = (float)CV_PI - acosf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
00355 
00356     float r = sinf(v_) / (1 - cosf(v_));
00357 
00358     u = scale * r * cos(u_);
00359     v = scale * r * sin(u_);
00360 }
00361 
00362 inline
00363 void StereographicProjector::mapBackward(float u, float v, float &x, float &y)
00364 {
00365     u /= scale;
00366     v /= scale;
00367 
00368     float u_ = atan2f(v, u);
00369     float r = sqrtf(u*u + v*v);
00370     float v_ = 2 * atanf(1.f / r);
00371 
00372     float sinv = sinf((float)CV_PI - v_);
00373     float x_ = sinv * sinf(u_);
00374     float y_ = cosf((float)CV_PI - v_);
00375     float z_ = sinv * cosf(u_);
00376 
00377     float z;
00378     x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
00379     y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
00380     z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
00381 
00382     if (z > 0) { x /= z; y /= z; }
00383     else x = y = -1;
00384 }
00385 
00386 inline
00387 void CompressedRectilinearProjector::mapForward(float x, float y, float &u, float &v)
00388 {
00389     float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
00390     float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
00391     float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
00392 
00393     float u_ = atan2f(x_, z_);
00394     float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
00395 
00396     u = scale * a * tanf(u_ / a);
00397     v = scale * b * tanf(v_) / cosf(u_);
00398 }
00399 
00400 inline
00401 void CompressedRectilinearProjector::mapBackward(float u, float v, float &x, float &y)
00402 {
00403     u /= scale;
00404     v /= scale;
00405 
00406     float aatg = a * atanf(u / a);
00407     float u_ = aatg;
00408     float v_ = atanf(v * cosf(aatg) / b);
00409 
00410     float cosv = cosf(v_);
00411     float x_ = cosv * sinf(u_);
00412     float y_ = sinf(v_);
00413     float z_ = cosv * cosf(u_);
00414 
00415     float z;
00416     x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
00417     y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
00418     z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
00419 
00420     if (z > 0) { x /= z; y /= z; }
00421     else x = y = -1;
00422 }
00423 
00424 inline
00425 void CompressedRectilinearPortraitProjector::mapForward(float x, float y, float &u, float &v)
00426 {
00427     float y_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
00428     float x_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
00429     float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
00430 
00431     float u_ = atan2f(x_, z_);
00432     float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
00433 
00434     u = - scale * a * tanf(u_ / a);
00435     v = scale * b * tanf(v_) / cosf(u_);
00436 }
00437 
00438 inline
00439 void CompressedRectilinearPortraitProjector::mapBackward(float u, float v, float &x, float &y)
00440 {
00441     u /= - scale;
00442     v /= scale;
00443 
00444     float aatg = a * atanf(u / a);
00445     float u_ = aatg;
00446     float v_ = atanf(v * cosf( aatg ) / b);
00447 
00448     float cosv = cosf(v_);
00449     float y_ = cosv * sinf(u_);
00450     float x_ = sinf(v_);
00451     float z_ = cosv * cosf(u_);
00452 
00453     float z;
00454     x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
00455     y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
00456     z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
00457 
00458     if (z > 0) { x /= z; y /= z; }
00459     else x = y = -1;
00460 }
00461 
00462 inline
00463 void PaniniProjector::mapForward(float x, float y, float &u, float &v)
00464 {
00465     float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
00466     float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
00467     float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
00468 
00469     float u_ = atan2f(x_, z_);
00470     float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
00471 
00472     float tg = a * tanf(u_ / a);
00473     u = scale * tg;
00474 
00475     float sinu = sinf(u_);
00476     if ( fabs(sinu) < 1E-7 )
00477         v = scale * b * tanf(v_);
00478     else
00479         v = scale * b * tg * tanf(v_) / sinu;
00480 }
00481 
00482 inline
00483 void PaniniProjector::mapBackward(float u, float v, float &x, float &y)
00484 {
00485     u /= scale;
00486     v /= scale;
00487 
00488     float lamda = a * atanf(u / a);
00489     float u_ = lamda;
00490 
00491     float v_;
00492     if ( fabs(lamda) > 1E-7)
00493         v_ = atanf(v * sinf(lamda) / (b * a * tanf(lamda / a)));
00494     else
00495         v_ = atanf(v / b);
00496 
00497     float cosv = cosf(v_);
00498     float x_ = cosv * sinf(u_);
00499     float y_ = sinf(v_);
00500     float z_ = cosv * cosf(u_);
00501 
00502     float z;
00503     x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
00504     y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
00505     z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
00506 
00507     if (z > 0) { x /= z; y /= z; }
00508     else x = y = -1;
00509 }
00510 
00511 inline
00512 void PaniniPortraitProjector::mapForward(float x, float y, float &u, float &v)
00513 {
00514     float y_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
00515     float x_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
00516     float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
00517 
00518     float u_ = atan2f(x_, z_);
00519     float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
00520 
00521     float tg = a * tanf(u_ / a);
00522     u = - scale * tg;
00523 
00524     float sinu = sinf( u_ );
00525     if ( fabs(sinu) < 1E-7 )
00526         v = scale * b * tanf(v_);
00527     else
00528         v = scale * b * tg * tanf(v_) / sinu;
00529 }
00530 
00531 inline
00532 void PaniniPortraitProjector::mapBackward(float u, float v, float &x, float &y)
00533 {
00534     u /= - scale;
00535     v /= scale;
00536 
00537     float lamda = a * atanf(u / a);
00538     float u_ = lamda;
00539 
00540     float v_;
00541     if ( fabs(lamda) > 1E-7)
00542         v_ = atanf(v * sinf(lamda) / (b * a * tanf(lamda/a)));
00543     else
00544         v_ = atanf(v / b);
00545 
00546     float cosv = cosf(v_);
00547     float y_ = cosv * sinf(u_);
00548     float x_ = sinf(v_);
00549     float z_ = cosv * cosf(u_);
00550 
00551     float z;
00552     x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
00553     y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
00554     z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
00555 
00556     if (z > 0) { x /= z; y /= z; }
00557     else x = y = -1;
00558 }
00559 
00560 inline
00561 void MercatorProjector::mapForward(float x, float y, float &u, float &v)
00562 {
00563     float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
00564     float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
00565     float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
00566 
00567     float u_ = atan2f(x_, z_);
00568     float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
00569 
00570     u = scale * u_;
00571     v = scale * logf( tanf( (float)(CV_PI/4) + v_/2 ) );
00572 }
00573 
00574 inline
00575 void MercatorProjector::mapBackward(float u, float v, float &x, float &y)
00576 {
00577     u /= scale;
00578     v /= scale;
00579 
00580     float v_ = atanf( sinhf(v) );
00581     float u_ = u;
00582 
00583     float cosv = cosf(v_);
00584     float x_ = cosv * sinf(u_);
00585     float y_ = sinf(v_);
00586     float z_ = cosv * cosf(u_);
00587 
00588     float z;
00589     x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
00590     y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
00591     z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
00592 
00593     if (z > 0) { x /= z; y /= z; }
00594     else x = y = -1;
00595 }
00596 
00597 inline
00598 void TransverseMercatorProjector::mapForward(float x, float y, float &u, float &v)
00599 {
00600     float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
00601     float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
00602     float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
00603 
00604     float u_ = atan2f(x_, z_);
00605     float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
00606 
00607     float B = cosf(v_) * sinf(u_);
00608 
00609     u = scale / 2 * logf( (1+B) / (1-B) );
00610     v = scale * atan2f(tanf(v_), cosf(u_));
00611 }
00612 
00613 inline
00614 void TransverseMercatorProjector::mapBackward(float u, float v, float &x, float &y)
00615 {
00616     u /= scale;
00617     v /= scale;
00618 
00619     float v_ = asinf( sinf(v) / coshf(u) );
00620     float u_ = atan2f( sinhf(u), cos(v) );
00621 
00622     float cosv = cosf(v_);
00623     float x_ = cosv * sinf(u_);
00624     float y_ = sinf(v_);
00625     float z_ = cosv * cosf(u_);
00626 
00627     float z;
00628     x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
00629     y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
00630     z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
00631 
00632     if (z > 0) { x /= z; y /= z; }
00633     else x = y = -1;
00634 }
00635 
00636 inline
00637 void SphericalPortraitProjector::mapForward(float x, float y, float &u0, float &v0)
00638 {
00639     float x0_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
00640     float y0_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
00641     float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
00642 
00643     float x_ = y0_;
00644     float y_ = x0_;
00645     float u, v;
00646 
00647     u = scale * atan2f(x_, z_);
00648     v = scale * (static_cast<float>(CV_PI) - acosf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_)));
00649 
00650     u0 = -u;//v;
00651     v0 = v;//u;
00652 }
00653 
00654 
00655 inline
00656 void SphericalPortraitProjector::mapBackward(float u0, float v0, float &x, float &y)
00657 {
00658     float u, v;
00659     u = -u0;//v0;
00660     v = v0;//u0;
00661 
00662     u /= scale;
00663     v /= scale;
00664 
00665     float sinv = sinf(static_cast<float>(CV_PI) - v);
00666     float x0_ = sinv * sinf(u);
00667     float y0_ = cosf(static_cast<float>(CV_PI) - v);
00668     float z_ = sinv * cosf(u);
00669 
00670     float x_ = y0_;
00671     float y_ = x0_;
00672 
00673     float z;
00674     x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
00675     y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
00676     z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
00677 
00678     if (z > 0) { x /= z; y /= z; }
00679     else x = y = -1;
00680 }
00681 
00682 inline
00683 void CylindricalPortraitProjector::mapForward(float x, float y, float &u0, float &v0)
00684 {
00685     float x0_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
00686     float y0_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
00687     float z_  = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
00688 
00689     float x_ = y0_;
00690     float y_ = x0_;
00691     float u, v;
00692 
00693     u = scale * atan2f(x_, z_);
00694     v = scale * y_ / sqrtf(x_ * x_ + z_ * z_);
00695 
00696     u0 = -u;//v;
00697     v0 = v;//u;
00698 }
00699 
00700 
00701 inline
00702 void CylindricalPortraitProjector::mapBackward(float u0, float v0, float &x, float &y)
00703 {
00704     float u, v;
00705     u = -u0;//v0;
00706     v = v0;//u0;
00707 
00708     u /= scale;
00709     v /= scale;
00710 
00711     float x0_ = sinf(u);
00712     float y0_ = v;
00713     float z_  = cosf(u);
00714 
00715     float x_ = y0_;
00716     float y_ = x0_;
00717 
00718     float z;
00719     x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
00720     y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
00721     z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
00722 
00723     if (z > 0) { x /= z; y /= z; }
00724     else x = y = -1;
00725 }
00726 
00727 inline
00728 void PlanePortraitProjector::mapForward(float x, float y, float &u0, float &v0)
00729 {
00730     float x0_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
00731     float y0_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
00732     float z_  = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
00733 
00734     float x_ = y0_;
00735     float y_ = x0_;
00736 
00737     x_ = t[0] + x_ / z_ * (1 - t[2]);
00738     y_ = t[1] + y_ / z_ * (1 - t[2]);
00739 
00740     float u,v;
00741     u = scale * x_;
00742     v = scale * y_;
00743 
00744     u0 = -u;
00745     v0 = v;
00746 }
00747 
00748 
00749 inline
00750 void PlanePortraitProjector::mapBackward(float u0, float v0, float &x, float &y)
00751 {
00752     float u, v;
00753     u = -u0;
00754     v = v0;
00755 
00756     u = u / scale - t[0];
00757     v = v / scale - t[1];
00758 
00759     float z;
00760     x = k_rinv[0] * v + k_rinv[1] * u + k_rinv[2] * (1 - t[2]);
00761     y = k_rinv[3] * v + k_rinv[4] * u + k_rinv[5] * (1 - t[2]);
00762     z = k_rinv[6] * v + k_rinv[7] * u + k_rinv[8] * (1 - t[2]);
00763 
00764     x /= z;
00765     y /= z;
00766 }
00767 
00768 
00769 } // namespace detail
00770 } // namespace cv
00771 
00772 //! @endcond
00773 
00774 #endif // OPENCV_STITCHING_WARPERS_INL_HPP