eigen.hpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  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_EIGEN_HPP
  44. #define OPENCV_CORE_EIGEN_HPP
  45. #ifndef EIGEN_WORLD_VERSION
  46. #error "Wrong usage of OpenCV's Eigen utility header. Include Eigen's headers first. See https://github.com/opencv/opencv/issues/17366"
  47. #endif
  48. #include "opencv2/core.hpp"
  49. #if defined _MSC_VER && _MSC_VER >= 1200
  50. #define NOMINMAX // fix https://github.com/opencv/opencv/issues/17548
  51. #pragma warning( disable: 4714 ) //__forceinline is not inlined
  52. #pragma warning( disable: 4127 ) //conditional expression is constant
  53. #pragma warning( disable: 4244 ) //conversion from '__int64' to 'int', possible loss of data
  54. #endif
  55. #if !defined(OPENCV_DISABLE_EIGEN_TENSOR_SUPPORT)
  56. #if EIGEN_WORLD_VERSION == 3 && EIGEN_MAJOR_VERSION >= 3 \
  57. && defined(CV_CXX11) && defined(CV_CXX_STD_ARRAY)
  58. #include <unsupported/Eigen/CXX11/Tensor>
  59. #define OPENCV_EIGEN_TENSOR_SUPPORT 1
  60. #endif // EIGEN_WORLD_VERSION == 3 && EIGEN_MAJOR_VERSION >= 3
  61. #endif // !defined(OPENCV_DISABLE_EIGEN_TENSOR_SUPPORT)
  62. namespace cv
  63. {
  64. /** @addtogroup core_eigen
  65. These functions are provided for OpenCV-Eigen interoperability. They convert `Mat`
  66. objects to corresponding `Eigen::Matrix` objects and vice-versa. Consult the [Eigen
  67. documentation](https://eigen.tuxfamily.org/dox/group__TutorialMatrixClass.html) for
  68. information about the `Matrix` template type.
  69. @note Using these functions requires the `Eigen/Dense` or similar header to be
  70. included before this header.
  71. */
  72. //! @{
  73. #if defined(OPENCV_EIGEN_TENSOR_SUPPORT) || defined(CV_DOXYGEN)
  74. /** @brief Converts an Eigen::Tensor to a cv::Mat.
  75. The method converts an Eigen::Tensor with shape (H x W x C) to a cv::Mat where:
  76. H = number of rows
  77. W = number of columns
  78. C = number of channels
  79. Usage:
  80. \code
  81. Eigen::Tensor<float, 3, Eigen::RowMajor> a_tensor(...);
  82. // populate tensor with values
  83. Mat a_mat;
  84. eigen2cv(a_tensor, a_mat);
  85. \endcode
  86. */
  87. template <typename _Tp, int _layout> static inline
  88. void eigen2cv( const Eigen::Tensor<_Tp, 3, _layout> &src, OutputArray dst )
  89. {
  90. if( !(_layout & Eigen::RowMajorBit) )
  91. {
  92. const std::array<int, 3> shuffle{2, 1, 0};
  93. Eigen::Tensor<_Tp, 3, !_layout> row_major_tensor = src.swap_layout().shuffle(shuffle);
  94. Mat _src(src.dimension(0), src.dimension(1), CV_MAKETYPE(DataType<_Tp>::type, src.dimension(2)), row_major_tensor.data());
  95. _src.copyTo(dst);
  96. }
  97. else
  98. {
  99. Mat _src(src.dimension(0), src.dimension(1), CV_MAKETYPE(DataType<_Tp>::type, src.dimension(2)), (void *)src.data());
  100. _src.copyTo(dst);
  101. }
  102. }
  103. /** @brief Converts a cv::Mat to an Eigen::Tensor.
  104. The method converts a cv::Mat to an Eigen Tensor with shape (H x W x C) where:
  105. H = number of rows
  106. W = number of columns
  107. C = number of channels
  108. Usage:
  109. \code
  110. Mat a_mat(...);
  111. // populate Mat with values
  112. Eigen::Tensor<float, 3, Eigen::RowMajor> a_tensor(...);
  113. cv2eigen(a_mat, a_tensor);
  114. \endcode
  115. */
  116. template <typename _Tp, int _layout> static inline
  117. void cv2eigen( const Mat &src, Eigen::Tensor<_Tp, 3, _layout> &dst )
  118. {
  119. if( !(_layout & Eigen::RowMajorBit) )
  120. {
  121. Eigen::Tensor<_Tp, 3, !_layout> row_major_tensor(src.rows, src.cols, src.channels());
  122. Mat _dst(src.rows, src.cols, CV_MAKETYPE(DataType<_Tp>::type, src.channels()), row_major_tensor.data());
  123. if (src.type() == _dst.type())
  124. src.copyTo(_dst);
  125. else
  126. src.convertTo(_dst, _dst.type());
  127. const std::array<int, 3> shuffle{2, 1, 0};
  128. dst = row_major_tensor.swap_layout().shuffle(shuffle);
  129. }
  130. else
  131. {
  132. dst.resize(src.rows, src.cols, src.channels());
  133. Mat _dst(src.rows, src.cols, CV_MAKETYPE(DataType<_Tp>::type, src.channels()), dst.data());
  134. if (src.type() == _dst.type())
  135. src.copyTo(_dst);
  136. else
  137. src.convertTo(_dst, _dst.type());
  138. }
  139. }
  140. /** @brief Maps cv::Mat data to an Eigen::TensorMap.
  141. The method wraps an existing Mat data array with an Eigen TensorMap of shape (H x W x C) where:
  142. H = number of rows
  143. W = number of columns
  144. C = number of channels
  145. Explicit instantiation of the return type is required.
  146. @note Caller should be aware of the lifetime of the cv::Mat instance and take appropriate safety measures.
  147. The cv::Mat instance will retain ownership of the data and the Eigen::TensorMap will lose access when the cv::Mat data is deallocated.
  148. The example below initializes a cv::Mat and produces an Eigen::TensorMap:
  149. \code
  150. float arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
  151. Mat a_mat(2, 2, CV_32FC3, arr);
  152. Eigen::TensorMap<Eigen::Tensor<float, 3, Eigen::RowMajor>> a_tensormap = cv2eigen_tensormap<float>(a_mat);
  153. \endcode
  154. */
  155. template <typename _Tp> static inline
  156. Eigen::TensorMap<Eigen::Tensor<_Tp, 3, Eigen::RowMajor>> cv2eigen_tensormap(InputArray src)
  157. {
  158. Mat mat = src.getMat();
  159. CV_CheckTypeEQ(mat.type(), CV_MAKETYPE(traits::Type<_Tp>::value, mat.channels()), "");
  160. return Eigen::TensorMap<Eigen::Tensor<_Tp, 3, Eigen::RowMajor>>((_Tp *)mat.data, mat.rows, mat.cols, mat.channels());
  161. }
  162. #endif // OPENCV_EIGEN_TENSOR_SUPPORT
  163. template<typename _Tp, int _rows, int _cols, int _options, int _maxRows, int _maxCols> static inline
  164. void eigen2cv( const Eigen::Matrix<_Tp, _rows, _cols, _options, _maxRows, _maxCols>& src, OutputArray dst )
  165. {
  166. if( !(src.Flags & Eigen::RowMajorBit) )
  167. {
  168. Mat _src(src.cols(), src.rows(), traits::Type<_Tp>::value,
  169. (void*)src.data(), src.outerStride()*sizeof(_Tp));
  170. transpose(_src, dst);
  171. }
  172. else
  173. {
  174. Mat _src(src.rows(), src.cols(), traits::Type<_Tp>::value,
  175. (void*)src.data(), src.outerStride()*sizeof(_Tp));
  176. _src.copyTo(dst);
  177. }
  178. }
  179. // Matx case
  180. template<typename _Tp, int _rows, int _cols, int _options, int _maxRows, int _maxCols> static inline
  181. void eigen2cv( const Eigen::Matrix<_Tp, _rows, _cols, _options, _maxRows, _maxCols>& src,
  182. Matx<_Tp, _rows, _cols>& dst )
  183. {
  184. if( !(src.Flags & Eigen::RowMajorBit) )
  185. {
  186. dst = Matx<_Tp, _cols, _rows>(static_cast<const _Tp*>(src.data())).t();
  187. }
  188. else
  189. {
  190. dst = Matx<_Tp, _rows, _cols>(static_cast<const _Tp*>(src.data()));
  191. }
  192. }
  193. template<typename _Tp, int _rows, int _cols, int _options, int _maxRows, int _maxCols> static inline
  194. void cv2eigen( const Mat& src,
  195. Eigen::Matrix<_Tp, _rows, _cols, _options, _maxRows, _maxCols>& dst )
  196. {
  197. CV_DbgAssert(src.rows == _rows && src.cols == _cols);
  198. if( !(dst.Flags & Eigen::RowMajorBit) )
  199. {
  200. const Mat _dst(src.cols, src.rows, traits::Type<_Tp>::value,
  201. dst.data(), (size_t)(dst.outerStride()*sizeof(_Tp)));
  202. if( src.type() == _dst.type() )
  203. transpose(src, _dst);
  204. else if( src.cols == src.rows )
  205. {
  206. src.convertTo(_dst, _dst.type());
  207. transpose(_dst, _dst);
  208. }
  209. else
  210. Mat(src.t()).convertTo(_dst, _dst.type());
  211. }
  212. else
  213. {
  214. const Mat _dst(src.rows, src.cols, traits::Type<_Tp>::value,
  215. dst.data(), (size_t)(dst.outerStride()*sizeof(_Tp)));
  216. src.convertTo(_dst, _dst.type());
  217. }
  218. }
  219. // Matx case
  220. template<typename _Tp, int _rows, int _cols, int _options, int _maxRows, int _maxCols> static inline
  221. void cv2eigen( const Matx<_Tp, _rows, _cols>& src,
  222. Eigen::Matrix<_Tp, _rows, _cols, _options, _maxRows, _maxCols>& dst )
  223. {
  224. if( !(dst.Flags & Eigen::RowMajorBit) )
  225. {
  226. const Mat _dst(_cols, _rows, traits::Type<_Tp>::value,
  227. dst.data(), (size_t)(dst.outerStride()*sizeof(_Tp)));
  228. transpose(src, _dst);
  229. }
  230. else
  231. {
  232. const Mat _dst(_rows, _cols, traits::Type<_Tp>::value,
  233. dst.data(), (size_t)(dst.outerStride()*sizeof(_Tp)));
  234. Mat(src).copyTo(_dst);
  235. }
  236. }
  237. template<typename _Tp> static inline
  238. void cv2eigen( const Mat& src,
  239. Eigen::Matrix<_Tp, Eigen::Dynamic, Eigen::Dynamic>& dst )
  240. {
  241. dst.resize(src.rows, src.cols);
  242. if( !(dst.Flags & Eigen::RowMajorBit) )
  243. {
  244. const Mat _dst(src.cols, src.rows, traits::Type<_Tp>::value,
  245. dst.data(), (size_t)(dst.outerStride()*sizeof(_Tp)));
  246. if( src.type() == _dst.type() )
  247. transpose(src, _dst);
  248. else if( src.cols == src.rows )
  249. {
  250. src.convertTo(_dst, _dst.type());
  251. transpose(_dst, _dst);
  252. }
  253. else
  254. Mat(src.t()).convertTo(_dst, _dst.type());
  255. }
  256. else
  257. {
  258. const Mat _dst(src.rows, src.cols, traits::Type<_Tp>::value,
  259. dst.data(), (size_t)(dst.outerStride()*sizeof(_Tp)));
  260. src.convertTo(_dst, _dst.type());
  261. }
  262. }
  263. // Matx case
  264. template<typename _Tp, int _rows, int _cols> static inline
  265. void cv2eigen( const Matx<_Tp, _rows, _cols>& src,
  266. Eigen::Matrix<_Tp, Eigen::Dynamic, Eigen::Dynamic>& dst )
  267. {
  268. dst.resize(_rows, _cols);
  269. if( !(dst.Flags & Eigen::RowMajorBit) )
  270. {
  271. const Mat _dst(_cols, _rows, traits::Type<_Tp>::value,
  272. dst.data(), (size_t)(dst.outerStride()*sizeof(_Tp)));
  273. transpose(src, _dst);
  274. }
  275. else
  276. {
  277. const Mat _dst(_rows, _cols, traits::Type<_Tp>::value,
  278. dst.data(), (size_t)(dst.outerStride()*sizeof(_Tp)));
  279. Mat(src).copyTo(_dst);
  280. }
  281. }
  282. template<typename _Tp> static inline
  283. void cv2eigen( const Mat& src,
  284. Eigen::Matrix<_Tp, Eigen::Dynamic, 1>& dst )
  285. {
  286. CV_Assert(src.cols == 1);
  287. dst.resize(src.rows);
  288. if( !(dst.Flags & Eigen::RowMajorBit) )
  289. {
  290. const Mat _dst(src.cols, src.rows, traits::Type<_Tp>::value,
  291. dst.data(), (size_t)(dst.outerStride()*sizeof(_Tp)));
  292. if( src.type() == _dst.type() )
  293. transpose(src, _dst);
  294. else
  295. Mat(src.t()).convertTo(_dst, _dst.type());
  296. }
  297. else
  298. {
  299. const Mat _dst(src.rows, src.cols, traits::Type<_Tp>::value,
  300. dst.data(), (size_t)(dst.outerStride()*sizeof(_Tp)));
  301. src.convertTo(_dst, _dst.type());
  302. }
  303. }
  304. // Matx case
  305. template<typename _Tp, int _rows> static inline
  306. void cv2eigen( const Matx<_Tp, _rows, 1>& src,
  307. Eigen::Matrix<_Tp, Eigen::Dynamic, 1>& dst )
  308. {
  309. dst.resize(_rows);
  310. if( !(dst.Flags & Eigen::RowMajorBit) )
  311. {
  312. const Mat _dst(1, _rows, traits::Type<_Tp>::value,
  313. dst.data(), (size_t)(dst.outerStride()*sizeof(_Tp)));
  314. transpose(src, _dst);
  315. }
  316. else
  317. {
  318. const Mat _dst(_rows, 1, traits::Type<_Tp>::value,
  319. dst.data(), (size_t)(dst.outerStride()*sizeof(_Tp)));
  320. src.copyTo(_dst);
  321. }
  322. }
  323. template<typename _Tp> static inline
  324. void cv2eigen( const Mat& src,
  325. Eigen::Matrix<_Tp, 1, Eigen::Dynamic>& dst )
  326. {
  327. CV_Assert(src.rows == 1);
  328. dst.resize(src.cols);
  329. if( !(dst.Flags & Eigen::RowMajorBit) )
  330. {
  331. const Mat _dst(src.cols, src.rows, traits::Type<_Tp>::value,
  332. dst.data(), (size_t)(dst.outerStride()*sizeof(_Tp)));
  333. if( src.type() == _dst.type() )
  334. transpose(src, _dst);
  335. else
  336. Mat(src.t()).convertTo(_dst, _dst.type());
  337. }
  338. else
  339. {
  340. const Mat _dst(src.rows, src.cols, traits::Type<_Tp>::value,
  341. dst.data(), (size_t)(dst.outerStride()*sizeof(_Tp)));
  342. src.convertTo(_dst, _dst.type());
  343. }
  344. }
  345. //Matx
  346. template<typename _Tp, int _cols> static inline
  347. void cv2eigen( const Matx<_Tp, 1, _cols>& src,
  348. Eigen::Matrix<_Tp, 1, Eigen::Dynamic>& dst )
  349. {
  350. dst.resize(_cols);
  351. if( !(dst.Flags & Eigen::RowMajorBit) )
  352. {
  353. const Mat _dst(_cols, 1, traits::Type<_Tp>::value,
  354. dst.data(), (size_t)(dst.outerStride()*sizeof(_Tp)));
  355. transpose(src, _dst);
  356. }
  357. else
  358. {
  359. const Mat _dst(1, _cols, traits::Type<_Tp>::value,
  360. dst.data(), (size_t)(dst.outerStride()*sizeof(_Tp)));
  361. Mat(src).copyTo(_dst);
  362. }
  363. }
  364. //! @}
  365. } // cv
  366. #endif