简体   繁体   English

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

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

I've created some data in numpy that I would like to use in a separate C++ program.我在 numpy 中创建了一些我想在单独的 C++ 程序中使用的数据。 Therefore I need to save the data using python and later load it in C++.因此我需要使用 python 保存数据,然后在 C++ 中加载它。 What is the best way of doing this?这样做的最佳方法是什么?

My numpy ndarray is float 32 and of shape [10000 x 18 x 5].我的 numpy ndarray 是 float 32,形状为 [10000 x 18 x 5]。 I can save it for example using我可以保存它,例如使用

numpy.save(filename, data)

Is there an easy way to load such data in C++?有没有一种简单的方法可以在 C++ 中加载此类数据? Target structure could be an Eigen::Matrix for example.例如,目标结构可以是Eigen::Matrix

After searching for hours I found my year-old example files.在搜索了几个小时后,我找到了我一年前的示例文件。

Caveat:警告:

  • solution only covers 2D matrices解决方案仅涵盖二维矩阵
  • not suited for 3 dimensional or generic ndarrays不适合 3 维或通用 ndarray

Write numpy array to ascii file with header specifying nrows, ncols:将 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")

Example output data-file.txt looks like this (first row is header specifying nrows and ncols):示例输出 data-file.txt 如下所示(第一行是指定 nrows 和 ncols 的标题):

2 3
1.0 2.0 3.0
4.0 5.0 6.0

Cpp function to read matrix from ascii file into OpenCV matrix:将 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();

}

Driver code to use above mentioned function in cpp program:在 cpp 程序中使用上述功能的驱动程序代码:

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

For completeness, some code to save the data using C++:为了完整起见,一些使用 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;
}

Future work:未来的工作:

  • solution for 3D matrices 3D 矩阵的解决方案
  • conversion to Eigen::Matrix转换为 Eigen::Matrix

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

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