cv :: Mat преобразование в Eigen-Matrix и обратно

У меня есть несколько векторов объектов, хранящихся в cv::Mat где каждая строка является вектором объектов (здесь несколько строк, подобных этой: [ x1 y1 x2 y2 x3 y3.... ]). Я должен применить SVD к каждому вектору признаков, и для этого я использую библиотеку Eigen. Но перед применением SVD матрицу объектов необходимо преобразовать в Eigen::Matrix форма.

Позже я должен преобразовать результат SVD обратно в cv::Mat,

Может ли кто-нибудь предложить хороший способ сделать это? Причина, по которой мне это нужно cv::Mat форма, потому что я должен ввести его в нейронную сеть в OpenCV и только cv::Mat входные матрицы разрешены.

Спасибо!!!

2

Решение

Пример из http://forum.kde.org/viewtopic.php?f=74&т = 97516:

#include <opencv2/core/eigen.hpp>
cv::Mat_<float> a = Mat_<float>::ones(2,2);
Eigen::Matrix<float,Dynamic,Dynamic> b;
cv2eigen(a,b);

Также, OpenCV CV :: Mat and Eigen :: Matrix имеет решение, использующее Eigen :: Map.

5

Другие решения

Попробуйте этот код для eigen to cv:

template<typename _Tp, int _rows, int _cols, int _options, int _maxRows, int _maxCols>
void eigen2cv(const Eigen::Matrix<_Tp, _rows, _cols, _options, _maxRows, _maxCols>& src, cv::Mat& dst)
{
if (!(src.Flags & Eigen::RowMajorBit))
{
cv::Mat _src(src.cols(), src.rows(), cv::DataType<_Tp>::type,
(void*)src.data(), src.stride() * sizeof(_Tp));
cv::transpose(_src, dst);
}
else
{
cv::Mat _src(src.rows(), src.cols(), cv::DataType<_Tp>::type,
(void*)src.data(), src.stride() * sizeof(_Tp));
_src.copyTo(dst);
}
}

Как вы можете видеть это выполняет копию. С такой маленькой матрицей вам все равно, но вы можете изменить код. чтобы получить первый столбец, используйте cv::Mat::column(),

Попробуйте один из этих методов для cv to eigen:

template<typename _Tp, int _rows, int _cols, int _options, int _maxRows, int _maxCols>
void cv2eigen( const Mat& src,
Eigen::Matrix<_Tp, _rows, _cols, _options, _maxRows, _maxCols>& dst )
{
CV_DbgAssert(src.rows == _rows && src.cols == _cols);
if( !(dst.Flags & Eigen::RowMajorBit) )
{
Mat _dst(src.cols, src.rows, DataType<_Tp>::type,
dst.data(), (size_t)(dst.stride()*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());
CV_DbgAssert(_dst.data == (uchar*)dst.data());
}
else
{
Mat _dst(src.rows, src.cols, DataType<_Tp>::type,
dst.data(), (size_t)(dst.stride()*sizeof(_Tp)));
src.convertTo(_dst, _dst.type());
CV_DbgAssert(_dst.data == (uchar*)dst.data());
}
}

template<typename _Tp>
void cv2eigen( const Mat& src,
Eigen::Matrix<_Tp, Eigen::Dynamic, Eigen::Dynamic>& dst )
{
dst.resize(src.rows, src.cols);
if( !(dst.Flags & Eigen::RowMajorBit) )
{
Mat _dst(src.cols, src.rows, DataType<_Tp>::type,
dst.data(), (size_t)(dst.stride()*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());
CV_DbgAssert(_dst.data == (uchar*)dst.data());
}
else
{
Mat _dst(src.rows, src.cols, DataType<_Tp>::type,
dst.data(), (size_t)(dst.stride()*sizeof(_Tp)));
src.convertTo(_dst, _dst.type());
CV_DbgAssert(_dst.data == (uchar*)dst.data());
}
}template<typename _Tp>
void cv2eigen( const Mat& src,
Eigen::Matrix<_Tp, Eigen::Dynamic, 1>& dst )
{
CV_Assert(src.cols == 1);
dst.resize(src.rows);

if( !(dst.Flags & Eigen::RowMajorBit) )
{
Mat _dst(src.cols, src.rows, DataType<_Tp>::type,
dst.data(), (size_t)(dst.stride()*sizeof(_Tp)));
if( src.type() == _dst.type() )
transpose(src, _dst);
else
Mat(src.t()).convertTo(_dst, _dst.type());
CV_DbgAssert(_dst.data == (uchar*)dst.data());
}
else
{
Mat _dst(src.rows, src.cols, DataType<_Tp>::type,
dst.data(), (size_t)(dst.stride()*sizeof(_Tp)));
src.convertTo(_dst, _dst.type());
CV_DbgAssert(_dst.data == (uchar*)dst.data());
}
}template<typename _Tp>
void cv2eigen( const Mat& src,
Eigen::Matrix<_Tp, 1, Eigen::Dynamic>& dst )
{
CV_Assert(src.rows == 1);
dst.resize(src.cols);
if( !(dst.Flags & Eigen::RowMajorBit) )
{
Mat _dst(src.cols, src.rows, DataType<_Tp>::type,
dst.data(), (size_t)(dst.stride()*sizeof(_Tp)));
if( src.type() == _dst.type() )
transpose(src, _dst);
else
Mat(src.t()).convertTo(_dst, _dst.type());
CV_DbgAssert(_dst.data == (uchar*)dst.data());
}
else
{
Mat _dst(src.rows, src.cols, DataType<_Tp>::type,
dst.data(), (size_t)(dst.stride()*sizeof(_Tp)));
src.convertTo(_dst, _dst.type());
CV_DbgAssert(_dst.data == (uchar*)dst.data());
}
}

Источник: Этот код взят из самого OpenCV, они используют его внутри, так как OpenCV может использовать libeigen для некоторых задач внутри страны. Я не понимаю, почему преобразования формата для таких библиотек и Qt не предоставляются через API.

3

Посмотрите на Отображение данных из Eigen в OpenCV и обратно статья. Он описывает, как отображать данные с меньшими издержками. В простейшем случае не было бы копии вообще. Это также касается и собственных выражений:

// Unsharp mask
Eigen::ArrayXXd img, blur;
eigen2cv(img) = cv::imread("lena.jpg");
cv::GaussianBlur(eigen2cv(img), eigen2cv(blur));

cv::imshow("sharpened", eigen2cv(1.5 * img - 0.5 * blur));
1
По вопросам рекламы [email protected]