include/opencv2/stitching/detail/warpers_inl.hpp
Go to the documentation of this file.
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/core.hpp"
00047 #include "warpers.hpp" // Make your IDE see declarations
00048 
00049 namespace cv {
00050 namespace detail {
00051 
00052 template <class P>
00053 Point2f RotationWarperBase<P>::warpPoint(const Point2f &pt, const Mat &K, const Mat &R)
00054 {
00055     projector_.setCameraParams(K, R);
00056     Point2f uv;
00057     projector_.mapForward(pt.x, pt.y, uv.x, uv.y);
00058     return uv;
00059 }
00060 
00061 
00062 template <class P>
00063 Rect RotationWarperBase<P>::buildMaps(Size src_size, const Mat &K, const Mat &R, Mat &xmap, Mat &ymap)
00064 {
00065     projector_.setCameraParams(K, R);
00066 
00067     Point dst_tl, dst_br;
00068     detectResultRoi(src_size, dst_tl, dst_br);
00069 
00070     xmap.create(dst_br.y - dst_tl.y + 1, dst_br.x - dst_tl.x + 1, CV_32F);
00071     ymap.create(dst_br.y - dst_tl.y + 1, dst_br.x - dst_tl.x + 1, CV_32F);
00072 
00073     float x, y;
00074     for (int v = dst_tl.y; v <= dst_br.y; ++v)
00075     {
00076         for (int u = dst_tl.x; u <= dst_br.x; ++u)
00077         {
00078             projector_.mapBackward(static_cast<float>(u), static_cast<float>(v), x, y);
00079             xmap.at<float>(v - dst_tl.y, u - dst_tl.x) = x;
00080             ymap.at<float>(v - dst_tl.y, u - dst_tl.x) = y;
00081         }
00082     }
00083 
00084     return Rect(dst_tl, dst_br);
00085 }
00086 
00087 
00088 template <class P>
00089 Point RotationWarperBase<P>::warp(const Mat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
00090                                   Mat &dst)
00091 {
00092     Mat xmap, ymap;
00093     Rect dst_roi = buildMaps(src.size(), K, R, xmap, ymap);
00094 
00095     dst.create(dst_roi.height + 1, dst_roi.width + 1, src.type());
00096     remap(src, dst, xmap, ymap, interp_mode, border_mode);
00097 
00098     return dst_roi.tl();
00099 }
00100 
00101 
00102 template <class P>
00103 void RotationWarperBase<P>::warpBackward(const Mat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
00104                                          Size dst_size, Mat &dst)
00105 {
00106     projector_.setCameraParams(K, R);
00107 
00108     Point src_tl, src_br;
00109     detectResultRoi(dst_size, src_tl, src_br);
00110     CV_Assert(src_br.x - src_tl.x + 1 == src.cols && src_br.y - src_tl.y + 1 == src.rows);
00111 
00112     Mat xmap(dst_size, CV_32F);
00113     Mat ymap(dst_size, CV_32F);
00114 
00115     float u, v;
00116     for (int y = 0; y < dst_size.height; ++y)
00117     {
00118         for (int x = 0; x < dst_size.width; ++x)
00119         {
00120             projector_.mapForward(static_cast<float>(x), static_cast<float>(y), u, v);
00121             xmap.at<float>(y, x) = u - src_tl.x;
00122             ymap.at<float>(y, x) = v - src_tl.y;
00123         }
00124     }
00125 
00126     dst.create(dst_size, src.type());
00127     remap(src, dst, xmap, ymap, interp_mode, border_mode);
00128 }
00129 
00130 
00131 template <class P>
00132 Rect RotationWarperBase<P>::warpRoi(Size src_size, const Mat &K, const Mat &R)
00133 {
00134     projector_.setCameraParams(K, R);
00135 
00136     Point dst_tl, dst_br;
00137     detectResultRoi(src_size, dst_tl, dst_br);
00138 
00139     return Rect(dst_tl, Point(dst_br.x + 1, dst_br.y + 1));
00140 }
00141 
00142 
00143 template <class P>
00144 void RotationWarperBase<P>::detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br)
00145 {
00146     float tl_uf = std::numeric_limits<float>::max();
00147     float tl_vf = std::numeric_limits<float>::max();
00148     float br_uf = -std::numeric_limits<float>::max();
00149     float br_vf = -std::numeric_limits<float>::max();
00150 
00151     float u, v;
00152     for (int y = 0; y < src_size.height; ++y)
00153     {
00154         for (int x = 0; x < src_size.width; ++x)
00155         {
00156             projector_.mapForward(static_cast<float>(x), static_cast<float>(y), u, v);
00157             tl_uf = std::min(tl_uf, u); tl_vf = std::min(tl_vf, v);
00158             br_uf = std::max(br_uf, u); br_vf = std::max(br_vf, v);
00159         }
00160     }
00161 
00162     dst_tl.x = static_cast<int>(tl_uf);
00163     dst_tl.y = static_cast<int>(tl_vf);
00164     dst_br.x = static_cast<int>(br_uf);
00165     dst_br.y = static_cast<int>(br_vf);
00166 }
00167 
00168 
00169 template <class P>
00170 void RotationWarperBase<P>::detectResultRoiByBorder(Size src_size, Point &dst_tl, Point &dst_br)
00171 {
00172     float tl_uf = std::numeric_limits<float>::max();
00173     float tl_vf = std::numeric_limits<float>::max();
00174     float br_uf = -std::numeric_limits<float>::max();
00175     float br_vf = -std::numeric_limits<float>::max();
00176 
00177     float u, v;
00178     for (float x = 0; x < src_size.width; ++x)
00179     {
00180         projector_.mapForward(static_cast<float>(x), 0, u, v);
00181         tl_uf = std::min(tl_uf, u); tl_vf = std::min(tl_vf, v);
00182         br_uf = std::max(br_uf, u); br_vf = std::max(br_vf, v);
00183 
00184         projector_.mapForward(static_cast<float>(x), static_cast<float>(src_size.height - 1), u, v);
00185         tl_uf = std::min(tl_uf, u); tl_vf = std::min(tl_vf, v);
00186         br_uf = std::max(br_uf, u); br_vf = std::max(br_vf, v);
00187     }
00188     for (int y = 0; y < src_size.height; ++y)
00189     {
00190         projector_.mapForward(0, static_cast<float>(y), u, v);
00191         tl_uf = std::min(tl_uf, u); tl_vf = std::min(tl_vf, v);
00192         br_uf = std::max(br_uf, u); br_vf = std::max(br_vf, v);
00193 
00194         projector_.mapForward(static_cast<float>(src_size.width - 1), static_cast<float>(y), u, v);
00195         tl_uf = std::min(tl_uf, u); tl_vf = std::min(tl_vf, v);
00196         br_uf = std::max(br_uf, u); br_vf = std::max(br_vf, v);
00197     }
00198 
00199     dst_tl.x = static_cast<int>(tl_uf);
00200     dst_tl.y = static_cast<int>(tl_vf);
00201     dst_br.x = static_cast<int>(br_uf);
00202     dst_br.y = static_cast<int>(br_vf);
00203 }
00204 
00205 
00206 inline
00207 void PlaneProjector::mapForward(float x, float y, float &u, float &v)
00208 {
00209     float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
00210     float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
00211     float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
00212 
00213     x_ = t[0] + x_ / z_ * (1 - t[2]);
00214     y_ = t[1] + y_ / z_ * (1 - t[2]);
00215 
00216     u = scale * x_;
00217     v = scale * y_;
00218 }
00219 
00220 
00221 inline
00222 void PlaneProjector::mapBackward(float u, float v, float &x, float &y)
00223 {
00224     u = u / scale - t[0];
00225     v = v / scale - t[1];
00226 
00227     float z;
00228     x = k_rinv[0] * u + k_rinv[1] * v + k_rinv[2] * (1 - t[2]);
00229     y = k_rinv[3] * u + k_rinv[4] * v + k_rinv[5] * (1 - t[2]);
00230     z = k_rinv[6] * u + k_rinv[7] * v + k_rinv[8] * (1 - t[2]);
00231 
00232     x /= z;
00233     y /= z;
00234 }
00235 
00236 
00237 inline
00238 void SphericalProjector::mapForward(float x, float y, float &u, float &v)
00239 {
00240     float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
00241     float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
00242     float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
00243 
00244     u = scale * atan2f(x_, z_);
00245     float w = y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_);
00246     v = scale * (static_cast<float>(CV_PI) - acosf(w == w ? w : 0));
00247 }
00248 
00249 
00250 inline
00251 void SphericalProjector::mapBackward(float u, float v, float &x, float &y)
00252 {
00253     u /= scale;
00254     v /= scale;
00255 
00256     float sinv = sinf(static_cast<float>(CV_PI) - v);
00257     float x_ = sinv * sinf(u);
00258     float y_ = cosf(static_cast<float>(CV_PI) - v);
00259     float z_ = sinv * cosf(u);
00260 
00261     float z;
00262     x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
00263     y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
00264     z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
00265 
00266     if (z > 0) { x /= z; y /= z; }
00267     else x = y = -1;
00268 }
00269 
00270 
00271 inline
00272 void CylindricalProjector::mapForward(float x, float y, float &u, float &v)
00273 {
00274     float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
00275     float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
00276     float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
00277 
00278     u = scale * atan2f(x_, z_);
00279     v = scale * y_ / sqrtf(x_ * x_ + z_ * z_);
00280 }
00281 
00282 
00283 inline
00284 void CylindricalProjector::mapBackward(float u, float v, float &x, float &y)
00285 {
00286     u /= scale;
00287     v /= scale;
00288 
00289     float x_ = sinf(u);
00290     float y_ = v;
00291     float z_ = cosf(u);
00292 
00293     float z;
00294     x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
00295     y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
00296     z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
00297 
00298     if (z > 0) { x /= z; y /= z; }
00299     else x = y = -1;
00300 }
00301 
00302 inline
00303 void FisheyeProjector::mapForward(float x, float y, float &u, float &v)
00304 {
00305     float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
00306     float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
00307     float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
00308 
00309     float u_ = atan2f(x_, z_);
00310     float v_ = (float)CV_PI - acosf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
00311 
00312     u = scale * v_ * cosf(u_);
00313     v = scale * v_ * sinf(u_);
00314 }
00315 
00316 inline
00317 void FisheyeProjector::mapBackward(float u, float v, float &x, float &y)
00318 {
00319     u /= scale;
00320     v /= scale;
00321 
00322     float u_ = atan2f(v, u);
00323     float v_ = sqrtf(u*u + v*v);
00324 
00325     float sinv = sinf((float)CV_PI - v_);
00326     float x_ = sinv * sinf(u_);
00327     float y_ = cosf((float)CV_PI - v_);
00328     float z_ = sinv * cosf(u_);
00329 
00330     float z;
00331     x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
00332     y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
00333     z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
00334 
00335     if (z > 0) { x /= z; y /= z; }
00336     else x = y = -1;
00337 }
00338 
00339 inline
00340 void StereographicProjector::mapForward(float x, float y, float &u, float &v)
00341 {
00342     float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
00343     float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
00344     float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
00345 
00346     float u_ = atan2f(x_, z_);
00347     float v_ = (float)CV_PI - acosf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
00348 
00349     float r = sinf(v_) / (1 - cosf(v_));
00350 
00351     u = scale * r * cos(u_);
00352     v = scale * r * sin(u_);
00353 }
00354 
00355 inline
00356 void StereographicProjector::mapBackward(float u, float v, float &x, float &y)
00357 {
00358     u /= scale;
00359     v /= scale;
00360 
00361     float u_ = atan2f(v, u);
00362     float r = sqrtf(u*u + v*v);
00363     float v_ = 2 * atanf(1.f / r);
00364 
00365     float sinv = sinf((float)CV_PI - v_);
00366     float x_ = sinv * sinf(u_);
00367     float y_ = cosf((float)CV_PI - v_);
00368     float z_ = sinv * cosf(u_);
00369 
00370     float z;
00371     x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
00372     y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
00373     z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
00374 
00375     if (z > 0) { x /= z; y /= z; }
00376     else x = y = -1;
00377 }
00378 
00379 inline
00380 void CompressedRectilinearProjector::mapForward(float x, float y, float &u, float &v)
00381 {
00382     float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
00383     float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
00384     float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
00385 
00386     float u_ = atan2f(x_, z_);
00387     float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
00388 
00389     u = scale * a * tanf(u_ / a);
00390     v = scale * b * tanf(v_) / cosf(u_);
00391 }
00392 
00393 inline
00394 void CompressedRectilinearProjector::mapBackward(float u, float v, float &x, float &y)
00395 {
00396     u /= scale;
00397     v /= scale;
00398 
00399     float aatg = a * atanf(u / a);
00400     float u_ = aatg;
00401     float v_ = atanf(v * cosf(aatg) / b);
00402 
00403     float cosv = cosf(v_);
00404     float x_ = cosv * sinf(u_);
00405     float y_ = sinf(v_);
00406     float z_ = cosv * cosf(u_);
00407 
00408     float z;
00409     x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
00410     y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
00411     z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
00412 
00413     if (z > 0) { x /= z; y /= z; }
00414     else x = y = -1;
00415 }
00416 
00417 inline
00418 void CompressedRectilinearPortraitProjector::mapForward(float x, float y, float &u, float &v)
00419 {
00420     float y_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
00421     float x_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
00422     float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
00423 
00424     float u_ = atan2f(x_, z_);
00425     float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
00426 
00427     u = - scale * a * tanf(u_ / a);
00428     v = scale * b * tanf(v_) / cosf(u_);
00429 }
00430 
00431 inline
00432 void CompressedRectilinearPortraitProjector::mapBackward(float u, float v, float &x, float &y)
00433 {
00434     u /= - scale;
00435     v /= scale;
00436 
00437     float aatg = a * atanf(u / a);
00438     float u_ = aatg;
00439     float v_ = atanf(v * cosf( aatg ) / b);
00440 
00441     float cosv = cosf(v_);
00442     float y_ = cosv * sinf(u_);
00443     float x_ = sinf(v_);
00444     float z_ = cosv * cosf(u_);
00445 
00446     float z;
00447     x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
00448     y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
00449     z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
00450 
00451     if (z > 0) { x /= z; y /= z; }
00452     else x = y = -1;
00453 }
00454 
00455 inline
00456 void PaniniProjector::mapForward(float x, float y, float &u, float &v)
00457 {
00458     float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
00459     float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
00460     float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
00461 
00462     float u_ = atan2f(x_, z_);
00463     float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
00464 
00465     float tg = a * tanf(u_ / a);
00466     u = scale * tg;
00467 
00468     float sinu = sinf(u_);
00469     if ( fabs(sinu) < 1E-7 )
00470         v = scale * b * tanf(v_);
00471     else
00472         v = scale * b * tg * tanf(v_) / sinu;
00473 }
00474 
00475 inline
00476 void PaniniProjector::mapBackward(float u, float v, float &x, float &y)
00477 {
00478     u /= scale;
00479     v /= scale;
00480 
00481     float lamda = a * atanf(u / a);
00482     float u_ = lamda;
00483 
00484     float v_;
00485     if ( fabs(lamda) > 1E-7)
00486         v_ = atanf(v * sinf(lamda) / (b * a * tanf(lamda / a)));
00487     else
00488         v_ = atanf(v / b);
00489 
00490     float cosv = cosf(v_);
00491     float x_ = cosv * sinf(u_);
00492     float y_ = sinf(v_);
00493     float z_ = cosv * cosf(u_);
00494 
00495     float z;
00496     x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
00497     y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
00498     z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
00499 
00500     if (z > 0) { x /= z; y /= z; }
00501     else x = y = -1;
00502 }
00503 
00504 inline
00505 void PaniniPortraitProjector::mapForward(float x, float y, float &u, float &v)
00506 {
00507     float y_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
00508     float x_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
00509     float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
00510 
00511     float u_ = atan2f(x_, z_);
00512     float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
00513 
00514     float tg = a * tanf(u_ / a);
00515     u = - scale * tg;
00516 
00517     float sinu = sinf( u_ );
00518     if ( fabs(sinu) < 1E-7 )
00519         v = scale * b * tanf(v_);
00520     else
00521         v = scale * b * tg * tanf(v_) / sinu;
00522 }
00523 
00524 inline
00525 void PaniniPortraitProjector::mapBackward(float u, float v, float &x, float &y)
00526 {
00527     u /= - scale;
00528     v /= scale;
00529 
00530     float lamda = a * atanf(u / a);
00531     float u_ = lamda;
00532 
00533     float v_;
00534     if ( fabs(lamda) > 1E-7)
00535         v_ = atanf(v * sinf(lamda) / (b * a * tanf(lamda/a)));
00536     else
00537         v_ = atanf(v / b);
00538 
00539     float cosv = cosf(v_);
00540     float y_ = cosv * sinf(u_);
00541     float x_ = sinf(v_);
00542     float z_ = cosv * cosf(u_);
00543 
00544     float z;
00545     x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
00546     y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
00547     z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
00548 
00549     if (z > 0) { x /= z; y /= z; }
00550     else x = y = -1;
00551 }
00552 
00553 inline
00554 void MercatorProjector::mapForward(float x, float y, float &u, float &v)
00555 {
00556     float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
00557     float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
00558     float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
00559 
00560     float u_ = atan2f(x_, z_);
00561     float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
00562 
00563     u = scale * u_;
00564     v = scale * logf( tanf( (float)(CV_PI/4) + v_/2 ) );
00565 }
00566 
00567 inline
00568 void MercatorProjector::mapBackward(float u, float v, float &x, float &y)
00569 {
00570     u /= scale;
00571     v /= scale;
00572 
00573     float v_ = atanf( sinhf(v) );
00574     float u_ = u;
00575 
00576     float cosv = cosf(v_);
00577     float x_ = cosv * sinf(u_);
00578     float y_ = sinf(v_);
00579     float z_ = cosv * cosf(u_);
00580 
00581     float z;
00582     x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
00583     y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
00584     z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
00585 
00586     if (z > 0) { x /= z; y /= z; }
00587     else x = y = -1;
00588 }
00589 
00590 inline
00591 void TransverseMercatorProjector::mapForward(float x, float y, float &u, float &v)
00592 {
00593     float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
00594     float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
00595     float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
00596 
00597     float u_ = atan2f(x_, z_);
00598     float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
00599 
00600     float B = cosf(v_) * sinf(u_);
00601 
00602     u = scale / 2 * logf( (1+B) / (1-B) );
00603     v = scale * atan2f(tanf(v_), cosf(u_));
00604 }
00605 
00606 inline
00607 void TransverseMercatorProjector::mapBackward(float u, float v, float &x, float &y)
00608 {
00609     u /= scale;
00610     v /= scale;
00611 
00612     float v_ = asinf( sinf(v) / coshf(u) );
00613     float u_ = atan2f( sinhf(u), cos(v) );
00614 
00615     float cosv = cosf(v_);
00616     float x_ = cosv * sinf(u_);
00617     float y_ = sinf(v_);
00618     float z_ = cosv * cosf(u_);
00619 
00620     float z;
00621     x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
00622     y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
00623     z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
00624 
00625     if (z > 0) { x /= z; y /= z; }
00626     else x = y = -1;
00627 }
00628 
00629 inline
00630 void SphericalPortraitProjector::mapForward(float x, float y, float &u0, float &v0)
00631 {
00632     float x0_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
00633     float y0_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
00634     float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
00635 
00636     float x_ = y0_;
00637     float y_ = x0_;
00638     float u, v;
00639 
00640     u = scale * atan2f(x_, z_);
00641     v = scale * (static_cast<float>(CV_PI) - acosf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_)));
00642 
00643     u0 = -u;//v;
00644     v0 = v;//u;
00645 }
00646 
00647 
00648 inline
00649 void SphericalPortraitProjector::mapBackward(float u0, float v0, float &x, float &y)
00650 {
00651     float u, v;
00652     u = -u0;//v0;
00653     v = v0;//u0;
00654 
00655     u /= scale;
00656     v /= scale;
00657 
00658     float sinv = sinf(static_cast<float>(CV_PI) - v);
00659     float x0_ = sinv * sinf(u);
00660     float y0_ = cosf(static_cast<float>(CV_PI) - v);
00661     float z_ = sinv * cosf(u);
00662 
00663     float x_ = y0_;
00664     float y_ = x0_;
00665 
00666     float z;
00667     x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
00668     y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
00669     z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
00670 
00671     if (z > 0) { x /= z; y /= z; }
00672     else x = y = -1;
00673 }
00674 
00675 inline
00676 void CylindricalPortraitProjector::mapForward(float x, float y, float &u0, float &v0)
00677 {
00678     float x0_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
00679     float y0_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
00680     float z_  = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
00681 
00682     float x_ = y0_;
00683     float y_ = x0_;
00684     float u, v;
00685 
00686     u = scale * atan2f(x_, z_);
00687     v = scale * y_ / sqrtf(x_ * x_ + z_ * z_);
00688 
00689     u0 = -u;//v;
00690     v0 = v;//u;
00691 }
00692 
00693 
00694 inline
00695 void CylindricalPortraitProjector::mapBackward(float u0, float v0, float &x, float &y)
00696 {
00697     float u, v;
00698     u = -u0;//v0;
00699     v = v0;//u0;
00700 
00701     u /= scale;
00702     v /= scale;
00703 
00704     float x0_ = sinf(u);
00705     float y0_ = v;
00706     float z_  = cosf(u);
00707 
00708     float x_ = y0_;
00709     float y_ = x0_;
00710 
00711     float z;
00712     x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
00713     y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
00714     z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
00715 
00716     if (z > 0) { x /= z; y /= z; }
00717     else x = y = -1;
00718 }
00719 
00720 inline
00721 void PlanePortraitProjector::mapForward(float x, float y, float &u0, float &v0)
00722 {
00723     float x0_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
00724     float y0_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
00725     float z_  = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
00726 
00727     float x_ = y0_;
00728     float y_ = x0_;
00729 
00730     x_ = t[0] + x_ / z_ * (1 - t[2]);
00731     y_ = t[1] + y_ / z_ * (1 - t[2]);
00732 
00733     float u,v;
00734     u = scale * x_;
00735     v = scale * y_;
00736 
00737     u0 = -u;
00738     v0 = v;
00739 }
00740 
00741 
00742 inline
00743 void PlanePortraitProjector::mapBackward(float u0, float v0, float &x, float &y)
00744 {
00745     float u, v;
00746     u = -u0;
00747     v = v0;
00748 
00749     u = u / scale - t[0];
00750     v = v / scale - t[1];
00751 
00752     float z;
00753     x = k_rinv[0] * v + k_rinv[1] * u + k_rinv[2] * (1 - t[2]);
00754     y = k_rinv[3] * v + k_rinv[4] * u + k_rinv[5] * (1 - t[2]);
00755     z = k_rinv[6] * v + k_rinv[7] * u + k_rinv[8] * (1 - t[2]);
00756 
00757     x /= z;
00758     y /= z;
00759 }
00760 
00761 
00762 } // namespace detail
00763 } // namespace cv
00764 
00765 #endif // __OPENCV_STITCHING_WARPERS_INL_HPP__