affine.hpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  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. *
  53. * It represents a 4x4 homogeneous transformation matrix \f$T\f$
  54. *
  55. * \f[T =
  56. * \begin{bmatrix}
  57. * R & t\\
  58. * 0 & 1\\
  59. * \end{bmatrix}
  60. * \f]
  61. *
  62. * where \f$R\f$ is a 3x3 rotation matrix and \f$t\f$ is a 3x1 translation vector.
  63. *
  64. * You can specify \f$R\f$ either by a 3x3 rotation matrix or by a 3x1 rotation vector,
  65. * which is converted to a 3x3 rotation matrix by the Rodrigues formula.
  66. *
  67. * To construct a matrix \f$T\f$ representing first rotation around the axis \f$r\f$ with rotation
  68. * angle \f$|r|\f$ in radian (right hand rule) and then translation by the vector \f$t\f$, you can use
  69. *
  70. * @code
  71. * cv::Vec3f r, t;
  72. * cv::Affine3f T(r, t);
  73. * @endcode
  74. *
  75. * If you already have the rotation matrix \f$R\f$, then you can use
  76. *
  77. * @code
  78. * cv::Matx33f R;
  79. * cv::Affine3f T(R, t);
  80. * @endcode
  81. *
  82. * To extract the rotation matrix \f$R\f$ from \f$T\f$, use
  83. *
  84. * @code
  85. * cv::Matx33f R = T.rotation();
  86. * @endcode
  87. *
  88. * To extract the translation vector \f$t\f$ from \f$T\f$, use
  89. *
  90. * @code
  91. * cv::Vec3f t = T.translation();
  92. * @endcode
  93. *
  94. * To extract the rotation vector \f$r\f$ from \f$T\f$, use
  95. *
  96. * @code
  97. * cv::Vec3f r = T.rvec();
  98. * @endcode
  99. *
  100. * Note that since the mapping from rotation vectors to rotation matrices
  101. * is many to one. The returned rotation vector is not necessarily the one
  102. * you used before to set the matrix.
  103. *
  104. * If you have two transformations \f$T = T_1 * T_2\f$, use
  105. *
  106. * @code
  107. * cv::Affine3f T, T1, T2;
  108. * T = T2.concatenate(T1);
  109. * @endcode
  110. *
  111. * To get the inverse transform of \f$T\f$, use
  112. *
  113. * @code
  114. * cv::Affine3f T, T_inv;
  115. * T_inv = T.inv();
  116. * @endcode
  117. *
  118. */
  119. template<typename T>
  120. class Affine3
  121. {
  122. public:
  123. typedef T float_type;
  124. typedef Matx<float_type, 3, 3> Mat3;
  125. typedef Matx<float_type, 4, 4> Mat4;
  126. typedef Vec<float_type, 3> Vec3;
  127. //! Default constructor. It represents a 4x4 identity matrix.
  128. Affine3();
  129. //! Augmented affine matrix
  130. Affine3(const Mat4& affine);
  131. /**
  132. * The resulting 4x4 matrix is
  133. *
  134. * \f[
  135. * \begin{bmatrix}
  136. * R & t\\
  137. * 0 & 1\\
  138. * \end{bmatrix}
  139. * \f]
  140. *
  141. * @param R 3x3 rotation matrix.
  142. * @param t 3x1 translation vector.
  143. */
  144. Affine3(const Mat3& R, const Vec3& t = Vec3::all(0));
  145. /**
  146. * Rodrigues vector.
  147. *
  148. * The last row of the current matrix is set to [0,0,0,1].
  149. *
  150. * @param rvec 3x1 rotation vector. Its direction indicates the rotation axis and its length
  151. * indicates the rotation angle in radian (using right hand rule).
  152. * @param t 3x1 translation vector.
  153. */
  154. Affine3(const Vec3& rvec, const Vec3& t = Vec3::all(0));
  155. /**
  156. * Combines all constructors above. Supports 4x4, 3x4, 3x3, 1x3, 3x1 sizes of data matrix.
  157. *
  158. * The last row of the current matrix is set to [0,0,0,1] when data is not 4x4.
  159. *
  160. * @param data 1-channel matrix.
  161. * when it is 4x4, it is copied to the current matrix and t is not used.
  162. * When it is 3x4, it is copied to the upper part 3x4 of the current matrix and t is not used.
  163. * When it is 3x3, it is copied to the upper left 3x3 part of the current matrix.
  164. * When it is 3x1 or 1x3, it is treated as a rotation vector and the Rodrigues formula is used
  165. * to compute a 3x3 rotation matrix.
  166. * @param t 3x1 translation vector. It is used only when data is neither 4x4 nor 3x4.
  167. */
  168. explicit Affine3(const Mat& data, const Vec3& t = Vec3::all(0));
  169. //! From 16-element array
  170. explicit Affine3(const float_type* vals);
  171. //! Create an 4x4 identity transform
  172. static Affine3 Identity();
  173. /**
  174. * Rotation matrix.
  175. *
  176. * Copy the rotation matrix to the upper left 3x3 part of the current matrix.
  177. * The remaining elements of the current matrix are not changed.
  178. *
  179. * @param R 3x3 rotation matrix.
  180. *
  181. */
  182. void rotation(const Mat3& R);
  183. /**
  184. * Rodrigues vector.
  185. *
  186. * It sets the upper left 3x3 part of the matrix. The remaining part is unaffected.
  187. *
  188. * @param rvec 3x1 rotation vector. The direction indicates the rotation axis and
  189. * its length indicates the rotation angle in radian (using the right thumb convention).
  190. */
  191. void rotation(const Vec3& rvec);
  192. /**
  193. * Combines rotation methods above. Supports 3x3, 1x3, 3x1 sizes of data matrix.
  194. *
  195. * It sets the upper left 3x3 part of the matrix. The remaining part is unaffected.
  196. *
  197. * @param data 1-channel matrix.
  198. * When it is a 3x3 matrix, it sets the upper left 3x3 part of the current matrix.
  199. * When it is a 1x3 or 3x1 matrix, it is used as a rotation vector. The Rodrigues formula
  200. * is used to compute the rotation matrix and sets the upper left 3x3 part of the current matrix.
  201. */
  202. void rotation(const Mat& data);
  203. /**
  204. * Copy the 3x3 matrix L to the upper left part of the current matrix
  205. *
  206. * It sets the upper left 3x3 part of the matrix. The remaining part is unaffected.
  207. *
  208. * @param L 3x3 matrix.
  209. */
  210. void linear(const Mat3& L);
  211. /**
  212. * Copy t to the first three elements of the last column of the current matrix
  213. *
  214. * It sets the upper right 3x1 part of the matrix. The remaining part is unaffected.
  215. *
  216. * @param t 3x1 translation vector.
  217. */
  218. void translation(const Vec3& t);
  219. //! @return the upper left 3x3 part
  220. Mat3 rotation() const;
  221. //! @return the upper left 3x3 part
  222. Mat3 linear() const;
  223. //! @return the upper right 3x1 part
  224. Vec3 translation() const;
  225. //! Rodrigues vector.
  226. //! @return a vector representing the upper left 3x3 rotation matrix of the current matrix.
  227. //! @warning Since the mapping between rotation vectors and rotation matrices is many to one,
  228. //! this function returns only one rotation vector that represents the current rotation matrix,
  229. //! which is not necessarily the same one set by `rotation(const Vec3& rvec)`.
  230. Vec3 rvec() const;
  231. //! @return the inverse of the current matrix.
  232. Affine3 inv(int method = cv::DECOMP_SVD) const;
  233. //! a.rotate(R) is equivalent to Affine(R, 0) * a;
  234. Affine3 rotate(const Mat3& R) const;
  235. //! a.rotate(rvec) is equivalent to Affine(rvec, 0) * a;
  236. Affine3 rotate(const Vec3& rvec) const;
  237. //! a.translate(t) is equivalent to Affine(E, t) * a, where E is an identity matrix
  238. Affine3 translate(const Vec3& t) const;
  239. //! a.concatenate(affine) is equivalent to affine * a;
  240. Affine3 concatenate(const Affine3& affine) const;
  241. template <typename Y> operator Affine3<Y>() const;
  242. template <typename Y> Affine3<Y> cast() const;
  243. Mat4 matrix;
  244. #if defined EIGEN_WORLD_VERSION && defined EIGEN_GEOMETRY_MODULE_H
  245. Affine3(const Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)>& affine);
  246. Affine3(const Eigen::Transform<T, 3, Eigen::Affine>& affine);
  247. operator Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)>() const;
  248. operator Eigen::Transform<T, 3, Eigen::Affine>() const;
  249. #endif
  250. };
  251. template<typename T> static
  252. Affine3<T> operator*(const Affine3<T>& affine1, const Affine3<T>& affine2);
  253. //! V is a 3-element vector with member fields x, y and z
  254. template<typename T, typename V> static
  255. V operator*(const Affine3<T>& affine, const V& vector);
  256. typedef Affine3<float> Affine3f;
  257. typedef Affine3<double> Affine3d;
  258. static Vec3f operator*(const Affine3f& affine, const Vec3f& vector);
  259. static Vec3d operator*(const Affine3d& affine, const Vec3d& vector);
  260. template<typename _Tp> class DataType< Affine3<_Tp> >
  261. {
  262. public:
  263. typedef Affine3<_Tp> value_type;
  264. typedef Affine3<typename DataType<_Tp>::work_type> work_type;
  265. typedef _Tp channel_type;
  266. enum { generic_type = 0,
  267. channels = 16,
  268. fmt = traits::SafeFmt<channel_type>::fmt + ((channels - 1) << 8)
  269. #ifdef OPENCV_TRAITS_ENABLE_DEPRECATED
  270. ,depth = DataType<channel_type>::depth
  271. ,type = CV_MAKETYPE(depth, channels)
  272. #endif
  273. };
  274. typedef Vec<channel_type, channels> vec_type;
  275. };
  276. namespace traits {
  277. template<typename _Tp>
  278. struct Depth< Affine3<_Tp> > { enum { value = Depth<_Tp>::value }; };
  279. template<typename _Tp>
  280. struct Type< Affine3<_Tp> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, 16) }; };
  281. } // namespace
  282. //! @} core
  283. }
  284. //! @cond IGNORED
  285. ///////////////////////////////////////////////////////////////////////////////////
  286. // Implementation
  287. template<typename T> inline
  288. cv::Affine3<T>::Affine3()
  289. : matrix(Mat4::eye())
  290. {}
  291. template<typename T> inline
  292. cv::Affine3<T>::Affine3(const Mat4& affine)
  293. : matrix(affine)
  294. {}
  295. template<typename T> inline
  296. cv::Affine3<T>::Affine3(const Mat3& R, const Vec3& t)
  297. {
  298. rotation(R);
  299. translation(t);
  300. matrix.val[12] = matrix.val[13] = matrix.val[14] = 0;
  301. matrix.val[15] = 1;
  302. }
  303. template<typename T> inline
  304. cv::Affine3<T>::Affine3(const Vec3& _rvec, const Vec3& t)
  305. {
  306. rotation(_rvec);
  307. translation(t);
  308. matrix.val[12] = matrix.val[13] = matrix.val[14] = 0;
  309. matrix.val[15] = 1;
  310. }
  311. template<typename T> inline
  312. cv::Affine3<T>::Affine3(const cv::Mat& data, const Vec3& t)
  313. {
  314. CV_Assert(data.type() == cv::traits::Type<T>::value);
  315. CV_Assert(data.channels() == 1);
  316. if (data.cols == 4 && data.rows == 4)
  317. {
  318. data.copyTo(matrix);
  319. return;
  320. }
  321. else if (data.cols == 4 && data.rows == 3)
  322. {
  323. rotation(data(Rect(0, 0, 3, 3)));
  324. translation(data(Rect(3, 0, 1, 3)));
  325. }
  326. else
  327. {
  328. rotation(data);
  329. translation(t);
  330. }
  331. matrix.val[12] = matrix.val[13] = matrix.val[14] = 0;
  332. matrix.val[15] = 1;
  333. }
  334. template<typename T> inline
  335. cv::Affine3<T>::Affine3(const float_type* vals) : matrix(vals)
  336. {}
  337. template<typename T> inline
  338. cv::Affine3<T> cv::Affine3<T>::Identity()
  339. {
  340. return Affine3<T>(cv::Affine3<T>::Mat4::eye());
  341. }
  342. template<typename T> inline
  343. void cv::Affine3<T>::rotation(const Mat3& R)
  344. {
  345. linear(R);
  346. }
  347. template<typename T> inline
  348. void cv::Affine3<T>::rotation(const Vec3& _rvec)
  349. {
  350. double theta = norm(_rvec);
  351. if (theta < DBL_EPSILON)
  352. rotation(Mat3::eye());
  353. else
  354. {
  355. double c = std::cos(theta);
  356. double s = std::sin(theta);
  357. double c1 = 1. - c;
  358. double itheta = (theta != 0) ? 1./theta : 0.;
  359. Point3_<T> r = _rvec*itheta;
  360. 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 );
  361. Mat3 r_x( 0, -r.z, r.y, r.z, 0, -r.x, -r.y, r.x, 0 );
  362. // R = cos(theta)*I + (1 - cos(theta))*r*rT + sin(theta)*[r_x]
  363. // where [r_x] is [0 -rz ry; rz 0 -rx; -ry rx 0]
  364. Mat3 R = c*Mat3::eye() + c1*rrt + s*r_x;
  365. rotation(R);
  366. }
  367. }
  368. //Combines rotation methods above. Supports 3x3, 1x3, 3x1 sizes of data matrix;
  369. template<typename T> inline
  370. void cv::Affine3<T>::rotation(const cv::Mat& data)
  371. {
  372. CV_Assert(data.type() == cv::traits::Type<T>::value);
  373. CV_Assert(data.channels() == 1);
  374. if (data.cols == 3 && data.rows == 3)
  375. {
  376. Mat3 R;
  377. data.copyTo(R);
  378. rotation(R);
  379. }
  380. else if ((data.cols == 3 && data.rows == 1) || (data.cols == 1 && data.rows == 3))
  381. {
  382. Vec3 _rvec;
  383. data.reshape(1, 3).copyTo(_rvec);
  384. rotation(_rvec);
  385. }
  386. else
  387. CV_Error(Error::StsError, "Input matrix can only be 3x3, 1x3 or 3x1");
  388. }
  389. template<typename T> inline
  390. void cv::Affine3<T>::linear(const Mat3& L)
  391. {
  392. matrix.val[0] = L.val[0]; matrix.val[1] = L.val[1]; matrix.val[ 2] = L.val[2];
  393. matrix.val[4] = L.val[3]; matrix.val[5] = L.val[4]; matrix.val[ 6] = L.val[5];
  394. matrix.val[8] = L.val[6]; matrix.val[9] = L.val[7]; matrix.val[10] = L.val[8];
  395. }
  396. template<typename T> inline
  397. void cv::Affine3<T>::translation(const Vec3& t)
  398. {
  399. matrix.val[3] = t[0]; matrix.val[7] = t[1]; matrix.val[11] = t[2];
  400. }
  401. template<typename T> inline
  402. typename cv::Affine3<T>::Mat3 cv::Affine3<T>::rotation() const
  403. {
  404. return linear();
  405. }
  406. template<typename T> inline
  407. typename cv::Affine3<T>::Mat3 cv::Affine3<T>::linear() const
  408. {
  409. typename cv::Affine3<T>::Mat3 R;
  410. R.val[0] = matrix.val[0]; R.val[1] = matrix.val[1]; R.val[2] = matrix.val[ 2];
  411. R.val[3] = matrix.val[4]; R.val[4] = matrix.val[5]; R.val[5] = matrix.val[ 6];
  412. R.val[6] = matrix.val[8]; R.val[7] = matrix.val[9]; R.val[8] = matrix.val[10];
  413. return R;
  414. }
  415. template<typename T> inline
  416. typename cv::Affine3<T>::Vec3 cv::Affine3<T>::translation() const
  417. {
  418. return Vec3(matrix.val[3], matrix.val[7], matrix.val[11]);
  419. }
  420. template<typename T> inline
  421. typename cv::Affine3<T>::Vec3 cv::Affine3<T>::rvec() const
  422. {
  423. cv::Vec3d w;
  424. cv::Matx33d u, vt, R = rotation();
  425. cv::SVD::compute(R, w, u, vt, cv::SVD::FULL_UV + cv::SVD::MODIFY_A);
  426. R = u * vt;
  427. double rx = R.val[7] - R.val[5];
  428. double ry = R.val[2] - R.val[6];
  429. double rz = R.val[3] - R.val[1];
  430. double s = std::sqrt((rx*rx + ry*ry + rz*rz)*0.25);
  431. double c = (R.val[0] + R.val[4] + R.val[8] - 1) * 0.5;
  432. c = c > 1.0 ? 1.0 : c < -1.0 ? -1.0 : c;
  433. double theta = acos(c);
  434. if( s < 1e-5 )
  435. {
  436. if( c > 0 )
  437. rx = ry = rz = 0;
  438. else
  439. {
  440. double t;
  441. t = (R.val[0] + 1) * 0.5;
  442. rx = std::sqrt(std::max(t, 0.0));
  443. t = (R.val[4] + 1) * 0.5;
  444. ry = std::sqrt(std::max(t, 0.0)) * (R.val[1] < 0 ? -1.0 : 1.0);
  445. t = (R.val[8] + 1) * 0.5;
  446. rz = std::sqrt(std::max(t, 0.0)) * (R.val[2] < 0 ? -1.0 : 1.0);
  447. if( fabs(rx) < fabs(ry) && fabs(rx) < fabs(rz) && (R.val[5] > 0) != (ry*rz > 0) )
  448. rz = -rz;
  449. theta /= std::sqrt(rx*rx + ry*ry + rz*rz);
  450. rx *= theta;
  451. ry *= theta;
  452. rz *= theta;
  453. }
  454. }
  455. else
  456. {
  457. double vth = 1/(2*s);
  458. vth *= theta;
  459. rx *= vth; ry *= vth; rz *= vth;
  460. }
  461. return cv::Vec3d(rx, ry, rz);
  462. }
  463. template<typename T> inline
  464. cv::Affine3<T> cv::Affine3<T>::inv(int method) const
  465. {
  466. return matrix.inv(method);
  467. }
  468. template<typename T> inline
  469. cv::Affine3<T> cv::Affine3<T>::rotate(const Mat3& R) const
  470. {
  471. Mat3 Lc = linear();
  472. Vec3 tc = translation();
  473. Mat4 result;
  474. result.val[12] = result.val[13] = result.val[14] = 0;
  475. result.val[15] = 1;
  476. for(int j = 0; j < 3; ++j)
  477. {
  478. for(int i = 0; i < 3; ++i)
  479. {
  480. float_type value = 0;
  481. for(int k = 0; k < 3; ++k)
  482. value += R(j, k) * Lc(k, i);
  483. result(j, i) = value;
  484. }
  485. result(j, 3) = R.row(j).dot(tc.t());
  486. }
  487. return result;
  488. }
  489. template<typename T> inline
  490. cv::Affine3<T> cv::Affine3<T>::rotate(const Vec3& _rvec) const
  491. {
  492. return rotate(Affine3f(_rvec).rotation());
  493. }
  494. template<typename T> inline
  495. cv::Affine3<T> cv::Affine3<T>::translate(const Vec3& t) const
  496. {
  497. Mat4 m = matrix;
  498. m.val[ 3] += t[0];
  499. m.val[ 7] += t[1];
  500. m.val[11] += t[2];
  501. return m;
  502. }
  503. template<typename T> inline
  504. cv::Affine3<T> cv::Affine3<T>::concatenate(const Affine3<T>& affine) const
  505. {
  506. return (*this).rotate(affine.rotation()).translate(affine.translation());
  507. }
  508. template<typename T> template <typename Y> inline
  509. cv::Affine3<T>::operator Affine3<Y>() const
  510. {
  511. return Affine3<Y>(matrix);
  512. }
  513. template<typename T> template <typename Y> inline
  514. cv::Affine3<Y> cv::Affine3<T>::cast() const
  515. {
  516. return Affine3<Y>(matrix);
  517. }
  518. template<typename T> inline
  519. cv::Affine3<T> cv::operator*(const cv::Affine3<T>& affine1, const cv::Affine3<T>& affine2)
  520. {
  521. return affine2.concatenate(affine1);
  522. }
  523. template<typename T, typename V> inline
  524. V cv::operator*(const cv::Affine3<T>& affine, const V& v)
  525. {
  526. const typename Affine3<T>::Mat4& m = affine.matrix;
  527. V r;
  528. r.x = m.val[0] * v.x + m.val[1] * v.y + m.val[ 2] * v.z + m.val[ 3];
  529. r.y = m.val[4] * v.x + m.val[5] * v.y + m.val[ 6] * v.z + m.val[ 7];
  530. r.z = m.val[8] * v.x + m.val[9] * v.y + m.val[10] * v.z + m.val[11];
  531. return r;
  532. }
  533. static inline
  534. cv::Vec3f cv::operator*(const cv::Affine3f& affine, const cv::Vec3f& v)
  535. {
  536. const cv::Matx44f& m = affine.matrix;
  537. cv::Vec3f r;
  538. r.val[0] = m.val[0] * v[0] + m.val[1] * v[1] + m.val[ 2] * v[2] + m.val[ 3];
  539. r.val[1] = m.val[4] * v[0] + m.val[5] * v[1] + m.val[ 6] * v[2] + m.val[ 7];
  540. r.val[2] = m.val[8] * v[0] + m.val[9] * v[1] + m.val[10] * v[2] + m.val[11];
  541. return r;
  542. }
  543. static inline
  544. cv::Vec3d cv::operator*(const cv::Affine3d& affine, const cv::Vec3d& v)
  545. {
  546. const cv::Matx44d& m = affine.matrix;
  547. cv::Vec3d r;
  548. r.val[0] = m.val[0] * v[0] + m.val[1] * v[1] + m.val[ 2] * v[2] + m.val[ 3];
  549. r.val[1] = m.val[4] * v[0] + m.val[5] * v[1] + m.val[ 6] * v[2] + m.val[ 7];
  550. r.val[2] = m.val[8] * v[0] + m.val[9] * v[1] + m.val[10] * v[2] + m.val[11];
  551. return r;
  552. }
  553. #if defined EIGEN_WORLD_VERSION && defined EIGEN_GEOMETRY_MODULE_H
  554. template<typename T> inline
  555. cv::Affine3<T>::Affine3(const Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)>& affine)
  556. {
  557. cv::Mat(4, 4, cv::traits::Type<T>::value, affine.matrix().data()).copyTo(matrix);
  558. }
  559. template<typename T> inline
  560. cv::Affine3<T>::Affine3(const Eigen::Transform<T, 3, Eigen::Affine>& affine)
  561. {
  562. Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)> a = affine;
  563. cv::Mat(4, 4, cv::traits::Type<T>::value, a.matrix().data()).copyTo(matrix);
  564. }
  565. template<typename T> inline
  566. cv::Affine3<T>::operator Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)>() const
  567. {
  568. Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)> r;
  569. cv::Mat hdr(4, 4, cv::traits::Type<T>::value, r.matrix().data());
  570. cv::Mat(matrix, false).copyTo(hdr);
  571. return r;
  572. }
  573. template<typename T> inline
  574. cv::Affine3<T>::operator Eigen::Transform<T, 3, Eigen::Affine>() const
  575. {
  576. return this->operator Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)>();
  577. }
  578. #endif /* defined EIGEN_WORLD_VERSION && defined EIGEN_GEOMETRY_MODULE_H */
  579. //! @endcond
  580. #endif /* __cplusplus */
  581. #endif /* OPENCV_CORE_AFFINE3_HPP */