warpers_inl.hpp 22 KB

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