C++ 难以编写多级for循环
我有一个单一的暗淡阵列,其中存储了图像的像素。我想把它打印成一个二维数组 每个图像是28*28像素,阵列包含60000个像素 我对输出单个图像的数学没有问题:C++ 难以编写多级for循环,c++,arrays,for-loop,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 = fop
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);
}
但是我想把60000张照片放在一张照片里。作为6860x6860像素的图像
但是数学计算让我头疼。你不能将这些图像精确地放入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的手写数字图像),我相信这是灰度的
祝您的项目好运。您不能将这些图像精确地放入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的手写数字图像),我相信这是灰度的
祝您的项目好运。因为您希望输出6860行6860点,并且您访问文件的方式是按顺序的,所以首先确定单行的形成方式:
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;
由于您希望输出6860行6860点,并且您访问文件的方式是按顺序进行的,因此首先确定单行的形成方式:
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;
请注意,
6860*6860=47059600
不等于28*28*60000=47040000
,这基本上意味着您无法准确地拟合所有图像,因为6860/28=245
和245*245=60025
还有25个图像。您想如何将60000个图像排列成一个大马赛克?因为你是逐个列这些图像,你已经把它们作为一个图像,28个像素高,1680000个像素宽。你需要使用另一个网格,像100×600个图像,即:2800×16800像素。BTW,C代码标记为C++。OT:在C++中使用IOFFROW。注意<代码> 6860×6860=47059600 < /C>不等于<代码> 28×28×60000=47040000 < /COD>这意味着你不能完全匹配你的所有图像,因为<代码> 6860/28=245 < /COD>和<代码> 245 * 245 = 60025 > /COD>这是更多的图像。变成一个大马赛克?因为你是逐个列这些图像,你已经把它们作为一个图像,28个像素高,1680000个像素宽。你需要使用另一个网格,像100×600个图像,即:2800×16800像素。BTW,C代码标记为C++。为什么?OT:在C++中使用IOFFROW。6860×6860是不可能的。图像无法精确匹配。6860 x 6860是绝对可能的,因为图像会匹配。的确,在生成的图像中会有一些剩余空间,但由于问题中提到了尺寸,我想提问方希望这样做。子图像将如何排列的问题已经在关于这个问题的其他评论中得到了解决。我的观点是,你无法获得一个大小为28x28像素的60000个图像的正方形。6860 x 6860是不可能的。图像无法精确匹配。6860 x 6860是绝对可能的,因为图像会匹配。的确,在生成的图像中会有一些剩余空间,但由于问题中提到了尺寸,我想提问方希望这样做。子图像将如何排列的问题已经在关于这个问题的其他评论中得到了解决。我的观点是,你无法获得一个大小为28x28像素的60000个图像的正方形。你的想法是对的,但是使用fwrite会有点困难,因为我是逐像素编写的。或者将其输出到另一个dim阵列。我可以批量复制到一个文件中。好的,我更新了我的答案f