我正在使用C ++提取MNIST数据集,并使用它将其输出到控制台。

// show a random character
int ind;
/* initialize random seed: */
srand(time(NULL));

/* generate secret number: */
ind = rand() % number_of_images;

cout << "" << endl;
cout << "Opening a  example: " << endl;
cout << +labels[ind] << endl;
cout << "" << endl;


// 28 rows
for (int i = 0; i < 28; i++)
{
    // 28 cols
    for (int j = 0; j < 28; j++)
    {
        if (dataset[ind][i * 28 + j] > 80)
        {
            cout << 1;
            SetPixel();
        }
        else
        {
            cout << 0;
        }
    }
    cout << "" << endl;
}
system("pause");


我尝试使用各种方法来创建它,但是它们都太复杂了。我只需要包含一个函数或方法即可将一个像素写入文件,其中I和J表示坐标,而(如果是数据集)则表示白色像素或黑色像素。谁能帮帮我吗?

最佳答案

文件train-images.idx3-ubyte似乎在开始时具有16字节的头数据,然后对于每个28x28像素的图像来说为784字节。

如果要制作PNG文件,最简单的方法是按照here所述编写NetPBM便携式灰度图(PGM)文件,然后让ImageMagick或Irfanview或Photoshop将生成的PGM文件转换为PNG。

因此,您的程序只需要在开始时就输出PGM标头,如下所示:

P5
28 28
255


然后是您当前正在写入控制台的768字节图像,然后将其另存为SomeFile.pgm。然后,您可以使用ImageMagick将其中之一转换为PNG

magick SomeFile.pgm -negate SomeFile.png


或者,您可以将充满PGM个文件的整个目录转换为它们相应的PNG文件,仍然使用ImageMagick但这次使用其mogrify工具:

magick mogrify -format PNG -negate *.pgm


如果您可以使用Linux或其他类似的(非Windows)系统,则可以像这样完全提取它们,而无需编写任何C:

#!/bin/bash

# Remove the 16 byte header
dd if=train-images.idx3-ubyte bs=16 iseek=1 > nohead

# Extract all 10,000 images to PNG
for ((i=0;i<10000;i++)) ; do
   echo $i
   { printf "P5\n28 28\n255\n"; dd if=nohead bs=784 iseek=$i count=1 2>/dev/null ; } | magick pgm:- -negate $i.png
done

关于c++ - 在MVC C++中从1个字节的控制台输出镜像创建PNG文件,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48566913/

10-11 22:36
查看更多