【问题标题】:how can I load a single tif image in parts into numpy array without loading the whole image into memory?如何在不将整个图像加载到内存的情况下将单个 tif 图像部分加载到 numpy 数组中?
【发布时间】:2019-12-04 18:49:15
【问题描述】:

所以有一个 4GB 的 .TIF 图像需要处理,作为内存限制,我无法将整个图像加载到 numpy 数组中,所以我需要从硬盘中懒惰地加载它。 所以基本上我需要并且需要在 python 中作为项目要求来完成。我还尝试在 PyPi tifffile 中寻找 tifffile 库,但没有发现任何有用的信息,请帮忙。

【问题讨论】:

  • 考虑使用pyvips - 它在内存上非常节俭。也许添加vips 标签来吸引合适的人。还要尝试更明确地说明您的处理。

标签: python numpy image-processing python-imaging-library vips


【解决方案1】:

pyvips 可以做到这一点。例如:

import sys
import numpy as np
import pyvips

image = pyvips.Image.new_from_file(sys.argv[1], access="sequential")

for y in range(0, image.height, 100):
    area_height = min(image.height - y, 100)
    area = image.crop(0, y, image.width, area_height)
    array = np.ndarray(buffer=area.write_to_memory(),
                       dtype=np.uint8,
                       shape=[area.height, area.width, area.bands])

new_from_fileaccess 选项打开顺序模式:pyvips 只会按需从文件中加载像素,但限制是您必须从上到下读取像素。

循环以 100 条扫描线为单位向下运行图像。当然,你可以调整它。

我可以这样运行:

$ vipsheader eso1242a-pyr.tif 
eso1242a-pyr.tif: 108199x81503 uchar, 3 bands, srgb, tiffload_stream
$ /usr/bin/time -f %M:%e ./sections.py ~/pics/eso1242a-pyr.tif
273388:479.50

因此,在这台可悲的旧笔记本电脑上,扫描一张 108,000 x 82,000 像素的图像需要 8 分钟,并且需要 270mb 的峰值内存。

你在做什么处理?您可能可以在 pyvips 中完成所有操作。它比 numpy 快很多。

【讨论】:

    【解决方案2】:
    import pyvips
    img = pyvips.Image.new_from_file("space.tif", access='sequential')
    out = img.resize(0.01, kernel = "linear")
    out.write_to_file("resied_image.jpg")
    

    如果您想将文件转换为具有较小尺寸的其他格式,则此代码就足够了,并且可以帮助您在没有任何内存峰值的情况下并且在更短的时间内完成...

    【讨论】:

    • 我从 1.6 GB 下载了一个文件,它可以在内存使用量没有任何峰值的情况下运行
    • 在转换之前不要将它加载到 numpy 中会更好
    猜你喜欢
    • 2013-04-24
    • 1970-01-01
    • 2018-05-26
    • 2011-08-26
    • 2017-09-21
    • 1970-01-01
    • 2012-06-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多