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_HPP__ 44 #define __OPENCV_STITCHING_WARPERS_HPP__ 45 46 #include "opencv2/core.hpp" 47 #include "opencv2/core/cuda.hpp" 48 #include "opencv2/imgproc.hpp" 49 #include "opencv2/opencv_modules.hpp" 50 51 namespace cv { 52 namespace detail { 53 54 //! @addtogroup stitching_warp 55 //! @{ 56 57 /** @brief Rotation-only model image warper interface. 58 */ 59 class CV_EXPORTS RotationWarper 60 { 61 public: ~RotationWarper()62 virtual ~RotationWarper() {} 63 64 /** @brief Projects the image point. 65 66 @param pt Source point 67 @param K Camera intrinsic parameters 68 @param R Camera rotation matrix 69 @return Projected point 70 */ 71 virtual Point2f warpPoint(const Point2f &pt, InputArray K, InputArray R) = 0; 72 73 /** @brief Builds the projection maps according to the given camera data. 74 75 @param src_size Source image size 76 @param K Camera intrinsic parameters 77 @param R Camera rotation matrix 78 @param xmap Projection map for the x axis 79 @param ymap Projection map for the y axis 80 @return Projected image minimum bounding box 81 */ 82 virtual Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap) = 0; 83 84 /** @brief Projects the image. 85 86 @param src Source image 87 @param K Camera intrinsic parameters 88 @param R Camera rotation matrix 89 @param interp_mode Interpolation mode 90 @param border_mode Border extrapolation mode 91 @param dst Projected image 92 @return Project image top-left corner 93 */ 94 virtual Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, 95 OutputArray dst) = 0; 96 97 /** @brief Projects the image backward. 98 99 @param src Projected image 100 @param K Camera intrinsic parameters 101 @param R Camera rotation matrix 102 @param interp_mode Interpolation mode 103 @param border_mode Border extrapolation mode 104 @param dst_size Backward-projected image size 105 @param dst Backward-projected image 106 */ 107 virtual void warpBackward(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, 108 Size dst_size, OutputArray dst) = 0; 109 110 /** 111 @param src_size Source image bounding box 112 @param K Camera intrinsic parameters 113 @param R Camera rotation matrix 114 @return Projected image minimum bounding box 115 */ 116 virtual Rect warpRoi(Size src_size, InputArray K, InputArray R) = 0; 117 getScale() const118 virtual float getScale() const { return 1.f; } setScale(float)119 virtual void setScale(float) {} 120 }; 121 122 /** @brief Base class for warping logic implementation. 123 */ 124 struct CV_EXPORTS ProjectorBase 125 { 126 void setCameraParams(InputArray K = Mat::eye(3, 3, CV_32F), 127 InputArray R = Mat::eye(3, 3, CV_32F), 128 InputArray T = Mat::zeros(3, 1, CV_32F)); 129 130 float scale; 131 float k[9]; 132 float rinv[9]; 133 float r_kinv[9]; 134 float k_rinv[9]; 135 float t[3]; 136 }; 137 138 /** @brief Base class for rotation-based warper using a detail::ProjectorBase_ derived class. 139 */ 140 template <class P> 141 class CV_EXPORTS RotationWarperBase : public RotationWarper 142 { 143 public: 144 Point2f warpPoint(const Point2f &pt, InputArray K, InputArray R); 145 146 Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap); 147 148 Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, 149 OutputArray dst); 150 151 void warpBackward(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, 152 Size dst_size, OutputArray dst); 153 154 Rect warpRoi(Size src_size, InputArray K, InputArray R); 155 getScale() const156 float getScale() const { return projector_.scale; } setScale(float val)157 void setScale(float val) { projector_.scale = val; } 158 159 protected: 160 161 // Detects ROI of the destination image. It's correct for any projection. 162 virtual void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br); 163 164 // Detects ROI of the destination image by walking over image border. 165 // Correctness for any projection isn't guaranteed. 166 void detectResultRoiByBorder(Size src_size, Point &dst_tl, Point &dst_br); 167 168 P projector_; 169 }; 170 171 172 struct CV_EXPORTS PlaneProjector : ProjectorBase 173 { 174 void mapForward(float x, float y, float &u, float &v); 175 void mapBackward(float u, float v, float &x, float &y); 176 }; 177 178 /** @brief Warper that maps an image onto the z = 1 plane. 179 */ 180 class CV_EXPORTS PlaneWarper : public RotationWarperBase<PlaneProjector> 181 { 182 public: 183 /** @brief Construct an instance of the plane warper class. 184 185 @param scale Projected image scale multiplier 186 */ PlaneWarper(float scale=1.f)187 PlaneWarper(float scale = 1.f) { projector_.scale = scale; } 188 189 Point2f warpPoint(const Point2f &pt, InputArray K, InputArray R); 190 Point2f warpPoint(const Point2f &pt, InputArray K, InputArray R, InputArray T); 191 192 virtual Rect buildMaps(Size src_size, InputArray K, InputArray R, InputArray T, OutputArray xmap, OutputArray ymap); 193 Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap); 194 195 Point warp(InputArray src, InputArray K, InputArray R, 196 int interp_mode, int border_mode, OutputArray dst); 197 virtual Point warp(InputArray src, InputArray K, InputArray R, InputArray T, int interp_mode, int border_mode, 198 OutputArray dst); 199 200 Rect warpRoi(Size src_size, InputArray K, InputArray R); 201 Rect warpRoi(Size src_size, InputArray K, InputArray R, InputArray T); 202 203 protected: 204 void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br); 205 }; 206 207 208 struct CV_EXPORTS SphericalProjector : ProjectorBase 209 { 210 void mapForward(float x, float y, float &u, float &v); 211 void mapBackward(float u, float v, float &x, float &y); 212 }; 213 214 215 /** @brief Warper that maps an image onto the unit sphere located at the origin. 216 217 Projects image onto unit sphere with origin at (0, 0, 0). 218 Poles are located at (0, -1, 0) and (0, 1, 0) points. 219 */ 220 class CV_EXPORTS SphericalWarper : public RotationWarperBase<SphericalProjector> 221 { 222 public: 223 /** @brief Construct an instance of the spherical warper class. 224 225 @param scale Projected image scale multiplier 226 */ SphericalWarper(float scale)227 SphericalWarper(float scale) { projector_.scale = scale; } 228 229 Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap); 230 Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, OutputArray dst); 231 protected: 232 void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br); 233 }; 234 235 236 struct CV_EXPORTS CylindricalProjector : ProjectorBase 237 { 238 void mapForward(float x, float y, float &u, float &v); 239 void mapBackward(float u, float v, float &x, float &y); 240 }; 241 242 243 /** @brief Warper that maps an image onto the x\*x + z\*z = 1 cylinder. 244 */ 245 class CV_EXPORTS CylindricalWarper : public RotationWarperBase<CylindricalProjector> 246 { 247 public: 248 /** @brief Construct an instance of the cylindrical warper class. 249 250 @param scale Projected image scale multiplier 251 */ CylindricalWarper(float scale)252 CylindricalWarper(float scale) { projector_.scale = scale; } 253 254 Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap); 255 Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, OutputArray dst); 256 protected: detectResultRoi(Size src_size,Point & dst_tl,Point & dst_br)257 void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br) 258 { 259 RotationWarperBase<CylindricalProjector>::detectResultRoiByBorder(src_size, dst_tl, dst_br); 260 } 261 }; 262 263 264 struct CV_EXPORTS FisheyeProjector : ProjectorBase 265 { 266 void mapForward(float x, float y, float &u, float &v); 267 void mapBackward(float u, float v, float &x, float &y); 268 }; 269 270 271 class CV_EXPORTS FisheyeWarper : public RotationWarperBase<FisheyeProjector> 272 { 273 public: FisheyeWarper(float scale)274 FisheyeWarper(float scale) { projector_.scale = scale; } 275 }; 276 277 278 struct CV_EXPORTS StereographicProjector : ProjectorBase 279 { 280 void mapForward(float x, float y, float &u, float &v); 281 void mapBackward(float u, float v, float &x, float &y); 282 }; 283 284 285 class CV_EXPORTS StereographicWarper : public RotationWarperBase<StereographicProjector> 286 { 287 public: StereographicWarper(float scale)288 StereographicWarper(float scale) { projector_.scale = scale; } 289 }; 290 291 292 struct CV_EXPORTS CompressedRectilinearProjector : ProjectorBase 293 { 294 float a, b; 295 296 void mapForward(float x, float y, float &u, float &v); 297 void mapBackward(float u, float v, float &x, float &y); 298 }; 299 300 301 class CV_EXPORTS CompressedRectilinearWarper : public RotationWarperBase<CompressedRectilinearProjector> 302 { 303 public: CompressedRectilinearWarper(float scale,float A=1,float B=1)304 CompressedRectilinearWarper(float scale, float A = 1, float B = 1) 305 { 306 projector_.a = A; 307 projector_.b = B; 308 projector_.scale = scale; 309 } 310 }; 311 312 313 struct CV_EXPORTS CompressedRectilinearPortraitProjector : ProjectorBase 314 { 315 float a, b; 316 317 void mapForward(float x, float y, float &u, float &v); 318 void mapBackward(float u, float v, float &x, float &y); 319 }; 320 321 322 class CV_EXPORTS CompressedRectilinearPortraitWarper : public RotationWarperBase<CompressedRectilinearPortraitProjector> 323 { 324 public: CompressedRectilinearPortraitWarper(float scale,float A=1,float B=1)325 CompressedRectilinearPortraitWarper(float scale, float A = 1, float B = 1) 326 { 327 projector_.a = A; 328 projector_.b = B; 329 projector_.scale = scale; 330 } 331 }; 332 333 334 struct CV_EXPORTS PaniniProjector : ProjectorBase 335 { 336 float a, b; 337 338 void mapForward(float x, float y, float &u, float &v); 339 void mapBackward(float u, float v, float &x, float &y); 340 }; 341 342 343 class CV_EXPORTS PaniniWarper : public RotationWarperBase<PaniniProjector> 344 { 345 public: PaniniWarper(float scale,float A=1,float B=1)346 PaniniWarper(float scale, float A = 1, float B = 1) 347 { 348 projector_.a = A; 349 projector_.b = B; 350 projector_.scale = scale; 351 } 352 }; 353 354 355 struct CV_EXPORTS PaniniPortraitProjector : ProjectorBase 356 { 357 float a, b; 358 359 void mapForward(float x, float y, float &u, float &v); 360 void mapBackward(float u, float v, float &x, float &y); 361 }; 362 363 364 class CV_EXPORTS PaniniPortraitWarper : public RotationWarperBase<PaniniPortraitProjector> 365 { 366 public: PaniniPortraitWarper(float scale,float A=1,float B=1)367 PaniniPortraitWarper(float scale, float A = 1, float B = 1) 368 { 369 projector_.a = A; 370 projector_.b = B; 371 projector_.scale = scale; 372 } 373 374 }; 375 376 377 struct CV_EXPORTS MercatorProjector : ProjectorBase 378 { 379 void mapForward(float x, float y, float &u, float &v); 380 void mapBackward(float u, float v, float &x, float &y); 381 }; 382 383 384 class CV_EXPORTS MercatorWarper : public RotationWarperBase<MercatorProjector> 385 { 386 public: MercatorWarper(float scale)387 MercatorWarper(float scale) { projector_.scale = scale; } 388 }; 389 390 391 struct CV_EXPORTS TransverseMercatorProjector : ProjectorBase 392 { 393 void mapForward(float x, float y, float &u, float &v); 394 void mapBackward(float u, float v, float &x, float &y); 395 }; 396 397 398 class CV_EXPORTS TransverseMercatorWarper : public RotationWarperBase<TransverseMercatorProjector> 399 { 400 public: TransverseMercatorWarper(float scale)401 TransverseMercatorWarper(float scale) { projector_.scale = scale; } 402 }; 403 404 405 class CV_EXPORTS PlaneWarperGpu : public PlaneWarper 406 { 407 public: PlaneWarperGpu(float scale=1.f)408 PlaneWarperGpu(float scale = 1.f) : PlaneWarper(scale) {} 409 buildMaps(Size src_size,InputArray K,InputArray R,OutputArray xmap,OutputArray ymap)410 Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap) 411 { 412 Rect result = buildMaps(src_size, K, R, d_xmap_, d_ymap_); 413 d_xmap_.download(xmap); 414 d_ymap_.download(ymap); 415 return result; 416 } 417 buildMaps(Size src_size,InputArray K,InputArray R,InputArray T,OutputArray xmap,OutputArray ymap)418 Rect buildMaps(Size src_size, InputArray K, InputArray R, InputArray T, OutputArray xmap, OutputArray ymap) 419 { 420 Rect result = buildMaps(src_size, K, R, T, d_xmap_, d_ymap_); 421 d_xmap_.download(xmap); 422 d_ymap_.download(ymap); 423 return result; 424 } 425 warp(InputArray src,InputArray K,InputArray R,int interp_mode,int border_mode,OutputArray dst)426 Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, 427 OutputArray dst) 428 { 429 d_src_.upload(src); 430 Point result = warp(d_src_, K, R, interp_mode, border_mode, d_dst_); 431 d_dst_.download(dst); 432 return result; 433 } 434 warp(InputArray src,InputArray K,InputArray R,InputArray T,int interp_mode,int border_mode,OutputArray dst)435 Point warp(InputArray src, InputArray K, InputArray R, InputArray T, int interp_mode, int border_mode, 436 OutputArray dst) 437 { 438 d_src_.upload(src); 439 Point result = warp(d_src_, K, R, T, interp_mode, border_mode, d_dst_); 440 d_dst_.download(dst); 441 return result; 442 } 443 444 Rect buildMaps(Size src_size, InputArray K, InputArray R, cuda::GpuMat & xmap, cuda::GpuMat & ymap); 445 446 Rect buildMaps(Size src_size, InputArray K, InputArray R, InputArray T, cuda::GpuMat & xmap, cuda::GpuMat & ymap); 447 448 Point warp(const cuda::GpuMat & src, InputArray K, InputArray R, int interp_mode, int border_mode, 449 cuda::GpuMat & dst); 450 451 Point warp(const cuda::GpuMat & src, InputArray K, InputArray R, InputArray T, int interp_mode, int border_mode, 452 cuda::GpuMat & dst); 453 454 private: 455 cuda::GpuMat d_xmap_, d_ymap_, d_src_, d_dst_; 456 }; 457 458 459 class CV_EXPORTS SphericalWarperGpu : public SphericalWarper 460 { 461 public: SphericalWarperGpu(float scale)462 SphericalWarperGpu(float scale) : SphericalWarper(scale) {} 463 buildMaps(Size src_size,InputArray K,InputArray R,OutputArray xmap,OutputArray ymap)464 Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap) 465 { 466 Rect result = buildMaps(src_size, K, R, d_xmap_, d_ymap_); 467 d_xmap_.download(xmap); 468 d_ymap_.download(ymap); 469 return result; 470 } 471 warp(InputArray src,InputArray K,InputArray R,int interp_mode,int border_mode,OutputArray dst)472 Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, 473 OutputArray dst) 474 { 475 d_src_.upload(src); 476 Point result = warp(d_src_, K, R, interp_mode, border_mode, d_dst_); 477 d_dst_.download(dst); 478 return result; 479 } 480 481 Rect buildMaps(Size src_size, InputArray K, InputArray R, cuda::GpuMat & xmap, cuda::GpuMat & ymap); 482 483 Point warp(const cuda::GpuMat & src, InputArray K, InputArray R, int interp_mode, int border_mode, 484 cuda::GpuMat & dst); 485 486 private: 487 cuda::GpuMat d_xmap_, d_ymap_, d_src_, d_dst_; 488 }; 489 490 491 class CV_EXPORTS CylindricalWarperGpu : public CylindricalWarper 492 { 493 public: CylindricalWarperGpu(float scale)494 CylindricalWarperGpu(float scale) : CylindricalWarper(scale) {} 495 buildMaps(Size src_size,InputArray K,InputArray R,OutputArray xmap,OutputArray ymap)496 Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap) 497 { 498 Rect result = buildMaps(src_size, K, R, d_xmap_, d_ymap_); 499 d_xmap_.download(xmap); 500 d_ymap_.download(ymap); 501 return result; 502 } 503 warp(InputArray src,InputArray K,InputArray R,int interp_mode,int border_mode,OutputArray dst)504 Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, 505 OutputArray dst) 506 { 507 d_src_.upload(src); 508 Point result = warp(d_src_, K, R, interp_mode, border_mode, d_dst_); 509 d_dst_.download(dst); 510 return result; 511 } 512 513 Rect buildMaps(Size src_size, InputArray K, InputArray R, cuda::GpuMat & xmap, cuda::GpuMat & ymap); 514 515 Point warp(const cuda::GpuMat & src, InputArray K, InputArray R, int interp_mode, int border_mode, 516 cuda::GpuMat & dst); 517 518 private: 519 cuda::GpuMat d_xmap_, d_ymap_, d_src_, d_dst_; 520 }; 521 522 523 struct SphericalPortraitProjector : ProjectorBase 524 { 525 void mapForward(float x, float y, float &u, float &v); 526 void mapBackward(float u, float v, float &x, float &y); 527 }; 528 529 530 // Projects image onto unit sphere with origin at (0, 0, 0). 531 // Poles are located NOT at (0, -1, 0) and (0, 1, 0) points, BUT at (1, 0, 0) and (-1, 0, 0) points. 532 class CV_EXPORTS SphericalPortraitWarper : public RotationWarperBase<SphericalPortraitProjector> 533 { 534 public: SphericalPortraitWarper(float scale)535 SphericalPortraitWarper(float scale) { projector_.scale = scale; } 536 537 protected: 538 void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br); 539 }; 540 541 struct CylindricalPortraitProjector : ProjectorBase 542 { 543 void mapForward(float x, float y, float &u, float &v); 544 void mapBackward(float u, float v, float &x, float &y); 545 }; 546 547 548 class CV_EXPORTS CylindricalPortraitWarper : public RotationWarperBase<CylindricalPortraitProjector> 549 { 550 public: CylindricalPortraitWarper(float scale)551 CylindricalPortraitWarper(float scale) { projector_.scale = scale; } 552 553 protected: detectResultRoi(Size src_size,Point & dst_tl,Point & dst_br)554 void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br) 555 { 556 RotationWarperBase<CylindricalPortraitProjector>::detectResultRoiByBorder(src_size, dst_tl, dst_br); 557 } 558 }; 559 560 struct PlanePortraitProjector : ProjectorBase 561 { 562 void mapForward(float x, float y, float &u, float &v); 563 void mapBackward(float u, float v, float &x, float &y); 564 }; 565 566 567 class CV_EXPORTS PlanePortraitWarper : public RotationWarperBase<PlanePortraitProjector> 568 { 569 public: PlanePortraitWarper(float scale)570 PlanePortraitWarper(float scale) { projector_.scale = scale; } 571 572 protected: detectResultRoi(Size src_size,Point & dst_tl,Point & dst_br)573 void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br) 574 { 575 RotationWarperBase<PlanePortraitProjector>::detectResultRoiByBorder(src_size, dst_tl, dst_br); 576 } 577 }; 578 579 //! @} stitching_warp 580 581 } // namespace detail 582 } // namespace cv 583 584 #include "warpers_inl.hpp" 585 586 #endif // __OPENCV_STITCHING_WARPERS_HPP__ 587