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> 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> 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> 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> 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> 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> 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> 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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