47
47
48
48
#include " opencv2/core.hpp"
49
49
50
+ #if EIGEN_WORLD_VERSION == 3 && EIGEN_MAJOR_VERSION >= 3
51
+ #include < unsupported/Eigen/CXX11/Tensor>
52
+ #define OPENCV_EIGEN_TENSOR_SUPPORT
53
+ #endif // EIGEN_WORLD_VERSION == 3 && EIGEN_MAJOR_VERSION >= 3
54
+
50
55
#if defined _MSC_VER && _MSC_VER >= 1200
51
56
#pragma warning( disable: 4714 ) // __forceinline is not inlined
52
57
#pragma warning( disable: 4127 ) // conditional expression is constant
@@ -59,6 +64,107 @@ namespace cv
59
64
// ! @addtogroup core_eigen
60
65
// ! @{
61
66
67
+ #ifdef OPENCV_EIGEN_TENSOR_SUPPORT
68
+ /* * @brief Converts an Eigen::Tensor to a cv::Mat.
69
+
70
+ The method converts an Eigen::Tensor with shape (H x W x C) to a cv::Mat where:
71
+ H = number of rows
72
+ W = number of columns
73
+ C = number of channels
74
+
75
+ Usage:
76
+ \code
77
+ Eigen::Tensor<float, 3, Eigen::RowMajor> a_tensor(...);
78
+ // populate tensor with values
79
+ Mat a_mat;
80
+ eigen2cv(a_tensor, a_mat);
81
+ \endcode
82
+ */
83
+ template <typename _Tp, int _layout> static inline
84
+ void eigen2cv ( const Eigen::Tensor<_Tp, 3 , _layout> &src, OutputArray dst )
85
+ {
86
+ if ( !(_layout & Eigen::RowMajorBit) )
87
+ {
88
+ const std::array<int , 3 > shuffle{2 , 1 , 0 };
89
+ Eigen::Tensor<_Tp, 3 , !_layout> row_major_tensor = src.swap_layout ().shuffle (shuffle);
90
+ Mat _src (src.dimension (0 ), src.dimension (1 ), CV_MAKETYPE (DataType<_Tp>::type, src.dimension (2 )), row_major_tensor.data ());
91
+ _src.copyTo (dst);
92
+ }
93
+ else
94
+ {
95
+ Mat _src (src.dimension (0 ), src.dimension (1 ), CV_MAKETYPE (DataType<_Tp>::type, src.dimension (2 )), (void *)src.data ());
96
+ _src.copyTo (dst);
97
+ }
98
+ }
99
+
100
+ /* * @brief Converts a cv::Mat to an Eigen::Tensor.
101
+
102
+ The method converts a cv::Mat to an Eigen Tensor with shape (H x W x C) where:
103
+ H = number of rows
104
+ W = number of columns
105
+ C = number of channels
106
+
107
+ Usage:
108
+ \code
109
+ Mat a_mat(...);
110
+ // populate Mat with values
111
+ Eigen::Tensor<float, 3, Eigen::RowMajor> a_tensor(...);
112
+ cv2eigen(a_mat, a_tensor);
113
+ \endcode
114
+ */
115
+ template <typename _Tp, int _layout> static inline
116
+ void cv2eigen ( const Mat &src, Eigen::Tensor<_Tp, 3 , _layout> &dst )
117
+ {
118
+ if ( !(_layout & Eigen::RowMajorBit) )
119
+ {
120
+ Eigen::Tensor<_Tp, 3 , !_layout> row_major_tensor (src.rows , src.cols , src.channels ());
121
+ Mat _dst (src.rows , src.cols , CV_MAKETYPE (DataType<_Tp>::type, src.channels ()), row_major_tensor.data ());
122
+ if (src.type () == _dst.type ())
123
+ src.copyTo (_dst);
124
+ else
125
+ src.convertTo (_dst, _dst.type ());
126
+ const std::array<int , 3 > shuffle{2 , 1 , 0 };
127
+ dst = row_major_tensor.swap_layout ().shuffle (shuffle);
128
+ }
129
+ else
130
+ {
131
+ dst.resize (src.rows , src.cols , src.channels ());
132
+ Mat _dst (src.rows , src.cols , CV_MAKETYPE (DataType<_Tp>::type, src.channels ()), dst.data ());
133
+ if (src.type () == _dst.type ())
134
+ src.copyTo (_dst);
135
+ else
136
+ src.convertTo (_dst, _dst.type ());
137
+ }
138
+ }
139
+
140
+ /* * @brief Maps cv::Mat data to an Eigen::TensorMap.
141
+
142
+ The method wraps an existing Mat data array with an Eigen TensorMap of shape (H x W x C) where:
143
+ H = number of rows
144
+ W = number of columns
145
+ C = number of channels
146
+
147
+ Explicit instantiation of the return type is required.
148
+
149
+ @note Caller should be aware of the lifetime of the cv::Mat instance and take appropriate safety measures.
150
+ The cv::Mat instance will retain ownership of the data and the Eigen::TensorMap will lose access when the cv::Mat data is deallocated.
151
+
152
+ The example below initializes a cv::Mat and produces an Eigen::TensorMap:
153
+ \code
154
+ float arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
155
+ Mat a_mat(2, 2, CV_32FC3, arr);
156
+ Eigen::TensorMap<Eigen::Tensor<float, 3, Eigen::RowMajor>> a_tensormap = cv2eigen_tensormap<float>(a_mat);
157
+ \endcode
158
+ */
159
+ template <typename _Tp> static inline
160
+ Eigen::TensorMap<Eigen::Tensor<_Tp, 3 , Eigen::RowMajor>> cv2eigen_tensormap (const cv::InputArray &src)
161
+ {
162
+ Mat mat = src.getMat ();
163
+ CV_CheckTypeEQ (mat.type (), CV_MAKETYPE (traits::Type<_Tp>::value, mat.channels ()), " " );
164
+ return Eigen::TensorMap<Eigen::Tensor<_Tp, 3 , Eigen::RowMajor>>((_Tp *)mat.data , mat.rows , mat.cols , mat.channels ());
165
+ }
166
+ #endif // OPENCV_EIGEN_TENSOR_SUPPORT
167
+
62
168
template <typename _Tp, int _rows, int _cols, int _options, int _maxRows, int _maxCols> static inline
63
169
void eigen2cv ( const Eigen::Matrix<_Tp, _rows, _cols, _options, _maxRows, _maxCols>& src, OutputArray dst )
64
170
{
0 commit comments