-
-
Notifications
You must be signed in to change notification settings - Fork 56.4k
Description
- 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.