Home | History | Annotate | Download | only in detail
      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:
     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 
    118     virtual float getScale() const { return 1.f; }
    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 
    156     float getScale() const { return projector_.scale; }
    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      */
    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      */
    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      */
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    401     TransverseMercatorWarper(float scale) { projector_.scale = scale; }
    402 };
    403 
    404 
    405 class CV_EXPORTS PlaneWarperGpu : public PlaneWarper
    406 {
    407 public:
    408     PlaneWarperGpu(float scale = 1.f) : PlaneWarper(scale) {}
    409 
    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 
    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 
    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 
    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:
    462     SphericalWarperGpu(float scale) : SphericalWarper(scale) {}
    463 
    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 
    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:
    494     CylindricalWarperGpu(float scale) : CylindricalWarper(scale) {}
    495 
    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 
    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:
    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:
    551     CylindricalPortraitWarper(float scale) { projector_.scale = scale; }
    552 
    553 protected:
    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:
    570     PlanePortraitWarper(float scale) { projector_.scale = scale; }
    571 
    572 protected:
    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