OpenCV BGR三通道Mat转Eigen 3D Tensor报错求助
解决OpenCV三通道Mat转Eigen 3D Tensor的问题
你遇到的错误根源在于 cv::cv2eigen 并不支持直接将多通道的OpenCV Mat转换为Eigen的二维Matrix。OpenCV的彩色图是3通道交错存储(BGRBGR...)的结构,而Eigen的MatrixXd是严格的二维矩阵,两者的维度和存储逻辑不匹配,因此触发了断言失败。
下面是两种可行的解决方案,直接跳过cv2eigen的中间步骤,从Mat的内存直接映射到Eigen Tensor:
方案1:直接映射为(行, 列, 通道)维度的Tensor
这个方案保持和OpenCV一致的内存布局(行优先,每个像素的BGR值连续存储),适合不需要调整通道顺序的场景:
#include <opencv2/opencv.hpp> #include <Eigen/Dense> #include <Eigen/Tensor> int main() { // 1. 读入彩色图像(默认是CV_8UC3类型) cv::Mat mat = cv::imread("/image/path.png", cv::IMREAD_COLOR); if (mat.empty()) { std::cerr << "Failed to read image!" << std::endl; return -1; } // 2. 将图像转换为64位浮点型(匹配Eigen Tensor的double类型) cv::Mat mat_double; mat.convertTo(mat_double, CV_64FC3); // 3. 确保Mat内存是连续的(imread默认返回连续内存,ROI操作后可能不连续) CV_Assert(mat_double.isContinuous()); // 4. 直接映射到Eigen Tensor,维度为(rows, cols, channels),行优先存储 Eigen::TensorMap<Eigen::Tensor<double, 3, Eigen::RowMajor>> myTensor( mat_double.data(), mat_double.rows, mat_double.cols, 3 ); // 验证:输出第一个像素的BGR值 std::cout << "First pixel B: " << myTensor(0, 0, 0) << ", G: " << myTensor(0, 0, 1) << ", R: " << myTensor(0, 0, 2) << std::endl; return 0; }
方案2:转换为(通道, 行, 列)维度的Tensor
如果你的Tensor需要通道优先的布局(比如深度学习中常见的CHW格式),可以通过shuffle操作调整维度顺序:
// 接上面的步骤3 Eigen::TensorMap<Eigen::Tensor<double, 3, Eigen::RowMajor>> temp_tensor( mat_double.data(), mat_double.rows, mat_double.cols, 3 ); // 重新排列维度:将原维度(rows, cols, channels)转为(channels, rows, cols) Eigen::array<int, 3> shuffle_dims = {2, 0, 1}; Eigen::Tensor<double, 3> myTensor = temp_tensor.shuffle(shuffle_dims); // 验证:输出第一个通道(B通道)的第一个像素值 std::cout << "B channel first pixel: " << myTensor(0, 0, 0) << std::endl;
关键注意点
- 类型匹配:OpenCV默认读入的是8位无符号整数(
CV_8UC3),必须先转换为CV_64FC3才能映射到double类型的Eigen Tensor。 - 内存连续性:只有连续的Mat内存才能直接用
TensorMap映射,非连续内存可以通过mat_double = mat_double.clone()强制转为连续。 - 通道顺序:OpenCV读入的是BGR顺序,如果需要RGB,可以在转换前用
cv::cvtColor(mat, mat, cv::COLOR_BGR2RGB)调整。
内容的提问来源于stack exchange,提问作者Gal Sight
相关产品推荐
相关产品推荐

