You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:13:19