难以编写多级循环

时间:2017-11-04 23:07:07

标签: c++ arrays for-loop

我有一个单独的暗淡数组,其中包含存储在其中的图像的像素。我正在尝试将其作为二维数组打印到文件中。

每个图像为28 * 28像素,阵列中包含60000个像素。

我输出单个图像的数学没有问题:

void makeImage(const std::string& filename,const char * insertion, const unsigned int& width, const unsigned int & height)
{
    int i = 0;
    FILE *fp = fopen(filename.c_str(), "wb"); /* b - binary mode */
    (void)fprintf(fp, "P6\n%d %d\n255\n", width, height);
    for (int x = 0; x < width; ++x)
    {
        for (int y = 0; y < height; ++y)
        {
            static unsigned char color[3];
            color[0] = *(insertion + i);  /* red */
            color[1] = *(insertion + i);  /* green */
            color[2] = *(insertion + i);  /* blue */
            (void)fwrite(color, 1, 3, fp);
            i++;
        }
    }
    (void)fclose(fp);
}

所以,如果我在哪做:

makeimage("myfile.ppm",&myarray[0],28,28); //First image.
makeimage("myfile2.ppm",&myarray[785],28,28); //Second image. ext.

但是我喜欢把所有60000张图片合二为一。作为6860x6860像素的图像。

但这样做的数学让我很头疼。

2 个答案:

答案 0 :(得分:2)

您无法将这些图像精确地放入60000图像正方形中,但您可以使用例如600行和100列的网格。 (生成的图像为16800 x 2800.)

我确信你可以处理C ++实现,所以这里是数学:

您有一系列图片:

| ---- ---- IM1 || ---- ---- IM2 | .... | ---- ---- im60000 |

您想要获得合成图像:

| ---- ---- IM1 || ---- ---- IM2 | .... | ---- ---- im600 |

| --- --- im601 || --- --- im602 | .... | --- im1200 ---- |

...

| --im59401-- || --im59402-- | .... | --im60000-- |

这是一些可以做到这一点的伪代码。

for a in 600
  for b in 28
    for c in 100
      for d in 28
        result[100*28*(28*a + b) + 28*c + d] = arr[28*28*(100*a + c) + 28*b + d]

这里,结果是你的大输出图像,而arr是你的巨型输入数组。

基本上,第一个和第三个循环负责处理图像的位置,第二个和第四个循环处理当前图像中当前像素的位置。

它不是很漂亮,但它有效。 我想你必须考虑颜色,但我假设你正在解析MNIST数据(60000 28x28手写数字图像),我相信它是灰度的。

祝你的项目好运。

答案 1 :(得分:0)

由于您要输出6860行6860点,并按顺序访问文件,首先要确定单行的形成方式:

  1. 在一行中,有6860个点或列。
  2. 第一行的前28个点来自第一个图像,接下来的28个来自第二个,依此类推。
  3. 第29行的前28个点来自第246个图像,依此类推。
  4. 在c / c ++中粗略地表达:

    int image_index = (y / 28 * 245) + (x / 245);
    int source_y = y % 28;
    int source_x = x % 28;
    int source_index = image_index * 28 * 28 + source_y * 28 + source_x;