提问人:trent 提问时间:11/1/2022 更新时间:11/1/2022 访问量:110
如何将图像数据的多维向量写入输出文件?
How can one write a multi-dimensional vector of image data to an output file?
问:
问题:
有没有一种好方法可以将大小为 (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();
总结:
我愿意更改输出文件类型、我使用的数据结构或任何其他可以提高效率的东西。欢迎任何和所有建议!
答:
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
感谢您的帮助!我玩过你的代码,现在它在不到十分之一秒的时间内运行。
评论