【问题标题】:Apply image smoothing and edge detection algorithms on a 2.4 GB GeoTIFF image在 2.4 GB GeoTIFF 图像上应用图像平滑和边缘检测算法
【发布时间】:2019-02-28 05:32:51
【问题描述】:

所以我有超过 150,000 个巨大的 GeoTIFF 图像(每个 2.4 GB),我需要在这些图像上运行图像平滑和边缘检测(LoG 过滤器)以获得锐化的图像。我使用 Gdal 读取图像,对其进行平滑处理、二次采样、创建高通滤波器(5 级)并重建图像。

这适用于普通的 .jpg 文件。

但对于一个巨大的 TIFF 文件,我无法完成此操作,因为即使使用 32 GB RAM 8 核处理器和 4 TB 磁盘空间,我也会经常遇到内存错误。

在 Python 3.6 Ubuntu 18 LTS 上进行重量级图像处理/图像分割的最佳方法是什么?

【问题讨论】:

  • 如果您使用 numpy 或基于 numpy 的库(例如 scikit-image)来处理图像,请尝试 dask

标签: python python-3.x image-processing edge-detection geotiff


【解决方案1】:

通常情况下,此类大图像会以平铺方式进行处理。这个想法是将图像分成小块,独立读取每个小块,并有足够的“重叠”来解释应用的过滤,处理它并将其写入文件。

TIFF 标准知道“平铺”格式(我相信 GeoTIFF 文件通常以平铺格式存储)。这种格式经过明确设计,可以在图像的小窗口中轻松阅读,而无需将整个文件中的点点滴滴拼凑在一起。 TIFF 文件中的每个图块都可以按位置进行索引,并独立编码和压缩,因此一次读取和写出一个图块很容易。

您需要的重叠取决于应用的过滤。例如,如果您应用具有 9x9 窗口的拉普拉斯高斯滤波器(超过中心像素达到 4 个像素),则重叠只需 4 个像素。如果您链接过滤器,您通常希望添加每个过滤器的覆盖范围以获得总重叠值。

接下来,将图像分割成 TIFF 文件中平铺大小的倍数。假设该文件具有 512x512 像素的图块。您可以选择一次处理 8 个图块,区域为 2048x2048 像素。

现在在每个维度上以 2048 步循环遍历图像。读入 8 个图块,并包括相邻的图块,您将对其进行裁剪,以便在一侧获得 2048+2*4 像素的方形图像。处理子图像,去除重叠区域,并将其余部分写入输出 TIFF 文件中的相应图块。输出 TIFF 文件的设置方式应与输入 TIFF 文件相同。

我确信有软件可以自动执行此过程,但我不知道 Python 中有任何软件。如果您自己实现此功能,您将需要学习如何在 TIFF 文件中读取和写入各个切片。一种选择是pylibtiff

【讨论】:

  • pyvips 的工作方式与此非常相似,并且会自动矢量化(它具有运行时代码生成器)和线程(默认情况下它会加载所有内核)。我有一个答案。
【解决方案2】:

pyvips 可以处理巨大的图像quickly and in little memory。它是 LGPL,可在 Linux、macOS 和 Windows 上运行,并且适用于 Python 的每个版本。大多数 linux(包括 Ubuntu)在包管理器中都有它。

这是一个需求驱动的流式图像处理库。它不是在单个巨大的块中处理图像,而是在您背后构建一个图像处理操作员网络,并且根据创建输出的需要,像素在小区域中通过您的计算机内存拉出。

例如,我可以运行这个程序:

import sys
import pyvips

# access='sequential' puts pyvips into streaming mode for this image
im = pyvips.Image.new_from_file(sys.argv[1], access='sequential')
im = im.crop(100, 100, im.width - 200, im.height - 200)
# 10% shrink, lanczos3 (by default)
im = im.resize(0.9)
mask = pyvips.Image.new_from_array([[-1, -1,  -1], 
                                    [-1,  16, -1], 
                                    [-1, -1,  -1]], scale=8)
# integer convolution ... you can use large float masks too, canny,
# sobel, etc. etc.
im = im.conv(mask, precision='integer')
im.write_to_file(sys.argv[2])

在 40k x 30k 像素的 GeoTIFF 图像上:

$ vipsheader SAV_X5S_transparent_mosaic_group1.tif 
SAV_X5S_transparent_mosaic_group1.tif: 42106x29852 uchar, 4 bands, srgb, tiffload

在这台 2015 年的笔记本电脑上运行如下:

$ /usr/bin/time -f %M:%e python3 bench.py SAV_X5S_transparent_mosaic_group1.tif x.tif
257012:101.43

即。 260mb 的内存,101 秒的运行时间。在您的大型机器上应该会快一些。

您可能遇到的一个问题是 GeoTIFF 标签:它们不会被 pyvips 保存。也许您在以后的处理中不需要它们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-07
    • 1970-01-01
    • 2010-12-01
    • 2016-09-21
    相关资源
    最近更新 更多