本文是沿着源码,把 GeoAI 里“遥感影像 → 训练 chip”的真实执行路径一层一层扒开。可以把它当成一篇“读完就能自己实现一套切片引擎”的技术博客。
从大幅影像到训练样本的完整机制
在 GeoAI 的整个流程中,“数据切片”不是一个简单的预处理步骤,而是连接 GIS 数据与深度学习模型之间最关键的一座桥。因为模型从来不直接理解:
• GeoTIFF(大幅遥感影像) • Shapefile(矢量标签)
它只理解:
• 固定大小的图像(如 256×256) • 对应的标签(mask / bbox)
GeoAI 的 chip 生成,本质上完成了这样一个转换:
大幅遥感影像 + 矢量标签 → 小图块(image chip)+ mask而这个过程,在源码中并不是一个函数,而是一整套逻辑链条。
切片不是裁剪,而是空间计算过程
GeoAI 的切片流程,可以抽象成如下步骤:
对应 GIS 逻辑:
关键点在于:每一个 chip 都是一个“空间对象”,不是简单的数组切片
chip 生成的基本调用方式
在 GeoAI 中,切片通常封装为高层接口(类似如下逻辑):
create_chips( image_path, label_path, chip_size=256, stride=128, output_dir="chips/")虽然源码分散在不同模块中,但核心逻辑集中在三件事:
1. 滑窗生成(Window Generator) 2. 栅格裁剪(Raster Clip) 3. 标签栅格化(Vector → Mask)
滑窗机制
滑窗生成逻辑
GeoAI 切片的核心不是裁剪函数,而是滑窗生成器,是chip 的本质来源。
典型实现逻辑如下:
for y inrange(0, height, stride):for x inrange(0, width, stride): window = Window(x, y, chip_size, chip_size)关键参数说明
• chip_size:输出图像大小(如 256)• stride:滑动步长(控制重叠)
为什么必须用滑窗?
如果不用滑窗,而是整图输入:
• 显存爆炸 • 数据量不可控 • 模型无法泛化
滑窗的意义在于:把“空间连续影像”转化为“离散样本集合”
GeoAI 的优化点
GeoAI 在这里通常会做两件优化:
边界处理
if x + chip_size > width: x = width - chip_size避免最后一块越界
重叠控制
stride < chip_size:
保证目标不会被切断例如:
chip_size = 256stride = 128每个像素会被覆盖多次
栅格裁剪
滑窗只是定义空间范围,真正裁剪影像依赖 rasterio:
with rasterio.open(image_path) as src: chip = src.read(window=window)关键点解释
1. window 不是像素切片
它是:
(x_offset, y_offset, width, height)带有空间含义
2. transform 更新
GeoAI 会更新 affine transform:
transform = src.window_transform(window)如果不做这一步: 后续 mask 会错位
3. 输出 chip
rasterio.open(output_path, "w", ...) as dst: dst.write(chip)标签处理
这是 GeoAI 最“值钱”的部分。因为模型训练需要:
image: (256, 256, 3)mask: (256, 256)而你原始数据是:
Polygon(建筑物)1. 空间裁剪标签
clipped_gdf = gdf.cx[minx:maxx, miny:maxy]只保留当前 chip 内的要素
2. 栅格化(核心)
mask = rasterize( [(geom, 1) for geom in clipped_gdf.geometry], out_shape=(chip_size, chip_size), transform=transform)关键解释
(1)为什么要 rasterize?
因为模型不理解 polygon,只理解像素
(2)transform 为什么重要?
它决定:
地理坐标 → 像素坐标如果 transform 错了: mask 会偏移
3. 多类别处理
[(geom, class_id) for geom in gdf]支持语义分割
样本过滤
GeoAI 通常不会保存所有切片,避免无效的clip标签,而是要过滤:
if mask.sum() == 0:continue为什么必须过滤?
否则会出现:
• 大量纯背景图 • 模型训练偏移 • 精度下降
更高级过滤
if mask_ratio < threshold: skip控制正样本比例
数据增强
在 chip 生成阶段,GeoAI 还可能做增强:
flip(chip)rotate(chip)normalize(chip)特别是遥感数据:
• 多尺度 • 多方向 • 光照差异大
输出结构
最终输出通常为:
dataset/├── images/│ ├── chip_001.tif│ ├── chip_002.tif├── masks/│ ├── chip_001.tif│ ├── chip_002.tif或 COCO / YOLO 格式
GeoAI 也支持:
• bbox(检测) • polygon(实例分割)
GeoAI 的工程设计亮点
1. 空间一致性优先
所有操作都围绕:
CRS + transform不是简单数组处理
2. Raster + Vector 联动
切片不是:
image → chip而是:
image + vector → image chip + mask3. 可扩展 pipeline
你可以插入:
• 多时相数据 • 多模态数据 • DEM / 气象数据
核心最简代码
抽一份“最小可用版本”:
defgenerate_chips(image_path, gdf, chip_size=256, stride=128):with rasterio.open(image_path) as src:for y inrange(0, src.height, stride):for x inrange(0, src.width, stride): window = Window(x, y, chip_size, chip_size) chip = src.read(window=window) transform = src.window_transform(window) bounds = rasterio.windows.bounds(window, src.transform) minx, miny, maxx, maxy = bounds clipped = gdf.cx[minx:maxx, miny:maxy]if clipped.empty:continue mask = rasterize( [(geom, 1) for geom in clipped.geometry], out_shape=(chip_size, chip_size), transform=transform )yield chip, maskGeoAI 的切片模块,本质不是“切图工具”,而是:一个把“空间世界”翻译成“机器语言”的过程
如果这一步做得不好: 模型再强也没用。如果这一步做得好: 普通模型也能出奇迹
夜雨聆风