affine.hpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528
  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. // Copyright (C) 2013, OpenCV Foundation, all rights reserved.
  16. // Third party copyrights are property of their respective owners.
  17. //
  18. // Redistribution and use in source and binary forms, with or without modification,
  19. // are permitted provided that the following conditions are met:
  20. //
  21. // * Redistribution's of source code must retain the above copyright notice,
  22. // this list of conditions and the following disclaimer.
  23. //
  24. // * Redistribution's in binary form must reproduce the above copyright notice,
  25. // this list of conditions and the following disclaimer in the documentation
  26. // and/or other materials provided with the distribution.
  27. //
  28. // * The name of the copyright holders may not be used to endorse or promote products
  29. // derived from this software without specific prior written permission.
  30. //
  31. // This software is provided by the copyright holders and contributors "as is" and
  32. // any express or implied warranties, including, but not limited to, the implied
  33. // warranties of merchantability and fitness for a particular purpose are disclaimed.
  34. // In no event shall the Intel Corporation or contributors be liable for any direct,
  35. // indirect, incidental, special, exemplary, or consequential damages
  36. // (including, but not limited to, procurement of substitute goods or services;
  37. // loss of use, data, or profits; or business interruption) however caused
  38. // and on any theory of liability, whether in contract, strict liability,
  39. // or tort (including negligence or otherwise) arising in any way out of
  40. // the use of this software, even if advised of the possibility of such damage.
  41. //
  42. //M*/
  43. #ifndef OPENCV_CORE_AFFINE3_HPP
  44. #define OPENCV_CORE_AFFINE3_HPP
  45. #ifdef __cplusplus
  46. #include <opencv2/core.hpp>
  47. namespace cv
  48. {
  49. //! @addtogroup core
  50. //! @{
  51. /** @brief Affine transform
  52. @todo document
  53. */
  54. template<typename T>
  55. class Affine3
  56. {
  57. public:
  58. typedef T float_type;
  59. typedef Matx<float_type, 3, 3> Mat3;
  60. typedef Matx<float_type, 4, 4> Mat4;
  61. typedef Vec<float_type, 3> Vec3;
  62. Affine3();
  63. //! Augmented affine matrix
  64. Affine3(const Mat4& affine);
  65. //! Rotation matrix
  66. Affine3(const Mat3& R, const Vec3& t = Vec3::all(0));
  67. //! Rodrigues vector
  68. Affine3(const Vec3& rvec, const Vec3& t = Vec3::all(0));
  69. //! Combines all contructors above. Supports 4x4, 4x3, 3x3, 1x3, 3x1 sizes of data matrix
  70. explicit Affine3(const Mat& data, const Vec3& t = Vec3::all(0));
  71. //! From 16th element array
  72. explicit Affine3(const float_type* vals);
  73. //! Create identity transform
  74. static Affine3 Identity();
  75. //! Rotation matrix
  76. void rotation(const Mat3& R);
  77. //! Rodrigues vector
  78. void rotation(const Vec3& rvec);
  79. //! Combines rotation methods above. Suports 3x3, 1x3, 3x1 sizes of data matrix;
  80. void rotation(const Mat& data);
  81. void linear(const Mat3& L);
  82. void translation(const Vec3& t);
  83. Mat3 rotation() const;
  84. Mat3 linear() const;
  85. Vec3 translation() const;
  86. //! Rodrigues vector
  87. Vec3 rvec() const;
  88. Affine3 inv(int method = cv::DECOMP_SVD) const;
  89. //! a.rotate(R) is equivalent to Affine(R, 0) * a;
  90. Affine3 rotate(const Mat3& R) const;
  91. //! a.rotate(rvec) is equivalent to Affine(rvec, 0) * a;
  92. Affine3 rotate(const Vec3& rvec) const;
  93. //! a.translate(t) is equivalent to Affine(E, t) * a;
  94. Affine3 translate(const Vec3& t) const;
  95. //! a.concatenate(affine) is equivalent to affine * a;
  96. Affine3 concatenate(const Affine3& affine) const;
  97. template <typename Y> operator Affine3<Y>() const;
  98. template <typename Y> Affine3<Y> cast() const;
  99. Mat4 matrix;
  100. #if defined EIGEN_WORLD_VERSION && defined EIGEN_GEOMETRY_MODULE_H
  101. Affine3(const Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)>& affine);
  102. Affine3(const Eigen::Transform<T, 3, Eigen::Affine>& affine);
  103. operator Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)>() const;
  104. operator Eigen::Transform<T, 3, Eigen::Affine>() const;
  105. #endif
  106. };
  107. template<typename T> static
  108. Affine3<T> operator*(const Affine3<T>& affine1, const Affine3<T>& affine2);
  109. template<typename T, typename V> static
  110. V operator*(const Affine3<T>& affine, const V& vector);
  111. typedef Affine3<float> Affine3f;
  112. typedef Affine3<double> Affine3d;
  113. static Vec3f operator*(const Affine3f& affine, const Vec3f& vector);
  114. static Vec3d operator*(const Affine3d& affine, const Vec3d& vector);
  115. template<typename _Tp> class DataType< Affine3<_Tp> >
  116. {
  117. public:
  118. typedef Affine3<_Tp> value_type;
  119. typedef Affine3<typename DataType<_Tp>::work_type> work_type;
  120. typedef _Tp channel_type;
  121. enum { generic_type = 0,
  122. channels = 16,
  123. fmt = traits::SafeFmt<channel_type>::fmt + ((channels - 1) << 8)
  124. #ifdef OPENCV_TRAITS_ENABLE_DEPRECATED
  125. ,depth = DataType<channel_type>::depth
  126. ,type = CV_MAKETYPE(depth, channels)
  127. #endif
  128. };
  129. typedef Vec<channel_type, channels> vec_type;
  130. };
  131. namespace traits {
  132. template<typename _Tp>
  133. struct Depth< Affine3<_Tp> > { enum { value = Depth<_Tp>::value }; };
  134. template<typename _Tp>
  135. struct Type< Affine3<_Tp> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, 16) }; };
  136. } // namespace
  137. //! @} core
  138. }
  139. //! @cond IGNORED
  140. ///////////////////////////////////////////////////////////////////////////////////
  141. // Implementaiton
  142. template<typename T> inline
  143. cv::Affine3<T>::Affine3()
  144. : matrix(Mat4::eye())
  145. {}
  146. template<typename T> inline
  147. cv::Affine3<T>::Affine3(const Mat4& affine)
  148. : matrix(affine)
  149. {}
  150. template<typename T> inline
  151. cv::Affine3<T>::Affine3(const Mat3& R, const Vec3& t)
  152. {
  153. rotation(R);
  154. translation(t);
  155. matrix.val[12] = matrix.val[13] = matrix.val[14] = 0;
  156. matrix.val[15] = 1;
  157. }
  158. template<typename T> inline
  159. cv::Affine3<T>::Affine3(const Vec3& _rvec, const Vec3& t)
  160. {
  161. rotation(_rvec);
  162. translation(t);
  163. matrix.val[12] = matrix.val[13] = matrix.val[14] = 0;
  164. matrix.val[15] = 1;
  165. }
  166. template<typename T> inline
  167. cv::Affine3<T>::Affine3(const cv::Mat& data, const Vec3& t)
  168. {
  169. CV_Assert(data.type() == cv::traits::Type<T>::value);
  170. if (data.cols == 4 && data.rows == 4)
  171. {
  172. data.copyTo(matrix);
  173. return;
  174. }
  175. else if (data.cols == 4 && data.rows == 3)
  176. {
  177. rotation(data(Rect(0, 0, 3, 3)));
  178. translation(data(Rect(3, 0, 1, 3)));
  179. }
  180. else
  181. {
  182. rotation(data);
  183. translation(t);
  184. }
  185. matrix.val[12] = matrix.val[13] = matrix.val[14] = 0;
  186. matrix.val[15] = 1;
  187. }
  188. template<typename T> inline
  189. cv::Affine3<T>::Affine3(const float_type* vals) : matrix(vals)
  190. {}
  191. template<typename T> inline
  192. cv::Affine3<T> cv::Affine3<T>::Identity()
  193. {
  194. return Affine3<T>(cv::Affine3<T>::Mat4::eye());
  195. }
  196. template<typename T> inline
  197. void cv::Affine3<T>::rotation(const Mat3& R)
  198. {
  199. linear(R);
  200. }
  201. template<typename T> inline
  202. void cv::Affine3<T>::rotation(const Vec3& _rvec)
  203. {
  204. double theta = norm(_rvec);
  205. if (theta < DBL_EPSILON)
  206. rotation(Mat3::eye());
  207. else
  208. {
  209. double c = std::cos(theta);
  210. double s = std::sin(theta);
  211. double c1 = 1. - c;
  212. double itheta = (theta != 0) ? 1./theta : 0.;
  213. Point3_<T> r = _rvec*itheta;
  214. Mat3 rrt( r.x*r.x, r.x*r.y, r.x*r.z, r.x*r.y, r.y*r.y, r.y*r.z, r.x*r.z, r.y*r.z, r.z*r.z );
  215. Mat3 r_x( 0, -r.z, r.y, r.z, 0, -r.x, -r.y, r.x, 0 );
  216. // R = cos(theta)*I + (1 - cos(theta))*r*rT + sin(theta)*[r_x]
  217. // where [r_x] is [0 -rz ry; rz 0 -rx; -ry rx 0]
  218. Mat3 R = c*Mat3::eye() + c1*rrt + s*r_x;
  219. rotation(R);
  220. }
  221. }
  222. //Combines rotation methods above. Suports 3x3, 1x3, 3x1 sizes of data matrix;
  223. template<typename T> inline
  224. void cv::Affine3<T>::rotation(const cv::Mat& data)
  225. {
  226. CV_Assert(data.type() == cv::traits::Type<T>::value);
  227. if (data.cols == 3 && data.rows == 3)
  228. {
  229. Mat3 R;
  230. data.copyTo(R);
  231. rotation(R);
  232. }
  233. else if ((data.cols == 3 && data.rows == 1) || (data.cols == 1 && data.rows == 3))
  234. {
  235. Vec3 _rvec;
  236. data.reshape(1, 3).copyTo(_rvec);
  237. rotation(_rvec);
  238. }
  239. else
  240. CV_Assert(!"Input marix can be 3x3, 1x3 or 3x1");
  241. }
  242. template<typename T> inline
  243. void cv::Affine3<T>::linear(const Mat3& L)
  244. {
  245. matrix.val[0] = L.val[0]; matrix.val[1] = L.val[1]; matrix.val[ 2] = L.val[2];
  246. matrix.val[4] = L.val[3]; matrix.val[5] = L.val[4]; matrix.val[ 6] = L.val[5];
  247. matrix.val[8] = L.val[6]; matrix.val[9] = L.val[7]; matrix.val[10] = L.val[8];
  248. }
  249. template<typename T> inline
  250. void cv::Affine3<T>::translation(const Vec3& t)
  251. {
  252. matrix.val[3] = t[0]; matrix.val[7] = t[1]; matrix.val[11] = t[2];
  253. }
  254. template<typename T> inline
  255. typename cv::Affine3<T>::Mat3 cv::Affine3<T>::rotation() const
  256. {
  257. return linear();
  258. }
  259. template<typename T> inline
  260. typename cv::Affine3<T>::Mat3 cv::Affine3<T>::linear() const
  261. {
  262. typename cv::Affine3<T>::Mat3 R;
  263. R.val[0] = matrix.val[0]; R.val[1] = matrix.val[1]; R.val[2] = matrix.val[ 2];
  264. R.val[3] = matrix.val[4]; R.val[4] = matrix.val[5]; R.val[5] = matrix.val[ 6];
  265. R.val[6] = matrix.val[8]; R.val[7] = matrix.val[9]; R.val[8] = matrix.val[10];
  266. return R;
  267. }
  268. template<typename T> inline
  269. typename cv::Affine3<T>::Vec3 cv::Affine3<T>::translation() const
  270. {
  271. return Vec3(matrix.val[3], matrix.val[7], matrix.val[11]);
  272. }
  273. template<typename T> inline
  274. typename cv::Affine3<T>::Vec3 cv::Affine3<T>::rvec() const
  275. {
  276. cv::Vec3d w;
  277. cv::Matx33d u, vt, R = rotation();
  278. cv::SVD::compute(R, w, u, vt, cv::SVD::FULL_UV + cv::SVD::MODIFY_A);
  279. R = u * vt;
  280. double rx = R.val[7] - R.val[5];
  281. double ry = R.val[2] - R.val[6];
  282. double rz = R.val[3] - R.val[1];
  283. double s = std::sqrt((rx*rx + ry*ry + rz*rz)*0.25);
  284. double c = (R.val[0] + R.val[4] + R.val[8] - 1) * 0.5;
  285. c = c > 1.0 ? 1.0 : c < -1.0 ? -1.0 : c;
  286. double theta = acos(c);
  287. if( s < 1e-5 )
  288. {
  289. if( c > 0 )
  290. rx = ry = rz = 0;
  291. else
  292. {
  293. double t;
  294. t = (R.val[0] + 1) * 0.5;
  295. rx = std::sqrt(std::max(t, 0.0));
  296. t = (R.val[4] + 1) * 0.5;
  297. ry = std::sqrt(std::max(t, 0.0)) * (R.val[1] < 0 ? -1.0 : 1.0);
  298. t = (R.val[8] + 1) * 0.5;
  299. rz = std::sqrt(std::max(t, 0.0)) * (R.val[2] < 0 ? -1.0 : 1.0);
  300. if( fabs(rx) < fabs(ry) && fabs(rx) < fabs(rz) && (R.val[5] > 0) != (ry*rz > 0) )
  301. rz = -rz;
  302. theta /= std::sqrt(rx*rx + ry*ry + rz*rz);
  303. rx *= theta;
  304. ry *= theta;
  305. rz *= theta;
  306. }
  307. }
  308. else
  309. {
  310. double vth = 1/(2*s);
  311. vth *= theta;
  312. rx *= vth; ry *= vth; rz *= vth;
  313. }
  314. return cv::Vec3d(rx, ry, rz);
  315. }
  316. template<typename T> inline
  317. cv::Affine3<T> cv::Affine3<T>::inv(int method) const
  318. {
  319. return matrix.inv(method);
  320. }
  321. template<typename T> inline
  322. cv::Affine3<T> cv::Affine3<T>::rotate(const Mat3& R) const
  323. {
  324. Mat3 Lc = linear();
  325. Vec3 tc = translation();
  326. Mat4 result;
  327. result.val[12] = result.val[13] = result.val[14] = 0;
  328. result.val[15] = 1;
  329. for(int j = 0; j < 3; ++j)
  330. {
  331. for(int i = 0; i < 3; ++i)
  332. {
  333. float_type value = 0;
  334. for(int k = 0; k < 3; ++k)
  335. value += R(j, k) * Lc(k, i);
  336. result(j, i) = value;
  337. }
  338. result(j, 3) = R.row(j).dot(tc.t());
  339. }
  340. return result;
  341. }
  342. template<typename T> inline
  343. cv::Affine3<T> cv::Affine3<T>::rotate(const Vec3& _rvec) const
  344. {
  345. return rotate(Affine3f(_rvec).rotation());
  346. }
  347. template<typename T> inline
  348. cv::Affine3<T> cv::Affine3<T>::translate(const Vec3& t) const
  349. {
  350. Mat4 m = matrix;
  351. m.val[ 3] += t[0];
  352. m.val[ 7] += t[1];
  353. m.val[11] += t[2];
  354. return m;
  355. }
  356. template<typename T> inline
  357. cv::Affine3<T> cv::Affine3<T>::concatenate(const Affine3<T>& affine) const
  358. {
  359. return (*this).rotate(affine.rotation()).translate(affine.translation());
  360. }
  361. template<typename T> template <typename Y> inline
  362. cv::Affine3<T>::operator Affine3<Y>() const
  363. {
  364. return Affine3<Y>(matrix);
  365. }
  366. template<typename T> template <typename Y> inline
  367. cv::Affine3<Y> cv::Affine3<T>::cast() const
  368. {
  369. return Affine3<Y>(matrix);
  370. }
  371. template<typename T> inline
  372. cv::Affine3<T> cv::operator*(const cv::Affine3<T>& affine1, const cv::Affine3<T>& affine2)
  373. {
  374. return affine2.concatenate(affine1);
  375. }
  376. template<typename T, typename V> inline
  377. V cv::operator*(const cv::Affine3<T>& affine, const V& v)
  378. {
  379. const typename Affine3<T>::Mat4& m = affine.matrix;
  380. V r;
  381. r.x = m.val[0] * v.x + m.val[1] * v.y + m.val[ 2] * v.z + m.val[ 3];
  382. r.y = m.val[4] * v.x + m.val[5] * v.y + m.val[ 6] * v.z + m.val[ 7];
  383. r.z = m.val[8] * v.x + m.val[9] * v.y + m.val[10] * v.z + m.val[11];
  384. return r;
  385. }
  386. static inline
  387. cv::Vec3f cv::operator*(const cv::Affine3f& affine, const cv::Vec3f& v)
  388. {
  389. const cv::Matx44f& m = affine.matrix;
  390. cv::Vec3f r;
  391. r.val[0] = m.val[0] * v[0] + m.val[1] * v[1] + m.val[ 2] * v[2] + m.val[ 3];
  392. r.val[1] = m.val[4] * v[0] + m.val[5] * v[1] + m.val[ 6] * v[2] + m.val[ 7];
  393. r.val[2] = m.val[8] * v[0] + m.val[9] * v[1] + m.val[10] * v[2] + m.val[11];
  394. return r;
  395. }
  396. static inline
  397. cv::Vec3d cv::operator*(const cv::Affine3d& affine, const cv::Vec3d& v)
  398. {
  399. const cv::Matx44d& m = affine.matrix;
  400. cv::Vec3d r;
  401. r.val[0] = m.val[0] * v[0] + m.val[1] * v[1] + m.val[ 2] * v[2] + m.val[ 3];
  402. r.val[1] = m.val[4] * v[0] + m.val[5] * v[1] + m.val[ 6] * v[2] + m.val[ 7];
  403. r.val[2] = m.val[8] * v[0] + m.val[9] * v[1] + m.val[10] * v[2] + m.val[11];
  404. return r;
  405. }
  406. #if defined EIGEN_WORLD_VERSION && defined EIGEN_GEOMETRY_MODULE_H
  407. template<typename T> inline
  408. cv::Affine3<T>::Affine3(const Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)>& affine)
  409. {
  410. cv::Mat(4, 4, cv::traits::Type<T>::value, affine.matrix().data()).copyTo(matrix);
  411. }
  412. template<typename T> inline
  413. cv::Affine3<T>::Affine3(const Eigen::Transform<T, 3, Eigen::Affine>& affine)
  414. {
  415. Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)> a = affine;
  416. cv::Mat(4, 4, cv::traits::Type<T>::value, a.matrix().data()).copyTo(matrix);
  417. }
  418. template<typename T> inline
  419. cv::Affine3<T>::operator Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)>() const
  420. {
  421. Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)> r;
  422. cv::Mat hdr(4, 4, cv::traits::Type<T>::value, r.matrix().data());
  423. cv::Mat(matrix, false).copyTo(hdr);
  424. return r;
  425. }
  426. template<typename T> inline
  427. cv::Affine3<T>::operator Eigen::Transform<T, 3, Eigen::Affine>() const
  428. {
  429. return this->operator Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)>();
  430. }
  431. #endif /* defined EIGEN_WORLD_VERSION && defined EIGEN_GEOMETRY_MODULE_H */
  432. //! @endcond
  433. #endif /* __cplusplus */
  434. #endif /* OPENCV_CORE_AFFINE3_HPP */