Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Eigen::RowMajor cv2eigen assertion failed (+ naive fix) #16606

@spacescientist

Description

@spacescientist
  • OpenCV => 4.2.0-dev
  • Operating System / Platform => Debian 10 x86_64 GNU/Linux (4.19.0-6-amd64)
  • Compiler => g++ 8.3.0
Detailed description

cv::cv2eigen doesn't work as I expected if the Eigen::Matrix is of type:
Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>.

I came up with a naive fix, but as I am relatively new to both OpenCV and Eigen (and especially at interfacing them), I thought I'd first open an issue and request a sanity check before going for a pull request. It seems entirely possible that I missed something obvious.

Steps to reproduce
cv::Mat_<double> image = cv::imread("../Lena.png", cv::IMREAD_GRAYSCALE);

Eigen::Matrix<double,Eigen::Dynamic, Eigen::Dynamic> A;
cv::cv2eigen(image, A); // Works as expected.

Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> B;
cv::cv2eigen(image, B); // Expected to work, but doesn't with the current opencv-master.

More precisely, it will compile, and then give at run time:

terminate called after throwing an instance of 'cv::Exception'
  what():  OpenCV(4.2.0-dev)  /usr/local/include/opencv4/opencv2/core/mat.inl.hpp:548: error: (-215:Assertion failed) total() == 0 || data != NULL in function 'Mat'

Aborted
Naive fix:

I made a copy of an existing function in eigen.hpp (line 140 of that file), simply adding Eigen::RowMajor so that the argument now reads Eigen::Matrix<_Tp, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>& dst. The body of the function is the same.

// What I've added in eigen.hpp; seems to solve the problem
template<typename _Tp>  static inline
void cv2eigen( const Mat& src,
               Eigen::Matrix<_Tp, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>& dst )
{
    dst.resize(src.rows, src.cols);
    if( !(dst.Flags & Eigen::RowMajorBit) )
    {
        const Mat _dst(src.cols, src.rows, traits::Type<_Tp>::value,
             dst.data(), (size_t)(dst.outerStride()*sizeof(_Tp)));
        if( src.type() == _dst.type() )
            transpose(src, _dst);
        else if( src.cols == src.rows )
        {
            src.convertTo(_dst, _dst.type());
            transpose(_dst, _dst);
        }
        else
            Mat(src.t()).convertTo(_dst, _dst.type());
    }
    else
    {
        const Mat _dst(src.rows, src.cols, traits::Type<_Tp>::value,
                 dst.data(), (size_t)(dst.outerStride()*sizeof(_Tp)));
        src.convertTo(_dst, _dst.type());
    }
}

Once that fct is defined inside the cv namespace, the programme compiles and runs, seemingly without issues.

cv::cv2eigen(image, B); // Works with B.
cv::cv2eigen(image, A); // Works with A.

// Everything's fine
H5Easy::File output_hdf("out.hdf", H5Easy::File::Overwrite);
H5Easy::dump(output_hdf, "/A", A);
H5Easy::dump(output_hdf, "/B", B);

Cheers.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions