You need to enable JavaScript to run this app. 使用rasterio实现栅格重叠窗口读取与无重叠窗口写入的问题
优惠活动
大模型
产品
解决方案
定价
更多

使用rasterio实现栅格重叠窗口读取与无重叠窗口写入的问题

栅格重叠窗口读取+无重叠写入调整方案

你的核心问题是读取时使用了带重叠的窗口,但写入时直接输出了完整的重叠区域数据,没有裁剪掉边缘重叠部分,也没有对应到原图的正确无重叠位置写入。

调整步骤

1. 修改分块生成逻辑

在生成重叠读取窗口的同时,同步生成每个块对应的无重叠写入窗口,以及处理后数组的裁剪索引:

  • 读取窗口:带重叠,用于加载数据做计算,避免边缘伪影
  • 写入窗口:无重叠,对应原图中该块的实际写入位置
  • 裁剪索引:用于从计算完成的带重叠数组中,抠出中间无重叠的部分

2. 修改写入逻辑

不要为每个块单独创建输出文件,全程只打开一次目标文件,将裁剪后的无重叠数据写入到对应的窗口位置即可。

修改后完整代码

from itertools import product
import rasterio 
from rasterio import windows
from rasterio.crs import CRS

def overlapping_windows(src, overlap, block_width, block_height):
    """
    生成带重叠的读取窗口、无重叠的写入窗口、以及数组裁剪索引
    :param src: rasterio打开的源文件对象
    :param overlap: 重叠像素数
    :param block_width: 无重叠块的宽度
    :param block_height: 无重叠块的高度
    """
    col_offsets = range(0, src.width, block_width)
    row_offsets = range(0, src.height, block_height)
    big_window = windows.Window(0, 0, src.width, src.height)

    for col_off, row_off in product(col_offsets, row_offsets):
        # 1. 计算带重叠的读取窗口
        read_col_off = max(0, col_off - overlap)
        read_row_off = max(0, row_off - overlap)
        read_width = block_width + overlap * 2
        read_height = block_height + overlap * 2
        read_window = windows.Window(
            read_col_off, read_row_off, read_width, read_height
        ).intersection(big_window)

        # 2. 计算无重叠的写入窗口(对应原图位置)
        write_width = min(block_width, src.width - col_off)
        write_height = min(block_height, src.height - row_off)
        write_window = windows.Window(
            col_off, row_off, write_width, write_height
        )

        # 3. 计算处理后数组的裁剪索引:从带重叠的数组中抠出无重叠部分
        crop_row_start = row_off - read_row_off
        crop_row_end = crop_row_start + write_height
        crop_col_start = col_off - read_col_off
        crop_col_end = crop_col_start + write_width

        yield read_window, write_window, (crop_row_start, crop_row_end, crop_col_start, crop_col_end)

def process_image(src_img, dst_img, overlap, block_width, block_height, epsg, band_id=1):
    # 先获取源文件元信息,目标文件和源文件坐标系、尺寸完全一致
    with rasterio.open(src_img) as src:
        out_meta = src.meta.copy()
        out_meta.update({
            'driver': 'GTiff',
            'tiled': True,
            'compress': None,
            'crs': CRS.from_epsg(epsg)
        })

        # 全程只打开一次目标文件
        with rasterio.open(dst_img, 'w', **out_meta) as dst:
            for read_window, write_window, crop_idx in overlapping_windows(src, overlap, block_width, block_height):
                # 读取带重叠的窗口数据
                src_data = src.read(band_id, window=read_window)
                # 此处替换为你的实际处理逻辑
                dst_data = src_data ** 2

                # 裁剪出无重叠部分
                crop_row_start, crop_row_end, crop_col_start, crop_col_end = crop_idx
                write_data = dst_data[crop_row_start:crop_row_end, crop_col_start:crop_col_end]

                # 写入到目标文件对应的无重叠窗口位置
                dst.write(write_data, band_id, window=write_window)
    return 0

# 调用示例
if __name__ == "__main__":
    process_image(
        src_img="输入.tif",
        dst_img="输出.tif",
        overlap=1, # 重叠1像素
        block_width=256, # 无重叠块宽256
        block_height=256, # 无重叠块高256
        epsg=4326 # 目标坐标系EPSG
    )

关键修改说明

  • 去掉了原代码中循环内重复创建输出文件的逻辑,避免每个块生成单独文件的错误
  • 写入时通过window参数指定写入位置,保证所有无重叠块刚好拼接成完整的输出影像,无重叠也无空隙
  • 自动处理边缘块的裁剪逻辑,边缘处没有足够重叠区域时也不会出现索引错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.22 02:57:05