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

Python保存numpy数组供C++加载为OpenCV Mat/Eigen矩阵方法

NPY文件跨语言加载方案

针对你用numpy.save生成的float32类型、形状为[10000,18,5]的npy文件,不需要修改Python侧的保存逻辑,C++侧可以非常简便地加载到OpenCV Mat、Eigen矩阵结构中,没有额外重型依赖。

核心原理

npy是numpy的原生存储格式,结构非常简单,除了很短的文件头存储数据类型、维度、存储顺序信息外,后续就是和numpy内存布局完全一致的连续二进制块,你存储的float32类型和C++的float类型位宽完全匹配,不需要做数值转换,加载开销和读裸二进制文件几乎一致。

npy文件结构如下:

  1. 前6字节为固定魔数:\x93NUMPY
  2. 接下来2字节为格式版本号
  3. 接下来2或4字节为文件头长度
  4. 接下来是ASCII编码的字典字符串,记录数据类型descr、存储顺序fortran_order、维度shape
  5. 文件头之后是连续的原始数组数据

你可以自己写100行以内的代码完成解析,不需要依赖第三方库。

加载到目标结构的方法

解析拿到原始数据的指针、维度、存储顺序后,直接映射到对应矩阵结构即可,注意numpy默认是C序(行优先)存储,和OpenCV默认布局一致,和Eigen默认的列优先布局不同,映射时需要指定行优先参数。

  • 加载到OpenCV Mat
// 假设解析后得到:float* data_ptr 指向原始数据起始位置,shape为维度数组
std::vector<int> shape = {10000, 18, 5};
// 直接构造Mat,默认共享解析得到的内存
cv::Mat mat(shape.size(), shape.data(), CV_32F, (void*)data_ptr);
// 需要Mat持有独立内存时调用clone,即可释放原始加载的缓冲区
cv::Mat mat_owned = mat.clone();
  • 加载到Eigen结构
    如果是二维矩阵场景,可以把三维数组reshape为二维使用;如果需要保留三维结构,可以用Eigen的Tensor模块:
// 二维映射:将数据reshape为10000行、18*5=90列的行优先矩阵
Eigen::Map<Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>>
    mat2d_map((float*)data_ptr, 10000, 90);
// 拷贝得到独立持有的Eigen矩阵
Eigen::MatrixXf eigen_mat = mat2d_map;

// 三维映射:使用Eigen::Tensor保留原始维度
Eigen::TensorMap<Eigen::Tensor<float, 3, Eigen::RowMajor>>
    tensor3d_map((float*)data_ptr, 10000, 18, 5);
// 拷贝得到独立持有的Eigen Tensor
Eigen::Tensor<float, 3, Eigen::RowMajor> eigen_tensor = tensor3d_map;

注意事项

  • 不要忽略存储顺序参数:如果Eigen映射时不指定Eigen::RowMajor,读出来的数据会完全错位。
  • 严格匹配数据类型:numpy的float32对应C++的float,不要误用double,否则会出现数值错乱。
  • 不需要转存CSV、JSON等文本格式,这类格式加载速度比二进制慢10~100倍,还会存在浮点数精度损失。
  • 如果不需要压缩,直接用numpy.save存npy即可,比numpy.savez压缩包少了解压步骤,加载速度更快。

内容的提问来源于stack exchange,提问作者mcExchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 00:42:22