eigen.hpp 14 KB

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