如何为十亿张 png 图像生成统一的缩略图?
Posted
技术标签:
【中文标题】如何为十亿张 png 图像生成统一的缩略图?【英文标题】:How to produce a unitary thumbnail for a billion of png images? 【发布时间】:2017-07-02 09:49:28 【问题描述】:在应用程序中,大约有10亿张png图片(大小1024*1024,每张大约1MB),需要将这10亿张图片组合成一个巨大的图片,然后生成一个1024*1024大小的统一缩略图 为它。或者也许我们不需要真正将图像组合成一个巨大的图像,而只需做一些神奇的算法来在计算机内存中生成单一的缩略图?同时,这个过程需要尽可能快地完成,最好在几秒钟内完成,或者至少在几分钟内完成。有人知道吗?
【问题讨论】:
十亿美元 (10**9
) 还是十亿欧元 (10**12
)?
一个意味着十亿,一个巨大的数量。
你所说的统一缩略图是什么意思,目的是什么?
就像我贴在帖子里的图片一样,png图片应该被分割成一张大图,然后,我想要大图的缩略图。
请注意,您的缩略图大小为 1024*1024,大约为 百万 像素。使用 十亿 个图像来生成此图像,意味着每个原始图像将在缩略图中贡献大约 1/1000 像素……缩略图不太可能显示任何有意义的信息。你确定这是你想要的吗?
【参考方案1】:
将十亿张图片加载到单个montage
进程中的想法是荒谬的。您的问题尚不清楚,但您的方法应该是确定每个原始图像在最终图像中的像素数,然后从每个图像中并行提取必要数量的像素。然后将这些像素组合成最终图像。
因此,如果每张图像将由最终图像中的一个像素表示,您需要获得每张图像的平均值,您可以这样做:
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:
然后您可以制作最终图像并将各个像素放入。
即使扫描 1,000,000 个 PNG 文件也可能需要好几个小时......
你没有说你的图像有多大,但如果它们每个大小为 1MB,并且你有 1,000,000,000,那么你需要执行 PB 的 I/O 来读取它们,所以即使使用 500MB/ s 超快速 SSD,您将在那里 23 天。
【讨论】:
如果平铺图像将从不同的客户端上传,在上传之前在客户端生成代表像素,然后在服务器上将像素合成为图像是一个好主意吗?这种方式会不会很快? 答案取决于您的环境,不幸的是,我无法理解当前的描述。如果有 1,000,000,000 位客户每人向您发送一张图片,那么每个人都向您发送最低限度的必要数据是有意义的。如果只有 1024 个客户端,每个客户端提供 1,000,000 张图像,则每个客户端为您计算出一个完整的块是有意义的,但如果每个客户端只发送一张图片,您就不能这样做。一般来说,您可以使用更多机器来处理单个零件,效果就越好。 我是否可以恭敬地建议您编辑您的问题并改进它,这样人们就不必猜测和浪费时间来覆盖可能不相关的案例或根据穷人提出的错误假设得出答案描述... 是的,谢谢,我会尽可能地改进描述。【参考方案2】:ImageMagick 可以做到这一点:
montage -tile *.png tiled.png
如果您出于某种原因不想使用外部帮助程序,您仍然可以使用源代码。
【讨论】:
在我的测试中,大量图像非常非常慢,有什么建议吗? 所以在机器集群上,使用 montage(带 -resize)可以将图像组合在一起。因此,为了实现您的目标,您将首先创建一组 nxn 作业并运行它们,然后在生成的蒙太奇上重复,直到您只剩下一个蒙太奇。【参考方案3】:随机抽样等随机算法可能是可行的。
考虑到合成图像这么大,任何线性算法都可能失败,更不用说复杂度更高的方法了。
通过计算,我们可以推断出每个缩略图像素取决于 1000 张图像。所以单次采样残差对结果影响不大。
算法描述如下:
对于每个缩略图像素坐标,随机选择对应位置的N张图片,每张图片采样M个像素,然后计算它们的平均值。对其他缩略图像素执行相同操作。
但是,如果您的图像是随机组合的,则结果往往是 0.5 值的灰度图像。因为根据中心极限定理,缩略图像素的方差趋于为零。因此,您必须确保组合缩略图本身是结构化的。
PS:使用 OpenCV 会是一个不错的选择
【讨论】:
以上是关于如何为十亿张 png 图像生成统一的缩略图?的主要内容,如果未能解决你的问题,请参考以下文章