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_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
00115 virtual void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br);
00116
00117
00118
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
00161
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
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
00462
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 }
00511 }
00512
00513 #include "warpers_inl.hpp"
00514
00515 #endif // __OPENCV_STITCHING_WARPERS_HPP__