python - 合并磁盘上的大图像

标签 python image mapreduce computer-vision

主要问题:

我有一个映射步骤,我在其中并行渲染图像的大量扇区:

1 2
3 4

worker a -> 1
worker b -> 2
...

merge 1,2,3,4 to make final image

如果它能装进内存

对于相对较小且可以放入 RAM 的图像,可以简单地使用 PIL 的功能:

def merge_images(image_files, x, y):
    images = map(Image.open, image_files)
    width, height = images[0].size    
    new_im = Image.new('RGB', (width * x, height * y))
    for n, im in enumerate(images):
        new_im.paste(im, ((n%x) * width, (n//y) * height))
    return new_im

不幸的是,我将拥有很多很多大扇区。我想最终将这些图片合并成一张大约 40,000 x 60,000 像素的图像,我估计大约有 20 GB。 (或者甚至更多)

很明显,我们不能在 RAM 上解决这个问题。我知道有一些替代方案,例如 memmap'ing 数组和写入切片,我会尝试这些。但是,我正在寻找尽可能开箱即用的解决方案

有没有人知道任何更简单的替代方案? 尽管到目前为止我尝试过的所有方法都是在 python 中,但它不需要在 python 中

最佳答案

pyvips可以非常快速有效地做你想做的事。例如:

import sys
import pyvips

images = [pyvips.Image.new_from_file(filename, access="sequential")
          for filename in sys.argv[2:]]
final = pyvips.Image.arrayjoin(images, across=10)
final.write_to_file(sys.argv[1])

access="sequential" 选项告诉 pyvips 您想要流式传输图像。它只会在生成输出时按需加载像素,因此您可以仅使用少量内存来合并大量图像。 arrayjoin运算符将图像数组连接到 across 的网格中。它有很多布局选项:您可以指定边框、重叠、背景、居中行为等。

我可以这样运行它:

$ for i in {1..100}; do cp ~/pics/k2.jpg $i.jpg; done
$ time ../arrayjoin.py x.tif *.jpg 

real    0m2.498s
user    0m3.579s
sys 0m1.054s
$ vipsheader x.tif
x.tif: 14500x20480 uchar, 3 bands, srgb, tiffload

所以它在这台笔记本电脑上加入 100 张 JPG 图片以在大约 2.5 秒内制作 14,000 x 20,000 像素的马赛克,并且从观看 top 来看,需要大约 300mb 的内存。我用它把 30,000 多张图片合并到一个文件中,而且它会更高。我制作了超过 300,000 x 300,000 像素的图像。

PIL 的 paste 的 pyvips 等价物是 insert .你也可以使用它,尽管它对于大量图像来说效果不佳。

还有一个命令行界面,所以你可以输入:

vips arrayjoin "${echo *.jpg}" x.tif --across 10

加入大量 JPG 图片。

关于python - 合并磁盘上的大图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50297176/

相关文章:

Xcode,无法从项目中删除 "Launch image"

html - 使图像像背景图像一样调整大小

Android Compose - 如何平铺/重复位图/矢量?

hadoop - hadoop的fft算法实现

hadoop - "merge"在 MapReduce 中是什么意思?

python - 从 2 个 uint64 值中提取 Spooky-hash 128 位值

python - 在 Python 中使用堆的前 K 个常用词

python - 为什么从初始化中添加零偏移量与从减法中添加零偏移量不同?

python - 如何使用 Python 从 .aspx 页面检索数据?

java - 用于剖析的不同工具以及对hadoop map的某种监视会减少Java中的程序?