Search code examples
c++opencveigen

How can I use an Eigen::Map object for Eigen::EigenSolver?


I have an continous OpenCV (assymmetric) matrix cv::Mat m and I want to compute its eigenvector and eigenvalues through Eigen::EigenSolver.

Since m could be big, making a copy through cv2eigen function is inefficient. Then, I want to use the Eigen::Map. This is my code:

Eigen::Map<Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>> mMapped (m.ptr<float>(), m.rows, m.cols);
Eigen::EigenSolver<Eigen::Map<Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>>> solver(mMapped,true);//this gives a bunch of errors

The last line gives a bunch of errors (see the end of the question). How can I solve this? Notice that I should avoid to copy mMapped to a matrix object, otherwise it's equivalent to use cv2eigen (I think).

/usr/local/include/eigen3/Eigen/src/Eigenvalues/EigenSolver.h: In instantiation of ‘class Eigen::EigenSolver<Eigen::Map<Eigen::Matrix<float, -1, -1, 1> > >’:
../Math.hpp:64:104:   required from ‘static void Math::createHashTable(const cv::Mat&, cv::Mat&, cv::Mat&, int, int) [with T = float]’
../CloudCache.cpp:155:58:   required from here
/usr/local/include/eigen3/Eigen/src/Eigenvalues/EigenSolver.h:71:10: error: ‘Options’ is not a member of ‘Eigen::EigenSolver<Eigen::Map<Eigen::Matrix<float, -1, -1, 1> > >::MatrixType {aka Eigen::Map<Eigen::Matrix<float, -1, -1, 1> >}’
     enum {
          ^
In file included from /usr/local/include/eigen3/Eigen/Eigenvalues:29:0,
                 from ../Math.hpp:16,
                 from ../CloudCache.cpp:15:
/usr/local/include/eigen3/Eigen/src/Eigenvalues/RealSchur.h: In instantiation of ‘class Eigen::RealSchur<Eigen::Map<Eigen::Matrix<float, -1, -1, 1> > >’:
/usr/local/include/eigen3/Eigen/src/Eigenvalues/EigenSolver.h:312:27:   required from ‘class Eigen::EigenSolver<Eigen::Map<Eigen::Matrix<float, -1, -1, 1> > >’
../Math.hpp:64:104:   required from ‘static void Math::createHashTable(const cv::Mat&, cv::Mat&, cv::Mat&, int, int) [with T = float]’
../CloudCache.cpp:155:58:   required from here
/usr/local/include/eigen3/Eigen/src/Eigenvalues/RealSchur.h:58:10: error: ‘Options’ is not a member of ‘Eigen::RealSchur<Eigen::Map<Eigen::Matrix<float, -1, -1, 1> > >::MatrixType {aka Eigen::Map<Eigen::Matrix<float, -1, -1, 1> >}’
     enum {
          ^
In file included from /usr/local/include/eigen3/Eigen/src/Eigenvalues/RealSchur.h:14:0,
                 from /usr/local/include/eigen3/Eigen/Eigenvalues:29,
                 from ../Math.hpp:16,
                 from ../CloudCache.cpp:15:
/usr/local/include/eigen3/Eigen/src/Eigenvalues/HessenbergDecomposition.h: In instantiation of ‘class Eigen::HessenbergDecomposition<Eigen::Map<Eigen::Matrix<float, -1, -1, 1> > >’:
/usr/local/include/eigen3/Eigen/src/Eigenvalues/RealSchur.h:228:41:   required from ‘class Eigen::RealSchur<Eigen::Map<Eigen::Matrix<float, -1, -1, 1> > >’
/usr/local/include/eigen3/Eigen/src/Eigenvalues/EigenSolver.h:312:27:   required from ‘class Eigen::EigenSolver<Eigen::Map<Eigen::Matrix<float, -1, -1, 1> > >’
../Math.hpp:64:104:   required from ‘static void Math::createHashTable(const cv::Mat&, cv::Mat&, cv::Mat&, int, int) [with T = float]’
../CloudCache.cpp:155:58:   required from here
/usr/local/include/eigen3/Eigen/src/Eigenvalues/HessenbergDecomposition.h:64:10: error: ‘Options’ is not a member of ‘Eigen::HessenbergDecomposition<Eigen::Map<Eigen::Matrix<float, -1, -1, 1> > >::MatrixType {aka Eigen::Map<Eigen::Matrix<float, -1, -1, 1> >}’
     enum {
          ^
subdir.mk:30: recipe for target 'CloudCache.o' failed
make: *** [CloudCache.o] Error 1

Solution

  • You cannot declare an EigenSolver with a Map, the matrix type must be a Matrix, so in your case:

    typedef Matrix<float,Dynamic,Dynamic,RowMajor> RowMatrixXf;
    Map<RowMatrixXf> mMapped (m.ptr<float>(), m.rows, m.cols);
    EigenSolver<MatrixXf> eig(mMapped);
    

    You can also instantiate EigenSolver with RowMatrixXf but the performance should be lower, despite of the transposition.