如何为十亿个PNG图像生成一个统一的缩略图?

8
在这个应用程序中,有大约10亿个PNG图像(每个尺寸为1024*1024,大小约为1MB),需要将这10亿张图片合并成一个巨大的图像,然后生成一个大小为1024*1024的统一缩略图。或者我们不需要真正将这些图像合并成一个巨大的图像,而只需在计算机内存中进行一些魔术算法来生成统一缩略图?同时,这个过程需要尽可能快地完成,最好在几秒钟内完成,或者至少在几分钟内完成。有人有想法吗?

enter image description here


2
美国的十亿(109)还是欧洲的万亿(1012)? - alk
一亿是一个巨大的数量。 - Suge
“单一缩略图”是什么意思?有什么作用? - user694733
就像我在帖子中附加的图片那样,应该将png图像切片为一张巨大的图片,然后我想要巨大图片的缩略图。 - Suge
2
请注意,您的缩略图大小为1024*1024,大约有一百万个像素。使用十亿张图片来生成它意味着每张原始图片只会在缩略图中贡献约1/1000个像素... 缩略图不太可能展示任何有意义的信息。您确定这就是您想要的吗? - Harald K
显示剩余3条评论
3个回答

9
在单个“合成”过程中加载十亿张图片的想法是荒谬的。尽管您的问题不是很明确,但您应该确定每个原始图像在最终图像中将占用多少像素,然后并行地从每个图像中提取必要数量的像素。然后将这些像素组装成最终图像。
因此,如果每个图像将由一个像素表示,则您需要获取每个图像的平均值,可以按照以下方式完成:
convert image1.png image2.png ... -format "%[fx:mean.r],%[fx:mean.g],%[fx:mean.b]:%f\n" info:

示例输出

0.423529,0.996078,0:image1.png
0.0262457,0,0:image2.png

如果您想要快速并行地完成这个任务,可以使用GNU Parallel来处理,例如:

find . -name \*.png -print0 | parallel -0 convert {} -format "%[fx:mean.r],%[fx:mean.g],%[fx:mean.b]:%f\n" info:

然后,您可以制作最终图像并放入单个像素。

即使扫描100万个PNG文件也可能需要数小时...

您没有说明图像的大小,但如果它们每个大小大约为1MB,并且您有10亿个图像,则需要进行1PB的I/O才能读取它们,因此即使使用500MB/秒的超快速SSD,您也需要23天时间。


如果瓷砖图像将从不同的客户端上传,那么在上传之前在客户端上生成代表像素,然后在服务器上合成像素以形成图像是一个好主意吗?这种方式会非常快吗? - Suge
1
答案取决于您的环境,但很遗憾,我无法根据当前的描述理解它。如果有10亿个客户端每个都发送一张图片,那么每个客户端只发送最小必要量是有意义的。如果只有1024个客户端每个提供100万张图片,那么每个客户端为您计算整个块是有意义的,但如果每个客户端只发送一张图片,则无法这样做。通常来说,您可以让更多的机器处理各个部分,这样会更好。 - Mark Setchell
2
我可以恭敬地建议您编辑您的问题并加以改进,这样人们就不必猜测和浪费时间去处理可能与问题无关的情况或者基于不准确的假设得出错误的答案,这些假设可能源自于描述不清晰。 - Mark Setchell
是的,谢谢,我会尽可能地改进描述,使其更加清晰明了。 - Suge

3
ImageMagick可以实现这个功能: montage -tile *.png tiled.png 如果出于任何原因你不想使用外部帮助程序,你仍然可以使用源代码。

我的测试中处理大量图片非常慢,有什么建议吗? - Suge
在一组机器上,使用montage(带有-resize选项)可以将图像分组。因此,为了实现您的目标,首先要创建一组nxn作业,并运行这些作业,然后在生成的montages上重复此过程,直到只剩下一个montage。 - mksteve

3

随机算法,例如随机采样,可能是可行的。

考虑到合成图像非常大,任何线性算法可能会失败,更不用说更高复杂度的方法。

通过计算,我们可以推断出每个缩略图像素依赖于1000张图像。因此,单个采样残差不会对结果产生太大影响。

算法描述如下:

对于每个缩略图像素坐标,随机选择N张在相应位置上的图像,并对每个图像采样M个像素,然后计算它们的平均值。对其他缩略图像素执行同样的操作。

然而,如果您的图像是随机组合的,则结果往往是一个灰度值为0.5的图像。因为根据中心极限定理,缩略图像素的方差往往趋近于零。所以你必须确保合成的缩略图本身是有结构的。

备注:使用OpenCV将是一个不错的选择。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接