vectorxf vectorxd tutorial c++ opencv eigen eigen3

c++ - vectorxd - cv:: conversión Mat a Eigen-Matrix y viceversa



vectorxd size (3)

Eche un vistazo a la asignación de datos de Eigen a OpenCV y el artículo de atrás . Describe cómo mapear datos con menos sobrecarga. En el caso más simple, no habría ninguna copia. También trata con expresiones Eigen también:

// 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));

Tengo varios vectores de características almacenados en un cv::Mat donde cada fila es un vector de características (varias filas como esta aquí: [ x1 y1 x2 y2 x3 y3.... ] ). Tengo que aplicar SVD en cada vector de característica y para eso uso la biblioteca Eigen. Pero, antes de aplicar SVD, la matriz de características debe convertirse a la forma Eigen::Matrix .

Más tarde, tengo que convertir el resultado SVD a cv::Mat .

¿Alguien podría sugerir una buena manera de hacer esto? La razón por la que lo necesito en formato cv::Mat es porque tengo que ingresarlo a una red neuronal en OpenCV y solo se permiten las matrices de entradas cv::Mat .

¡¡¡Gracias!!!


Pruebe este código para eigen a 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); } }

Como puede ver, esto realiza una copia. Con una matriz tan pequeña, no debería importarle, pero podría cambiar el código. para obtener la primera columna, use cv::Mat::column() .

Pruebe uno de estos métodos para cv a 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()); } }

Fuente: Este código está tomado de OpenCV, lo usan internamente ya que OpenCV puede usar libeigen para algunas tareas internamente. No entiendo por qué las conversiones de formato a tales libs y Qt no están expuestas a través de la API.