如何将图像数据的多维向量写入输出文件?

How can one write a multi-dimensional vector of image data to an output file?

提问人:trent 提问时间:11/1/2022 更新时间:11/1/2022 访问量:110

问:

问题:

有没有一种好方法可以将大小为 (9000,9000,4) 的 3D 浮点向量写入 C++ 中的输出文件?

我的 C++ 程序生成一个 9000x9000 的图像矩阵,每个像素有 4 个颜色值(R、G、B、A)。我需要将此数据保存为输出文件,以便稍后使用 python 将其读入 numpy.array()(或类似文件)。每个颜色值都保存为浮点数(可以大于 1.0),该浮点数将在代码的 python 部分进行规范化。

目前,我正在将 (9000,9000,4) 大小的向量写入一个包含 8100 万行和 4 列的 CSV 文件。这对于读取和写入来说很慢,并且会创建大文件 (~650MB)。

NOTE: I run the program multiple times (up to 20) for each trial, so read/write times and file sizes add up.

当前 C++ 代码:

这是初始化和写入 3D 向量的代码段。

// initializes the vector with data from 'makematrix' class instance
vector<vector<vector<float>>> colorMat = makematrix->getMatrix();

outfile.open("../output/11_14MidRed9k8.csv",std::ios::out);

if (outfile.is_open()) {
    outfile << "r,g,b,a\n"; // writes column labels

    for (unsigned int l=0; l<colorMat.size(); l++) { // 0 to 8999
        for (unsigned int m=0; m<colorMat[0].size(); m++) { // 0 to 8999
            outfile << colorMat[l][m][0] << ',' << colorMat[l][m][1] << ','
                << colorMat[l][m][2] << ',' << colorMat[l][m][3] << '\n';
        }
    }
}

outfile.close();

总结:

我愿意更改输出文件类型、我使用的数据结构或任何其他可以提高效率的东西。欢迎任何和所有建议!

C++ CSV 多维数组 文件-IO IOstream

评论

2赞 Amadan 11/1/2022
libnpycnpy 这样的东西?
0赞 Mickaël C. Guimarães 11/1/2022
您存储的相当于两张 8K 图像,无需压缩。无论如何,这将是一件大事

答:

1赞 Mickaël C. Guimarães 11/1/2022 #1

使用旧的 C 文件函数和二进制格式

    auto startT = chrono::high_resolution_clock::now();

ofstream outfile;

FILE* f = fopen("example.bin", "wb");

if (f) {
    const int imgWidth = 9000;
    const int imgHeight = 9000;
    fwrite(&imgWidth, sizeof(imgWidth), 1, f);
    fwrite(&imgHeight, sizeof(imgHeight), 1, f);

    for (unsigned int i=0; i<colorMat.size(); ++i)
    {
        fwrite(&colorMat[i], sizeof(struct Pixel), 1, f);
    }
}

auto endT = chrono::high_resolution_clock::now();
cout << "Time taken : " << chrono::duration_cast<chrono::seconds>(endT-startT).count() << endl;

fclose(f);

格式如下:

[图像宽度][图像高度][RGBA][RGBA[RGBA]...对于所有 ImageWidth * ImageHeight 像素。

您的样品在我的机器中运行了 119 秒。此代码在 2 秒内运行。

但请注意,无论如何,该文件都会很大:您正在编写相当于两个 8K 文件的文件,而无需任何压缩

除此之外,关于代码的一些提示:

  • 不要使用浮点数的向量来表示像素。它们的组件不会比 RGBA 多。相反,创建一个包含四个浮点数的简单结构。
  • 您无需分别查看宽度和高度。在内部,所有行都是按顺序排列的。创建宽度 * 高度大小的一维数组更容易。

评论

0赞 trent 11/2/2022
感谢您的帮助!我玩过你的代码,现在它在不到十分之一秒的时间内运行。