00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
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"
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;
00644 v0 = v;
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;
00653 v = v0;
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;
00690 v0 = v;
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;
00699 v = v0;
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 }
00763 }
00764
00765 #endif // __OPENCV_STITCHING_WARPERS_INL_HPP__