warpers_inl.hpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782
  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. #ifndef OPENCV_STITCHING_WARPERS_INL_HPP
  43. #define OPENCV_STITCHING_WARPERS_INL_HPP
  44. #include "opencv2/core.hpp"
  45. #include "warpers.hpp" // Make your IDE see declarations
  46. #include <limits>
  47. //! @cond IGNORED
  48. namespace cv {
  49. namespace detail {
  50. template <class P>
  51. Point2f RotationWarperBase<P>::warpPoint(const Point2f &pt, InputArray K, InputArray R)
  52. {
  53. projector_.setCameraParams(K, R);
  54. Point2f uv;
  55. projector_.mapForward(pt.x, pt.y, uv.x, uv.y);
  56. return uv;
  57. }
  58. template <class P>
  59. Point2f RotationWarperBase<P>::warpPointBackward(const Point2f& pt, InputArray K, InputArray R)
  60. {
  61. projector_.setCameraParams(K, R);
  62. Point2f xy;
  63. projector_.mapBackward(pt.x, pt.y, xy.x, xy.y);
  64. return xy;
  65. }
  66. template <class P>
  67. Rect RotationWarperBase<P>::buildMaps(Size src_size, InputArray K, InputArray R, OutputArray _xmap, OutputArray _ymap)
  68. {
  69. projector_.setCameraParams(K, R);
  70. Point dst_tl, dst_br;
  71. detectResultRoi(src_size, dst_tl, dst_br);
  72. _xmap.create(dst_br.y - dst_tl.y + 1, dst_br.x - dst_tl.x + 1, CV_32F);
  73. _ymap.create(dst_br.y - dst_tl.y + 1, dst_br.x - dst_tl.x + 1, CV_32F);
  74. Mat xmap = _xmap.getMat(), ymap = _ymap.getMat();
  75. float x, y;
  76. for (int v = dst_tl.y; v <= dst_br.y; ++v)
  77. {
  78. for (int u = dst_tl.x; u <= dst_br.x; ++u)
  79. {
  80. projector_.mapBackward(static_cast<float>(u), static_cast<float>(v), x, y);
  81. xmap.at<float>(v - dst_tl.y, u - dst_tl.x) = x;
  82. ymap.at<float>(v - dst_tl.y, u - dst_tl.x) = y;
  83. }
  84. }
  85. return Rect(dst_tl, dst_br);
  86. }
  87. template <class P>
  88. Point RotationWarperBase<P>::warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
  89. OutputArray dst)
  90. {
  91. UMat xmap, ymap;
  92. Rect dst_roi = buildMaps(src.size(), K, R, xmap, ymap);
  93. dst.create(dst_roi.height + 1, dst_roi.width + 1, src.type());
  94. remap(src, dst, xmap, ymap, interp_mode, border_mode);
  95. return dst_roi.tl();
  96. }
  97. template <class P>
  98. void RotationWarperBase<P>::warpBackward(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
  99. Size dst_size, OutputArray dst)
  100. {
  101. projector_.setCameraParams(K, R);
  102. Point src_tl, src_br;
  103. detectResultRoi(dst_size, src_tl, src_br);
  104. Size size = src.size();
  105. CV_Assert(src_br.x - src_tl.x + 1 == size.width && src_br.y - src_tl.y + 1 == size.height);
  106. Mat xmap(dst_size, CV_32F);
  107. Mat ymap(dst_size, CV_32F);
  108. float u, v;
  109. for (int y = 0; y < dst_size.height; ++y)
  110. {
  111. for (int x = 0; x < dst_size.width; ++x)
  112. {
  113. projector_.mapForward(static_cast<float>(x), static_cast<float>(y), u, v);
  114. xmap.at<float>(y, x) = u - src_tl.x;
  115. ymap.at<float>(y, x) = v - src_tl.y;
  116. }
  117. }
  118. dst.create(dst_size, src.type());
  119. remap(src, dst, xmap, ymap, interp_mode, border_mode);
  120. }
  121. template <class P>
  122. Rect RotationWarperBase<P>::warpRoi(Size src_size, InputArray K, InputArray R)
  123. {
  124. projector_.setCameraParams(K, R);
  125. Point dst_tl, dst_br;
  126. detectResultRoi(src_size, dst_tl, dst_br);
  127. return Rect(dst_tl, Point(dst_br.x + 1, dst_br.y + 1));
  128. }
  129. template <class P>
  130. void RotationWarperBase<P>::detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br)
  131. {
  132. float tl_uf = (std::numeric_limits<float>::max)();
  133. float tl_vf = (std::numeric_limits<float>::max)();
  134. float br_uf = -(std::numeric_limits<float>::max)();
  135. float br_vf = -(std::numeric_limits<float>::max)();
  136. float u, v;
  137. for (int y = 0; y < src_size.height; ++y)
  138. {
  139. for (int x = 0; x < src_size.width; ++x)
  140. {
  141. projector_.mapForward(static_cast<float>(x), static_cast<float>(y), u, v);
  142. tl_uf = (std::min)(tl_uf, u); tl_vf = (std::min)(tl_vf, v);
  143. br_uf = (std::max)(br_uf, u); br_vf = (std::max)(br_vf, v);
  144. }
  145. }
  146. dst_tl.x = static_cast<int>(tl_uf);
  147. dst_tl.y = static_cast<int>(tl_vf);
  148. dst_br.x = static_cast<int>(br_uf);
  149. dst_br.y = static_cast<int>(br_vf);
  150. }
  151. template <class P>
  152. void RotationWarperBase<P>::detectResultRoiByBorder(Size src_size, Point &dst_tl, Point &dst_br)
  153. {
  154. float tl_uf = (std::numeric_limits<float>::max)();
  155. float tl_vf = (std::numeric_limits<float>::max)();
  156. float br_uf = -(std::numeric_limits<float>::max)();
  157. float br_vf = -(std::numeric_limits<float>::max)();
  158. float u, v;
  159. for (float x = 0; x < src_size.width; ++x)
  160. {
  161. projector_.mapForward(static_cast<float>(x), 0, u, v);
  162. tl_uf = (std::min)(tl_uf, u); tl_vf = (std::min)(tl_vf, v);
  163. br_uf = (std::max)(br_uf, u); br_vf = (std::max)(br_vf, v);
  164. projector_.mapForward(static_cast<float>(x), static_cast<float>(src_size.height - 1), u, v);
  165. tl_uf = (std::min)(tl_uf, u); tl_vf = (std::min)(tl_vf, v);
  166. br_uf = (std::max)(br_uf, u); br_vf = (std::max)(br_vf, v);
  167. }
  168. for (int y = 0; y < src_size.height; ++y)
  169. {
  170. projector_.mapForward(0, static_cast<float>(y), u, v);
  171. tl_uf = (std::min)(tl_uf, u); tl_vf = (std::min)(tl_vf, v);
  172. br_uf = (std::max)(br_uf, u); br_vf = (std::max)(br_vf, v);
  173. projector_.mapForward(static_cast<float>(src_size.width - 1), static_cast<float>(y), u, v);
  174. tl_uf = (std::min)(tl_uf, u); tl_vf = (std::min)(tl_vf, v);
  175. br_uf = (std::max)(br_uf, u); br_vf = (std::max)(br_vf, v);
  176. }
  177. dst_tl.x = static_cast<int>(tl_uf);
  178. dst_tl.y = static_cast<int>(tl_vf);
  179. dst_br.x = static_cast<int>(br_uf);
  180. dst_br.y = static_cast<int>(br_vf);
  181. }
  182. inline
  183. void PlaneProjector::mapForward(float x, float y, float &u, float &v)
  184. {
  185. float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
  186. float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
  187. float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
  188. x_ = t[0] + x_ / z_ * (1 - t[2]);
  189. y_ = t[1] + y_ / z_ * (1 - t[2]);
  190. u = scale * x_;
  191. v = scale * y_;
  192. }
  193. inline
  194. void PlaneProjector::mapBackward(float u, float v, float &x, float &y)
  195. {
  196. u = u / scale - t[0];
  197. v = v / scale - t[1];
  198. float z;
  199. x = k_rinv[0] * u + k_rinv[1] * v + k_rinv[2] * (1 - t[2]);
  200. y = k_rinv[3] * u + k_rinv[4] * v + k_rinv[5] * (1 - t[2]);
  201. z = k_rinv[6] * u + k_rinv[7] * v + k_rinv[8] * (1 - t[2]);
  202. x /= z;
  203. y /= z;
  204. }
  205. inline
  206. void SphericalProjector::mapForward(float x, float y, float &u, float &v)
  207. {
  208. float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
  209. float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
  210. float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
  211. u = scale * atan2f(x_, z_);
  212. float w = y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_);
  213. v = scale * (static_cast<float>(CV_PI) - acosf(w == w ? w : 0));
  214. }
  215. inline
  216. void SphericalProjector::mapBackward(float u, float v, float &x, float &y)
  217. {
  218. u /= scale;
  219. v /= scale;
  220. float sinv = sinf(static_cast<float>(CV_PI) - v);
  221. float x_ = sinv * sinf(u);
  222. float y_ = cosf(static_cast<float>(CV_PI) - v);
  223. float z_ = sinv * cosf(u);
  224. float z;
  225. x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
  226. y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
  227. z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
  228. if (z > 0) { x /= z; y /= z; }
  229. else x = y = -1;
  230. }
  231. inline
  232. void CylindricalProjector::mapForward(float x, float y, float &u, float &v)
  233. {
  234. float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
  235. float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
  236. float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
  237. u = scale * atan2f(x_, z_);
  238. v = scale * y_ / sqrtf(x_ * x_ + z_ * z_);
  239. }
  240. inline
  241. void CylindricalProjector::mapBackward(float u, float v, float &x, float &y)
  242. {
  243. u /= scale;
  244. v /= scale;
  245. float x_ = sinf(u);
  246. float y_ = v;
  247. float z_ = cosf(u);
  248. float z;
  249. x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
  250. y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
  251. z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
  252. if (z > 0) { x /= z; y /= z; }
  253. else x = y = -1;
  254. }
  255. inline
  256. void FisheyeProjector::mapForward(float x, float y, float &u, float &v)
  257. {
  258. float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
  259. float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
  260. float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
  261. float u_ = atan2f(x_, z_);
  262. float v_ = (float)CV_PI - acosf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
  263. u = scale * v_ * cosf(u_);
  264. v = scale * v_ * sinf(u_);
  265. }
  266. inline
  267. void FisheyeProjector::mapBackward(float u, float v, float &x, float &y)
  268. {
  269. u /= scale;
  270. v /= scale;
  271. float u_ = atan2f(v, u);
  272. float v_ = sqrtf(u*u + v*v);
  273. float sinv = sinf((float)CV_PI - v_);
  274. float x_ = sinv * sinf(u_);
  275. float y_ = cosf((float)CV_PI - v_);
  276. float z_ = sinv * cosf(u_);
  277. float z;
  278. x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
  279. y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
  280. z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
  281. if (z > 0) { x /= z; y /= z; }
  282. else x = y = -1;
  283. }
  284. inline
  285. void StereographicProjector::mapForward(float x, float y, float &u, float &v)
  286. {
  287. float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
  288. float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
  289. float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
  290. float u_ = atan2f(x_, z_);
  291. float v_ = (float)CV_PI - acosf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
  292. float r = sinf(v_) / (1 - cosf(v_));
  293. u = scale * r * std::cos(u_);
  294. v = scale * r * std::sin(u_);
  295. }
  296. inline
  297. void StereographicProjector::mapBackward(float u, float v, float &x, float &y)
  298. {
  299. u /= scale;
  300. v /= scale;
  301. float u_ = atan2f(v, u);
  302. float r = sqrtf(u*u + v*v);
  303. float v_ = 2 * atanf(1.f / r);
  304. float sinv = sinf((float)CV_PI - v_);
  305. float x_ = sinv * sinf(u_);
  306. float y_ = cosf((float)CV_PI - v_);
  307. float z_ = sinv * cosf(u_);
  308. float z;
  309. x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
  310. y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
  311. z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
  312. if (z > 0) { x /= z; y /= z; }
  313. else x = y = -1;
  314. }
  315. inline
  316. void CompressedRectilinearProjector::mapForward(float x, float y, float &u, float &v)
  317. {
  318. float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
  319. float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
  320. float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
  321. float u_ = atan2f(x_, z_);
  322. float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
  323. u = scale * a * tanf(u_ / a);
  324. v = scale * b * tanf(v_) / cosf(u_);
  325. }
  326. inline
  327. void CompressedRectilinearProjector::mapBackward(float u, float v, float &x, float &y)
  328. {
  329. u /= scale;
  330. v /= scale;
  331. float aatg = a * atanf(u / a);
  332. float u_ = aatg;
  333. float v_ = atanf(v * cosf(aatg) / b);
  334. float cosv = cosf(v_);
  335. float x_ = cosv * sinf(u_);
  336. float y_ = sinf(v_);
  337. float z_ = cosv * cosf(u_);
  338. float z;
  339. x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
  340. y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
  341. z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
  342. if (z > 0) { x /= z; y /= z; }
  343. else x = y = -1;
  344. }
  345. inline
  346. void CompressedRectilinearPortraitProjector::mapForward(float x, float y, float &u, float &v)
  347. {
  348. float y_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
  349. float x_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
  350. float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
  351. float u_ = atan2f(x_, z_);
  352. float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
  353. u = - scale * a * tanf(u_ / a);
  354. v = scale * b * tanf(v_) / cosf(u_);
  355. }
  356. inline
  357. void CompressedRectilinearPortraitProjector::mapBackward(float u, float v, float &x, float &y)
  358. {
  359. u /= - scale;
  360. v /= scale;
  361. float aatg = a * atanf(u / a);
  362. float u_ = aatg;
  363. float v_ = atanf(v * cosf( aatg ) / b);
  364. float cosv = cosf(v_);
  365. float y_ = cosv * sinf(u_);
  366. float x_ = sinf(v_);
  367. float z_ = cosv * cosf(u_);
  368. float z;
  369. x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
  370. y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
  371. z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
  372. if (z > 0) { x /= z; y /= z; }
  373. else x = y = -1;
  374. }
  375. inline
  376. void PaniniProjector::mapForward(float x, float y, float &u, float &v)
  377. {
  378. float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
  379. float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
  380. float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
  381. float u_ = atan2f(x_, z_);
  382. float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
  383. float tg = a * tanf(u_ / a);
  384. u = scale * tg;
  385. float sinu = sinf(u_);
  386. if ( fabs(sinu) < 1E-7 )
  387. v = scale * b * tanf(v_);
  388. else
  389. v = scale * b * tg * tanf(v_) / sinu;
  390. }
  391. inline
  392. void PaniniProjector::mapBackward(float u, float v, float &x, float &y)
  393. {
  394. u /= scale;
  395. v /= scale;
  396. float lamda = a * atanf(u / a);
  397. float u_ = lamda;
  398. float v_;
  399. if ( fabs(lamda) > 1E-7)
  400. v_ = atanf(v * sinf(lamda) / (b * a * tanf(lamda / a)));
  401. else
  402. v_ = atanf(v / b);
  403. float cosv = cosf(v_);
  404. float x_ = cosv * sinf(u_);
  405. float y_ = sinf(v_);
  406. float z_ = cosv * cosf(u_);
  407. float z;
  408. x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
  409. y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
  410. z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
  411. if (z > 0) { x /= z; y /= z; }
  412. else x = y = -1;
  413. }
  414. inline
  415. void PaniniPortraitProjector::mapForward(float x, float y, float &u, float &v)
  416. {
  417. float y_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
  418. float x_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
  419. float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
  420. float u_ = atan2f(x_, z_);
  421. float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
  422. float tg = a * tanf(u_ / a);
  423. u = - scale * tg;
  424. float sinu = sinf( u_ );
  425. if ( fabs(sinu) < 1E-7 )
  426. v = scale * b * tanf(v_);
  427. else
  428. v = scale * b * tg * tanf(v_) / sinu;
  429. }
  430. inline
  431. void PaniniPortraitProjector::mapBackward(float u, float v, float &x, float &y)
  432. {
  433. u /= - scale;
  434. v /= scale;
  435. float lamda = a * atanf(u / a);
  436. float u_ = lamda;
  437. float v_;
  438. if ( fabs(lamda) > 1E-7)
  439. v_ = atanf(v * sinf(lamda) / (b * a * tanf(lamda/a)));
  440. else
  441. v_ = atanf(v / b);
  442. float cosv = cosf(v_);
  443. float y_ = cosv * sinf(u_);
  444. float x_ = sinf(v_);
  445. float z_ = cosv * cosf(u_);
  446. float z;
  447. x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
  448. y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
  449. z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
  450. if (z > 0) { x /= z; y /= z; }
  451. else x = y = -1;
  452. }
  453. inline
  454. void MercatorProjector::mapForward(float x, float y, float &u, float &v)
  455. {
  456. float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
  457. float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
  458. float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
  459. float u_ = atan2f(x_, z_);
  460. float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
  461. u = scale * u_;
  462. v = scale * logf( tanf( (float)(CV_PI/4) + v_/2 ) );
  463. }
  464. inline
  465. void MercatorProjector::mapBackward(float u, float v, float &x, float &y)
  466. {
  467. u /= scale;
  468. v /= scale;
  469. float v_ = atanf( sinhf(v) );
  470. float u_ = u;
  471. float cosv = cosf(v_);
  472. float x_ = cosv * sinf(u_);
  473. float y_ = sinf(v_);
  474. float z_ = cosv * cosf(u_);
  475. float z;
  476. x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
  477. y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
  478. z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
  479. if (z > 0) { x /= z; y /= z; }
  480. else x = y = -1;
  481. }
  482. inline
  483. void TransverseMercatorProjector::mapForward(float x, float y, float &u, float &v)
  484. {
  485. float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
  486. float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
  487. float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
  488. float u_ = atan2f(x_, z_);
  489. float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
  490. float B = cosf(v_) * sinf(u_);
  491. u = scale / 2 * logf( (1+B) / (1-B) );
  492. v = scale * atan2f(tanf(v_), cosf(u_));
  493. }
  494. inline
  495. void TransverseMercatorProjector::mapBackward(float u, float v, float &x, float &y)
  496. {
  497. u /= scale;
  498. v /= scale;
  499. float v_ = asinf( sinf(v) / coshf(u) );
  500. float u_ = atan2f( sinhf(u), std::cos(v) );
  501. float cosv = cosf(v_);
  502. float x_ = cosv * sinf(u_);
  503. float y_ = sinf(v_);
  504. float z_ = cosv * cosf(u_);
  505. float z;
  506. x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
  507. y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
  508. z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
  509. if (z > 0) { x /= z; y /= z; }
  510. else x = y = -1;
  511. }
  512. inline
  513. void SphericalPortraitProjector::mapForward(float x, float y, float &u0, float &v0)
  514. {
  515. float x0_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
  516. float y0_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
  517. float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
  518. float x_ = y0_;
  519. float y_ = x0_;
  520. float u, v;
  521. u = scale * atan2f(x_, z_);
  522. v = scale * (static_cast<float>(CV_PI) - acosf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_)));
  523. u0 = -u;//v;
  524. v0 = v;//u;
  525. }
  526. inline
  527. void SphericalPortraitProjector::mapBackward(float u0, float v0, float &x, float &y)
  528. {
  529. float u, v;
  530. u = -u0;//v0;
  531. v = v0;//u0;
  532. u /= scale;
  533. v /= scale;
  534. float sinv = sinf(static_cast<float>(CV_PI) - v);
  535. float x0_ = sinv * sinf(u);
  536. float y0_ = cosf(static_cast<float>(CV_PI) - v);
  537. float z_ = sinv * cosf(u);
  538. float x_ = y0_;
  539. float y_ = x0_;
  540. float z;
  541. x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
  542. y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
  543. z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
  544. if (z > 0) { x /= z; y /= z; }
  545. else x = y = -1;
  546. }
  547. inline
  548. void CylindricalPortraitProjector::mapForward(float x, float y, float &u0, float &v0)
  549. {
  550. float x0_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
  551. float y0_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
  552. float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
  553. float x_ = y0_;
  554. float y_ = x0_;
  555. float u, v;
  556. u = scale * atan2f(x_, z_);
  557. v = scale * y_ / sqrtf(x_ * x_ + z_ * z_);
  558. u0 = -u;//v;
  559. v0 = v;//u;
  560. }
  561. inline
  562. void CylindricalPortraitProjector::mapBackward(float u0, float v0, float &x, float &y)
  563. {
  564. float u, v;
  565. u = -u0;//v0;
  566. v = v0;//u0;
  567. u /= scale;
  568. v /= scale;
  569. float x0_ = sinf(u);
  570. float y0_ = v;
  571. float z_ = cosf(u);
  572. float x_ = y0_;
  573. float y_ = x0_;
  574. float z;
  575. x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
  576. y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
  577. z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
  578. if (z > 0) { x /= z; y /= z; }
  579. else x = y = -1;
  580. }
  581. inline
  582. void PlanePortraitProjector::mapForward(float x, float y, float &u0, float &v0)
  583. {
  584. float x0_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
  585. float y0_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
  586. float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
  587. float x_ = y0_;
  588. float y_ = x0_;
  589. x_ = t[0] + x_ / z_ * (1 - t[2]);
  590. y_ = t[1] + y_ / z_ * (1 - t[2]);
  591. float u,v;
  592. u = scale * x_;
  593. v = scale * y_;
  594. u0 = -u;
  595. v0 = v;
  596. }
  597. inline
  598. void PlanePortraitProjector::mapBackward(float u0, float v0, float &x, float &y)
  599. {
  600. float u, v;
  601. u = -u0;
  602. v = v0;
  603. u = u / scale - t[0];
  604. v = v / scale - t[1];
  605. float z;
  606. x = k_rinv[0] * v + k_rinv[1] * u + k_rinv[2] * (1 - t[2]);
  607. y = k_rinv[3] * v + k_rinv[4] * u + k_rinv[5] * (1 - t[2]);
  608. z = k_rinv[6] * v + k_rinv[7] * u + k_rinv[8] * (1 - t[2]);
  609. x /= z;
  610. y /= z;
  611. }
  612. } // namespace detail
  613. } // namespace cv
  614. //! @endcond
  615. #endif // OPENCV_STITCHING_WARPERS_INL_HPP