include/opencv2/stitching/detail/warpers.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_HPP__
00044 #define __OPENCV_STITCHING_WARPERS_HPP__
00045 
00046 #include "opencv2/core/core.hpp"
00047 #include "opencv2/imgproc/imgproc.hpp"
00048 #include "opencv2/opencv_modules.hpp"
00049 #ifdef HAVE_OPENCV_GPU
00050 # include "opencv2/gpu/gpu.hpp"
00051 #endif
00052 
00053 namespace cv {
00054 namespace detail {
00055 
00056 class CV_EXPORTS RotationWarper
00057 {
00058 public:
00059     virtual ~RotationWarper() {}
00060 
00061     virtual Point2f warpPoint(const Point2f &pt, const Mat &K, const Mat &R) = 0;
00062 
00063     virtual Rect buildMaps(Size src_size, const Mat &K, const Mat &R, Mat &xmap, Mat &ymap) = 0;
00064 
00065     virtual Point warp(const Mat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
00066                        Mat &dst) = 0;
00067 
00068     virtual void warpBackward(const Mat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
00069                               Size dst_size, Mat &dst) = 0;
00070 
00071     virtual Rect warpRoi(Size src_size, const Mat &K, const Mat &R) = 0;
00072 
00073     float getScale() const { return 1.f; }
00074     void setScale(float) {}
00075 };
00076 
00077 
00078 struct CV_EXPORTS ProjectorBase
00079 {
00080     void setCameraParams(const Mat &K = Mat::eye(3, 3, CV_32F),
00081                          const Mat &R = Mat::eye(3, 3, CV_32F),
00082                          const Mat &T = Mat::zeros(3, 1, CV_32F));
00083 
00084     float scale;
00085     float k[9];
00086     float rinv[9];
00087     float r_kinv[9];
00088     float k_rinv[9];
00089     float t[3];
00090 };
00091 
00092 
00093 template <class P>
00094 class CV_EXPORTS RotationWarperBase : public RotationWarper
00095 {
00096 public:
00097     Point2f warpPoint(const Point2f &pt, const Mat &K, const Mat &R);
00098 
00099     Rect buildMaps(Size src_size, const Mat &K, const Mat &R, Mat &xmap, Mat &ymap);
00100 
00101     Point warp(const Mat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
00102                Mat &dst);
00103 
00104     void warpBackward(const Mat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
00105                       Size dst_size, Mat &dst);
00106 
00107     Rect warpRoi(Size src_size, const Mat &K, const Mat &R);
00108 
00109     float getScale() const { return projector_.scale; }
00110     void setScale(float val) { projector_.scale = val; }
00111 
00112 protected:
00113 
00114     // Detects ROI of the destination image. It's correct for any projection.
00115     virtual void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br);
00116 
00117     // Detects ROI of the destination image by walking over image border.
00118     // Correctness for any projection isn't guaranteed.
00119     void detectResultRoiByBorder(Size src_size, Point &dst_tl, Point &dst_br);
00120 
00121     P projector_;
00122 };
00123 
00124 
00125 struct CV_EXPORTS PlaneProjector : ProjectorBase
00126 {
00127     void mapForward(float x, float y, float &u, float &v);
00128     void mapBackward(float u, float v, float &x, float &y);
00129 };
00130 
00131 
00132 class CV_EXPORTS PlaneWarper : public RotationWarperBase<PlaneProjector>
00133 {
00134 public:
00135     PlaneWarper(float scale = 1.f) { projector_.scale = scale; }
00136 
00137     void setScale(float scale) { projector_.scale = scale; }
00138 
00139     Point2f warpPoint(const Point2f &pt, const Mat &K, const Mat &R, const Mat &T);
00140 
00141     Rect buildMaps(Size src_size, const Mat &K, const Mat &R, const Mat &T, Mat &xmap, Mat &ymap);
00142 
00143     Point warp(const Mat &src, const Mat &K, const Mat &R, const Mat &T, int interp_mode, int border_mode,
00144                Mat &dst);
00145 
00146     Rect warpRoi(Size src_size, const Mat &K, const Mat &R, const Mat &T);
00147 
00148 protected:
00149     void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br);
00150 };
00151 
00152 
00153 struct CV_EXPORTS SphericalProjector : ProjectorBase
00154 {
00155     void mapForward(float x, float y, float &u, float &v);
00156     void mapBackward(float u, float v, float &x, float &y);
00157 };
00158 
00159 
00160 // Projects image onto unit sphere with origin at (0, 0, 0).
00161 // Poles are located at (0, -1, 0) and (0, 1, 0) points.
00162 class CV_EXPORTS SphericalWarper : public RotationWarperBase<SphericalProjector>
00163 {
00164 public:
00165     SphericalWarper(float scale) { projector_.scale = scale; }
00166 
00167 protected:
00168     void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br);
00169 };
00170 
00171 
00172 struct CV_EXPORTS CylindricalProjector : ProjectorBase
00173 {
00174     void mapForward(float x, float y, float &u, float &v);
00175     void mapBackward(float u, float v, float &x, float &y);
00176 };
00177 
00178 
00179 // Projects image onto x * x + z * z = 1 cylinder
00180 class CV_EXPORTS CylindricalWarper : public RotationWarperBase<CylindricalProjector>
00181 {
00182 public:
00183     CylindricalWarper(float scale) { projector_.scale = scale; }
00184 
00185 protected:
00186     void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br)
00187     {
00188         RotationWarperBase<CylindricalProjector>::detectResultRoiByBorder(src_size, dst_tl, dst_br);
00189     }
00190 };
00191 
00192 
00193 struct CV_EXPORTS FisheyeProjector : ProjectorBase
00194 {
00195     void mapForward(float x, float y, float &u, float &v);
00196     void mapBackward(float u, float v, float &x, float &y);
00197 };
00198 
00199 
00200 class CV_EXPORTS FisheyeWarper : public RotationWarperBase<FisheyeProjector>
00201 {
00202 public:
00203     FisheyeWarper(float scale) { projector_.scale = scale; }
00204 };
00205 
00206 
00207 struct CV_EXPORTS StereographicProjector : ProjectorBase
00208 {
00209     void mapForward(float x, float y, float &u, float &v);
00210     void mapBackward(float u, float v, float &x, float &y);
00211 };
00212 
00213 
00214 class CV_EXPORTS StereographicWarper : public RotationWarperBase<StereographicProjector>
00215 {
00216 public:
00217     StereographicWarper(float scale) { projector_.scale = scale; }
00218 };
00219 
00220 
00221 struct CV_EXPORTS CompressedRectilinearProjector : ProjectorBase
00222 {
00223     float a, b;
00224 
00225     void mapForward(float x, float y, float &u, float &v);
00226     void mapBackward(float u, float v, float &x, float &y);
00227 };
00228 
00229 
00230 class CV_EXPORTS CompressedRectilinearWarper : public RotationWarperBase<CompressedRectilinearProjector>
00231 {
00232 public:
00233     CompressedRectilinearWarper(float scale, float A = 1, float B = 1)
00234     {
00235         projector_.a = A;
00236         projector_.b = B;
00237         projector_.scale = scale;
00238     }
00239 };
00240 
00241 
00242 struct CV_EXPORTS CompressedRectilinearPortraitProjector : ProjectorBase
00243 {
00244     float a, b;
00245 
00246     void mapForward(float x, float y, float &u, float &v);
00247     void mapBackward(float u, float v, float &x, float &y);
00248 };
00249 
00250 
00251 class CV_EXPORTS CompressedRectilinearPortraitWarper : public RotationWarperBase<CompressedRectilinearPortraitProjector>
00252 {
00253 public:
00254    CompressedRectilinearPortraitWarper(float scale, float A = 1, float B = 1)
00255    {
00256        projector_.a = A;
00257        projector_.b = B;
00258        projector_.scale = scale;
00259    }
00260 };
00261 
00262 
00263 struct CV_EXPORTS PaniniProjector : ProjectorBase
00264 {
00265     float a, b;
00266 
00267     void mapForward(float x, float y, float &u, float &v);
00268     void mapBackward(float u, float v, float &x, float &y);
00269 };
00270 
00271 
00272 class CV_EXPORTS PaniniWarper : public RotationWarperBase<PaniniProjector>
00273 {
00274 public:
00275    PaniniWarper(float scale, float A = 1, float B = 1)
00276    {
00277        projector_.a = A;
00278        projector_.b = B;
00279        projector_.scale = scale;
00280    }
00281 };
00282 
00283 
00284 struct CV_EXPORTS PaniniPortraitProjector : ProjectorBase
00285 {
00286     float a, b;
00287 
00288     void mapForward(float x, float y, float &u, float &v);
00289     void mapBackward(float u, float v, float &x, float &y);
00290 };
00291 
00292 
00293 class CV_EXPORTS PaniniPortraitWarper : public RotationWarperBase<PaniniPortraitProjector>
00294 {
00295 public:
00296    PaniniPortraitWarper(float scale, float A = 1, float B = 1)
00297    {
00298        projector_.a = A;
00299        projector_.b = B;
00300        projector_.scale = scale;
00301    }
00302 
00303 };
00304 
00305 
00306 struct CV_EXPORTS MercatorProjector : ProjectorBase
00307 {
00308     void mapForward(float x, float y, float &u, float &v);
00309     void mapBackward(float u, float v, float &x, float &y);
00310 };
00311 
00312 
00313 class CV_EXPORTS MercatorWarper : public RotationWarperBase<MercatorProjector>
00314 {
00315 public:
00316     MercatorWarper(float scale) { projector_.scale = scale; }
00317 };
00318 
00319 
00320 struct CV_EXPORTS TransverseMercatorProjector : ProjectorBase
00321 {
00322     void mapForward(float x, float y, float &u, float &v);
00323     void mapBackward(float u, float v, float &x, float &y);
00324 };
00325 
00326 
00327 class CV_EXPORTS TransverseMercatorWarper : public RotationWarperBase<TransverseMercatorProjector>
00328 {
00329 public:
00330     TransverseMercatorWarper(float scale) { projector_.scale = scale; }
00331 };
00332 
00333 
00334 #ifdef HAVE_OPENCV_GPU
00335 class CV_EXPORTS PlaneWarperGpu : public PlaneWarper
00336 {
00337 public:
00338     PlaneWarperGpu(float scale = 1.f) : PlaneWarper(scale) {}
00339 
00340     Rect buildMaps(Size src_size, const Mat &K, const Mat &R, Mat &xmap, Mat &ymap)
00341     {
00342         Rect result = buildMaps(src_size, K, R, d_xmap_, d_ymap_);
00343         d_xmap_.download(xmap);
00344         d_ymap_.download(ymap);
00345         return result;
00346     }
00347 
00348     Rect buildMaps(Size src_size, const Mat &K, const Mat &R, const Mat &T, Mat &xmap, Mat &ymap)
00349     {
00350         Rect result = buildMaps(src_size, K, R, T, d_xmap_, d_ymap_);
00351         d_xmap_.download(xmap);
00352         d_ymap_.download(ymap);
00353         return result;
00354     }
00355 
00356     Point warp(const Mat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
00357                Mat &dst)
00358     {
00359         d_src_.upload(src);
00360         Point result = warp(d_src_, K, R, interp_mode, border_mode, d_dst_);
00361         d_dst_.download(dst);
00362         return result;
00363     }
00364 
00365     Point warp(const Mat &src, const Mat &K, const Mat &R, const Mat &T, int interp_mode, int border_mode,
00366                Mat &dst)
00367     {
00368         d_src_.upload(src);
00369         Point result = warp(d_src_, K, R, T, interp_mode, border_mode, d_dst_);
00370         d_dst_.download(dst);
00371         return result;
00372     }
00373 
00374     Rect buildMaps(Size src_size, const Mat &K, const Mat &R, gpu::GpuMat &xmap, gpu::GpuMat &ymap);
00375 
00376     Rect buildMaps(Size src_size, const Mat &K, const Mat &R, const Mat &T, gpu::GpuMat &xmap, gpu::GpuMat &ymap);
00377 
00378     Point warp(const gpu::GpuMat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
00379                gpu::GpuMat &dst);
00380 
00381     Point warp(const gpu::GpuMat &src, const Mat &K, const Mat &R, const Mat &T, int interp_mode, int border_mode,
00382                gpu::GpuMat &dst);
00383 
00384 private:
00385     gpu::GpuMat d_xmap_, d_ymap_, d_src_, d_dst_;
00386 };
00387 
00388 
00389 class CV_EXPORTS SphericalWarperGpu : public SphericalWarper
00390 {
00391 public:
00392     SphericalWarperGpu(float scale) : SphericalWarper(scale) {}
00393 
00394     Rect buildMaps(Size src_size, const Mat &K, const Mat &R, Mat &xmap, Mat &ymap)
00395     {
00396         Rect result = buildMaps(src_size, K, R, d_xmap_, d_ymap_);
00397         d_xmap_.download(xmap);
00398         d_ymap_.download(ymap);
00399         return result;
00400     }
00401 
00402     Point warp(const Mat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
00403                Mat &dst)
00404     {
00405         d_src_.upload(src);
00406         Point result = warp(d_src_, K, R, interp_mode, border_mode, d_dst_);
00407         d_dst_.download(dst);
00408         return result;
00409     }
00410 
00411     Rect buildMaps(Size src_size, const Mat &K, const Mat &R, gpu::GpuMat &xmap, gpu::GpuMat &ymap);
00412 
00413     Point warp(const gpu::GpuMat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
00414                gpu::GpuMat &dst);
00415 
00416 private:
00417     gpu::GpuMat d_xmap_, d_ymap_, d_src_, d_dst_;
00418 };
00419 
00420 
00421 class CV_EXPORTS CylindricalWarperGpu : public CylindricalWarper
00422 {
00423 public:
00424     CylindricalWarperGpu(float scale) : CylindricalWarper(scale) {}
00425 
00426     Rect buildMaps(Size src_size, const Mat &K, const Mat &R, Mat &xmap, Mat &ymap)
00427     {
00428         Rect result = buildMaps(src_size, K, R, d_xmap_, d_ymap_);
00429         d_xmap_.download(xmap);
00430         d_ymap_.download(ymap);
00431         return result;
00432     }
00433 
00434     Point warp(const Mat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
00435                Mat &dst)
00436     {
00437         d_src_.upload(src);
00438         Point result = warp(d_src_, K, R, interp_mode, border_mode, d_dst_);
00439         d_dst_.download(dst);
00440         return result;
00441     }
00442 
00443     Rect buildMaps(Size src_size, const Mat &K, const Mat &R, gpu::GpuMat &xmap, gpu::GpuMat &ymap);
00444 
00445     Point warp(const gpu::GpuMat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
00446                gpu::GpuMat &dst);
00447 
00448 private:
00449     gpu::GpuMat d_xmap_, d_ymap_, d_src_, d_dst_;
00450 };
00451 #endif
00452 
00453 
00454 struct SphericalPortraitProjector : ProjectorBase
00455 {
00456     void mapForward(float x, float y, float &u, float &v);
00457     void mapBackward(float u, float v, float &x, float &y);
00458 };
00459 
00460 
00461 // Projects image onto unit sphere with origin at (0, 0, 0).
00462 // Poles are located NOT at (0, -1, 0) and (0, 1, 0) points, BUT at (1, 0, 0) and (-1, 0, 0) points.
00463 class SphericalPortraitWarper : public RotationWarperBase<SphericalPortraitProjector>
00464 {
00465 public:
00466     SphericalPortraitWarper(float scale) { projector_.scale = scale; }
00467 
00468 protected:
00469     void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br);
00470 };
00471 
00472 struct CylindricalPortraitProjector : ProjectorBase
00473 {
00474     void mapForward(float x, float y, float &u, float &v);
00475     void mapBackward(float u, float v, float &x, float &y);
00476 };
00477 
00478 
00479 class CylindricalPortraitWarper : public RotationWarperBase<CylindricalPortraitProjector>
00480 {
00481 public:
00482     CylindricalPortraitWarper(float scale) { projector_.scale = scale; }
00483 
00484 protected:
00485     void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br)
00486     {
00487         RotationWarperBase<CylindricalPortraitProjector>::detectResultRoiByBorder(src_size, dst_tl, dst_br);
00488     }
00489 };
00490 
00491 struct PlanePortraitProjector : ProjectorBase
00492 {
00493     void mapForward(float x, float y, float &u, float &v);
00494     void mapBackward(float u, float v, float &x, float &y);
00495 };
00496 
00497 
00498 class PlanePortraitWarper : public RotationWarperBase<PlanePortraitProjector>
00499 {
00500 public:
00501     PlanePortraitWarper(float scale) { projector_.scale = scale; }
00502 
00503 protected:
00504     void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br)
00505     {
00506         RotationWarperBase<PlanePortraitProjector>::detectResultRoiByBorder(src_size, dst_tl, dst_br);
00507     }
00508 };
00509 
00510 } // namespace detail
00511 } // namespace cv
00512 
00513 #include "warpers_inl.hpp"
00514 
00515 #endif // __OPENCV_STITCHING_WARPERS_HPP__