如何在不分配内存的情况下将 opencv 映射到具有对齐支持的特征?
How to map opencv to eigen with alignment support without allocate the memory?
我使用 opencv 从一些数据集中读取大数据(28*28 行,200000 列)并希望将其映射到具有对齐支持的特征矩阵而不分配另一个大缓冲区。
cv::Mat big_data(28*28, 200000, CV_64F);
//...read data and preprocess
EMatrix map_big_data;
//cv2Eigen will allocate a new, big buffer
cv::cv2Eigen(big_data, map_big_data);
是否可以在不分配另一个大内存的情况下映射矩阵?可以调整 cv::Mat 的大小,我想避免同时存在两个大缓冲区(可能会抛出 bad_alloc )
cv::Mat big_data(28*28, 200000, CV_64F);
//read data and preprocess....
using EMatrix = Eigen::Matrix<double, Eigen::Dynamic,
Eigen::Dynamic, Eigen::RowMajor>;
using EMap = Eigen::Map<EMatrix, Eigen::Aligned>;
//resize the cv::Mat to meet the alignment requirement(16bytes aligned),is this possible?How could I get the align_cols?
big_data.resize(big_data.rows, align_cols);
//this may or may not crash
EMap map_big_data(reinterpret_cast<double*>(big_data.data),
big_data.rows,
big_data.cols);
编辑:使用Eigen::aligned_allocator分配对齐内存
Eigen::aligned_allocator<double> alloc;
int const Rows = 28*28;
int const Cols = 200000;
auto buffer = alloc.allocate(Rows*Cols);
cv::Mat big_data(Rows, Cols, CV_64F, buffer, Cols * sizeof(double));
//read data set and do some preprocess....
using EMatrix = Eigen::Matrix<double, Eigen::Dynamic,
Eigen::Dynamic, Eigen::RowMajor>;
using EMap = Eigen::Map<EMatrix, Eigen::Aligned>;
EMap map_big_data(reinterpret_cast<double*>(big_data.data),
big_data.rows,
big_data.cols);
//some jobs.....
alloc.deallocate(buffer, 0);
这样可以吗?
为什么要直接使用 Eigen 分配器?使用 Eigen::MatrixXd (或类似的),并将指向数据的指针传递给 cvMat 构造函数。以这种方式使用,cvMat "wraps" 数据无需复制(与 Eigen::Map 相同)。
int Rows = 28*28;
int Cols = 200000;
Eigen::Matrix<double, Eigen::Dynamic,
Eigen::Dynamic, Eigen::RowMajor> eigenMat(Rows, Cols);
cv::Mat big_data(Rows, Cols, CV_64F, eigenMat.data(), Cols * sizeof(double));
//read data set and do some preprocess....
您唯一不应该做的就是尝试调整大小 big_data
,而是 eigenMat
如有必要。
来自 OpenCV documentation:
data
Pointer to the user data. Matrix constructors that take data and step parameters do not allocate matrix data. Instead, they just initialize the matrix header that points to the specified data, which means that no data is copied. This operation is very efficient and can be used to process external data using OpenCV functions. The external data is not automatically deallocated, so you should take care of it.
这样就没有映射,没有试图确定是否有额外的填充,也不需要记住释放。所有这一切同时仍然获得本征矩阵的所有优势。
我使用 opencv 从一些数据集中读取大数据(28*28 行,200000 列)并希望将其映射到具有对齐支持的特征矩阵而不分配另一个大缓冲区。
cv::Mat big_data(28*28, 200000, CV_64F);
//...read data and preprocess
EMatrix map_big_data;
//cv2Eigen will allocate a new, big buffer
cv::cv2Eigen(big_data, map_big_data);
是否可以在不分配另一个大内存的情况下映射矩阵?可以调整 cv::Mat 的大小,我想避免同时存在两个大缓冲区(可能会抛出 bad_alloc )
cv::Mat big_data(28*28, 200000, CV_64F);
//read data and preprocess....
using EMatrix = Eigen::Matrix<double, Eigen::Dynamic,
Eigen::Dynamic, Eigen::RowMajor>;
using EMap = Eigen::Map<EMatrix, Eigen::Aligned>;
//resize the cv::Mat to meet the alignment requirement(16bytes aligned),is this possible?How could I get the align_cols?
big_data.resize(big_data.rows, align_cols);
//this may or may not crash
EMap map_big_data(reinterpret_cast<double*>(big_data.data),
big_data.rows,
big_data.cols);
编辑:使用Eigen::aligned_allocator分配对齐内存
Eigen::aligned_allocator<double> alloc;
int const Rows = 28*28;
int const Cols = 200000;
auto buffer = alloc.allocate(Rows*Cols);
cv::Mat big_data(Rows, Cols, CV_64F, buffer, Cols * sizeof(double));
//read data set and do some preprocess....
using EMatrix = Eigen::Matrix<double, Eigen::Dynamic,
Eigen::Dynamic, Eigen::RowMajor>;
using EMap = Eigen::Map<EMatrix, Eigen::Aligned>;
EMap map_big_data(reinterpret_cast<double*>(big_data.data),
big_data.rows,
big_data.cols);
//some jobs.....
alloc.deallocate(buffer, 0);
这样可以吗?
为什么要直接使用 Eigen 分配器?使用 Eigen::MatrixXd (或类似的),并将指向数据的指针传递给 cvMat 构造函数。以这种方式使用,cvMat "wraps" 数据无需复制(与 Eigen::Map 相同)。
int Rows = 28*28;
int Cols = 200000;
Eigen::Matrix<double, Eigen::Dynamic,
Eigen::Dynamic, Eigen::RowMajor> eigenMat(Rows, Cols);
cv::Mat big_data(Rows, Cols, CV_64F, eigenMat.data(), Cols * sizeof(double));
//read data set and do some preprocess....
您唯一不应该做的就是尝试调整大小 big_data
,而是 eigenMat
如有必要。
来自 OpenCV documentation:
data
Pointer to the user data. Matrix constructors that take data and step parameters do not allocate matrix data. Instead, they just initialize the matrix header that points to the specified data, which means that no data is copied. This operation is very efficient and can be used to process external data using OpenCV functions. The external data is not automatically deallocated, so you should take care of it.
这样就没有映射,没有试图确定是否有额外的填充,也不需要记住释放。所有这一切同时仍然获得本征矩阵的所有优势。