You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何利用带GPS坐标的.shp文件快速制作大.tif文件的二值掩码

大TIFF文件批量多边形掩码优化方案

问题背景

处理24GB的大型.tif文件,内存无法完全加载。尝试过rasterio官方的shp掩码方法,但批量处理所有多边形耗时超3小时,且常被服务器终止进程。现有代码仅能逐个处理多边形,效率低下。

当前代码核心问题

  • 每次处理单个多边形都重复打开/写入输出TIFF,IO开销极大
  • 重复调用rasterio.mask.mask和窗口读取,存在大量冗余计算
  • 未利用rasterio分块处理能力,内存占用控制不佳

优化方案

优化方向1:按类别批量处理,减少IO操作

同一类别的所有多边形一次性处理,仅打开/写入输出TIFF一次,避免多次磁盘IO的耗时。

优化方向2:利用栅格化批量生成掩码

使用rasterio.features.rasterize直接批量栅格化同类别多边形,跳过冗余的影像读取步骤(若仅需掩码文件)。

优化方向3:压缩存储+坐标系预转换

  • 掩码采用单通道+压缩存储,减小输出文件体积,加快读写速度
  • 提前将矢量数据转换为栅格坐标系,避免每次处理时的动态转换开销

优化后代码

import rasterio
import geopandas as gpd
from tqdm import tqdm
import os
from rasterio.features import rasterize
from rasterio.windows import from_bounds, transform as window_transform

def generate_mask(raster_path, shape_path, output_path):
    # 确保输出目录存在
    os.makedirs(output_path, exist_ok=True)
    
    gdf = gpd.read_file(shape_path)
    with rasterio.open(raster_path) as src:
        # 统一坐标系,避免后续重复转换
        gdf = gdf.to_crs(src.crs)
        # 初始化掩码文件元数据:单通道、uint8类型、压缩存储
        mask_meta = src.meta.copy()
        mask_meta.update(count=1, dtype='uint8', compress='deflate')
        
        for class_num in tqdm(sorted(gdf['class'].unique())):
            output_file = os.path.join(output_path, f'{class_num}.tif')
            if os.path.exists(output_file):
                continue
            
            # 获取当前类别的所有多边形
            class_geoms = gdf[gdf['class'] == class_num]['geometry'].tolist()
            if not class_geoms:
                continue
            
            # 计算当前类别所有多边形的总边界,缩小处理范围
            total_bounds = gdf[gdf['class'] == class_num].total_bounds
            bbox = from_bounds(*total_bounds, src.transform)
            win_transform = window_transform(bbox, src.transform)
            win_h, win_w = int(bbox.height), int(bbox.width)
            
            # 批量栅格化生成掩码
            mask = rasterize(
                [(geom, 1) for geom in class_geoms],
                out_shape=(win_h, win_w),
                transform=win_transform,
                fill=0,
                dtype=rasterio.uint8
            )
            
            # 更新元数据并写入掩码文件
            mask_meta.update(height=win_h, width=win_w, transform=win_transform)
            with rasterio.open(output_file, 'w', **mask_meta) as dest:
                dest.write(mask, 1)
            print(f'类别 {class_num} 掩码已写入 {output_file}')

额外需求:结合原影像裁剪

如果需要生成原影像裁剪+掩码叠加的结果,可修改写入部分的代码:

import numpy as np

# 读取对应窗口的原影像
img_crop = src.read(window=bbox)
# 将单通道掩码扩展为与影像匹配的多通道
mask_3d = np.expand_dims(mask, axis=0)
# 应用掩码
out_image = img_crop * mask_3d

# 更新元数据为原影像的通道数和数据类型
img_meta = src.meta.copy()
img_meta.update(height=win_h, width=win_w, transform=win_transform, compress='deflate')
with rasterio.open(output_file, 'w', **img_meta) as dest:
    dest.write(out_image)

内容的提问来源于stack exchange,提问作者Nikita Artemenko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 03:45:23