繁体   English   中英

用 python 保存数据(矩阵或 ndarray),然后在 c++ 中加载(作为 OpenCV Mat)

[英]save data (matrix or ndarray) with python then it load in c++ (as OpenCV Mat)

我在 numpy 中创建了一些我想在单独的 C++ 程序中使用的数据。 因此我需要使用 python 保存数据,然后在 C++ 中加载它。 这样做的最佳方法是什么?

我的 numpy ndarray 是 float 32,形状为 [10000 x 18 x 5]。 我可以保存它,例如使用

numpy.save(filename, data)

有没有一种简单的方法可以在 C++ 中加载此类数据? 例如,目标结构可以是Eigen::Matrix

在搜索了几个小时后,我找到了我一年前的示例文件。

警告:

  • 解决方案仅涵盖二维矩阵
  • 不适合 3 维或通用 ndarray

将 numpy 数组写入 ascii 文件,标头指定 nrows、ncols:

def write_matrix2D_to_ascii(filename, matrix2D):
    
    nrows, ncols = matrix2D.shape
    
    with open(filename, "w") as file:
        
        # write header [rows x cols]
        nrows, ncols = matrix2D.shape
        file.write(f"{nrows} {ncols}")
        file.write("\n")
        
        # write values 
        for row in range(nrows):
            for col in range(ncols):
                value = matrix2D[row, col]

                file.write(str(value))
                file.write(" ")
            file.write("\n")

示例输出 data-file.txt 如下所示(第一行是指定 nrows 和 ncols 的标题):

2 3
1.0 2.0 3.0
4.0 5.0 6.0

将 ascii 文件中的矩阵读取到 OpenCV 矩阵中的 Cpp 函数:

#include <iostream>
#include <fstream>
#include <iomanip> // set precision of output string

#include <opencv2/core/core.hpp> // OpenCV matrices for storing data

using namespace std;
using namespace cv;

void readMatAsciiWithHeader( const string& filename, Mat& matData)
{
    cout << "Create matrix from file :" << filename << endl;

    ifstream inFileStream(filename.c_str());
    if(!inFileStream){
        cout << "File cannot be found" << endl;
        exit(-1);
    }

    int rows, cols;
    inFileStream >> rows;
    inFileStream >> cols;
    matData.create(rows,cols,CV_32F);
    cout << "numRows: " << rows << "\t numCols: " << cols << endl;

    matData.setTo(0);  // init all values to 0
    float *dptr;
    for(int ridx=0; ridx < matData.rows; ++ridx){
        dptr = matData.ptr<float>(ridx);
        for(int cidx=0; cidx < matData.cols; ++cidx, ++dptr){
            inFileStream >> *dptr;
        }
    }
    inFileStream.close();

}

在 cpp 程序中使用上述功能的驱动程序代码:

Mat myMatrix;
readMatAsciiWithHeader("path/to/data-file.txt", myMatrix);

为了完整起见,一些使用 C++ 保存数据的代码:

int saveMatAsciiWithHeader( const string& filename, Mat& matData)
{
    if (matData.empty()){
       cout << "File could not be saved. MatData is empty" << endl;
       return 0;
    }
    ofstream oStream(filename.c_str());

    // Create header
    oStream << matData.rows << " " << matData.cols << endl;
    
    // Write data
    for(int ridx=0; ridx < matData.rows; ridx++)
    {
        for(int cidx=0; cidx < matData.cols; cidx++)
        {
            oStream << setprecision(9) << matData.at<float>(ridx,cidx) << " ";
        }
        oStream << endl;
    }
    oStream.close();
    cout << "Saved " << filename.c_str() << endl;

    return 1;
}

未来的工作:

  • 3D 矩阵的解决方案
  • 转换为 Eigen::Matrix

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM