In my code, I have to convert cv::Mat
to Eigen::Matrix
so that I can use some of the functionalities of the Eigen
library. I believe a straightforward option would be to manually copy paste each element of cv::Mat
into Eigen::Matrix
. However, I stumbled upon this question on SO and found out about the cv::cv2eigen
function. It's located in opencv2/core/eigen.hpp
file.
Here is the sample code:
#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/core/eigen.hpp>
#include <Eigen/Core>
int main(int argc, char const *argv[]) {
cv::Mat cv_mat = cv::Mat::eye(3, 3, CV_64FC1);
std::cout << cv_mat << std::endl;
Eigen::Matrix3d eigen_mat;
cv::cv2eigen(cv_mat, eigen_mat);
std::cout << eigen_mat << std::endl;
return 0;
}
However, weirdly enough, upon trying to build, I get way too many compilation errors from opencv2/core/eigen.hpp
file:
/usr/local/<blah_blah>/include/opencv4/opencv2/core/eigen.hpp:63:22: error: ‘Eigen’ does not name a type; did you mean ‘eigen’?
void eigen2cv( const Eigen::Matrix<_Tp, _rows, _cols, _options, _maxRows, _maxCols>& src, OutputArray dst )
^~~~~
eigen
/usr/local/<blah_blah>/include/opencv4/opencv2/core/eigen.hpp:63:35: error: expected unqualified-id before ‘<’ token
void eigen2cv( const Eigen::Matrix<_Tp, _rows, _cols, _options, _maxRows, _maxCols>& src, OutputArray dst )
^
/usr/local/<blah_blah>/include/opencv4/opencv2/core/eigen.hpp:63:35: error: expected ‘)’ before ‘<’ token
/usr/local/<blah_blah>/include/opencv4/opencv2/core/eigen.hpp:63:35: error: expected initializer before ‘<’ token
/usr/local/<blah_blah>/include/opencv4/opencv2/core/eigen.hpp:81:22: error: ‘Eigen’ does not name a type; did you mean ‘eigen’?
void eigen2cv( const Eigen::Matrix<_Tp, _rows, _cols, _options, _maxRows, _maxCols>& src,
^~~~~
eigen
.
.
.
/usr/local/<blah_blah>/include/opencv4/opencv2/core/eigen.hpp:234:6: error: redefinition of ‘template<class _Tp> void cv::cv2eigen(const cv::Mat&, int)’
void cv2eigen( const Mat& src,
^~~~~~~~
/usr/local/<blah_blah>/include/opencv4/opencv2/core/eigen.hpp:141:6: note: ‘template<class _Tp> void cv::cv2eigen(const cv::Mat&, int)’ previously declared here
void cv2eigen( const Mat& src,
^~~~~~~~
/usr/local/<blah_blah>/include/opencv4/opencv2/core/eigen.hpp:259:16: error: ‘Eigen’ has not been declared
Eigen::Matrix<_Tp, 1, Eigen::Dynamic>& dst )
^~~~~
/usr/local/<blah_blah>/include/opencv4/opencv2/core/eigen.hpp:259:29: error: expected ‘,’ or ‘...’ before ‘<’ token
Eigen::Matrix<_Tp, 1, Eigen::Dynamic>& dst )
^
/usr/local/<blah_blah>/include/opencv4/opencv2/core/eigen.hpp: In function ‘void cv::cv2eigen(const cv::Matx<_Tp, 1, _cols>&, int)’:
.
.
.
/usr/local/<blah_blah>/include/opencv4/opencv2/core/eigen.hpp:262:23: error: ‘Eigen’ has not been declared
if( !(dst.Flags & Eigen::RowMajorBit) )
^~~~~
This is quite strange, right? Because I'm getting errors for the OpenCV
functions that I'm not even touching.
So, how can I fix this weird issue?
P.S.
- I'm using
OpenCV 4.2.0
- I've modified some explicit paths with
<string>
CodePudding user response:
Actually, I found the root cause:
As per opencv/modules/core/include/opencv2/core/eigen.hpp
on 4.x
branch, line 78 & 79:
@note Using these functions requires the
Eigen/Dense
or similar header to be included before this header.
So, surprisingly enough, all I had to do was change the #include
order
from
#include <opencv2/core.hpp>
#include <opencv2/core/eigen.hpp>
#include <Eigen/Core>
to
#include <opencv2/core.hpp>
#include <Eigen/Core>
#include <opencv2/core/eigen.hpp>
On the other hand, I checked the existing /usr/local/<blah_blah>/include/opencv4/opencv2/core/eigen.hpp
file (OpenCV 4.2.0
) on my machine that, sadly, does not say anything about the #include
order!
¯\_(ツ)_/¯