GeoAI 中的 SamGeo:基于 Segment Anything Model 的地理空间影像分割实战指南
人工智能计算机视觉GIS图像处理微调【免费下载链接】geoaiGeoAI: Artificial Intelligence for Geospatial Data项目地址https://gitcode.com/gh_mirrors/ge/geoai点击查看免费下载导读本文围绕 GeoAI 项目中的sam模块展开系统讲解如何基于 Segment Anything ModelSAMMeta 提出的通用分割模型对遥感影像、航拍影像等地理空间数据进行分割。sam模块的核心是SamGeo类它同时支持两种工作方式自动掩码生成automaticTrue分割整幅影像中的所有对象与输入提示词分割automaticFalse通过点、框等提示精准分割指定对象。读完本文你将掌握SamGeo的初始化参数、完整的分割工作流、掩码保存与矢量化后处理以及将经纬度坐标转换为像素坐标进行地理坐标提示分割的底层原理。本文内容以 docs/sam.md 的模块文档为骨架该文档通过 mkdocstrings 指令::: geoai.sam自动渲染 geoai/sam.py 中的完整 API 文档下文在此基础上结合源码实现、单元测试tests/test_sam.py与实战示例docs/examples/samgeo.ipynb进行深度展开。模块定位为地理空间数据封装 SAMSamGeo类定义于 geoai/sam.py的文档字符串明确说明了其职责The SamGeo class provides an interface for segmenting geospatial data using the Segment Anything Model (SAM)即它为地理空间数据的分割提供统一接口底层基于 Hugging Face Transformers 库中的SamModel、SamProcessor与pipeline实现。从 geoai/sam.py 的导入语句可以看到模块的依赖结构leafmap的array_to_image、blend_images负责将掩码数组写出为带地理参考georeferenced的 GeoTIFF 影像、以及注释与原始影像的融合transformers的SamModel、SamProcessor、pipeline提供 SAM 模型本体与推理管线geoai.utils下的工具函数download_file下载远程影像、coords_to_xy/bbox_to_xy坐标转像素坐标、geojson_to_coords/vector_to_geojson矢量数据坐标提取、raster_to_vector栅格掩码矢量化。由此可以看出SamGeo的设计目标把「模型推理」与「地理空间数据读写/转换」两条链路整合在一个类中让用户无需关心坐标系转换、影像地理参考写入等繁琐细节。环境与依赖sam模块运行所需的核心依赖声明于 requirements.txt主要包括依赖版本要求用途transformers4.56.2SAM 模型、处理器与 mask-generation 管线torch2.10.0深度学习后端leafmap0.63.1影像读写、掩码输出、地图可视化opencv-python-headless无影像读取BGR→RGB、掩码腐蚀处理rasterio/rioxarray无地理栅格读写与坐标转换geopandas无矢量数据读取与 CRS 转换此外示例 notebook 使用了geoai.view_raster、geoai.create_split_map、geoai.download_file等顶层工具在 geoai/init.py 中以懒加载方式导出避免import geoai时加载重依赖。SamGeo 初始化两种模式与关键参数SamGeo构造函数geoai/sam.py的完整签名如下SamGeo( model: str facebook/sam-vit-huge, automatic: bool True, device: Optional[Union[str, int]] None, sam_kwargs: Optional[Dict[str, Any]] None, **kwargs: Any, )参数说明参数默认值说明modelfacebook/sam-vit-hugeSAM 模型类型可选facebook/sam-vit-huge、facebook/sam-vit-large、facebook/sam-vit-base等 Hugging Face 上的 SAM 权重automaticTrue是否使用自动掩码生成器。True表示分割整幅影像中的所有对象False表示使用输入提示点、框分割指定对象deviceNone推理设备可选cpu、cuda或代表 CUDA 设备索引的整数。默认为None自动模式与提示模式下的默认策略略有差异见下文sam_kwargsNone用于微调 SAM 模型的可选参数**kwargs—透传给自动掩码生成器的其他参数自动模式automaticTrue自动模式下geoai/sam.py类通过 Transformers 的pipeline构建 mask-generation 管线若device为None自动选择0CUDA 可用时或-1CPU若设备索引 0会先调用torch.cuda.empty_cache()清理 GPU 缓存随后pipeline(taskmask-generation, modelmodel, devicedevice, **kwargs)完成管线初始化。generate()、generate_batch()与show_masks()等方法均基于该自动掩码生成器工作。提示模式automaticFalse提示模式下geoai/sam.py类加载完整的SamModel.from_pretrained(facebook/sam-vit-huge)与SamProcessor.from_pretrained(facebook/sam-vit-huge)并将模型移动到推理设备。此时device默认取torch.device(cuda if torch.cuda.is_available() else cpu)CUDA 可用时同样先清空缓存。该模式下需要配合set_image()与predict()完成「先编码影像嵌入再基于提示预测掩码」的两阶段流程。实战一自动掩码生成整幅影像分割自动掩码生成是SamGeo最常见的用法。官方示例 docs/examples/samgeo.ipynb 给出了完整流程下面是拆解讲解。1. 下载演示影像import geoai from geoai.sam import SamGeo url https://huggingface.co/datasets/giswqs/geospatial/resolve/main/sam_demo_image.tif image geoai.download_file(url)geoai.download_file实现在 geoai/utils/download.py带进度条下载文件。SamGeo.generate()内部也支持直接传入http(s)开头的 URL——当source以http开头时会自动调用download_file下载到本地后再读取geoai/sam.py。2. 实例化 SamGeo 并生成掩码sam SamGeo(modelfacebook/sam-vit-huge, automaticTrue) sam.generate(sourceimage, outputmasks.tif, foregroundTrue)generate()geoai/sam.py是自动模式的核心方法签名如下generate( source: Union[str, np.ndarray], # 输入影像路径含 http URL或 numpy 数组 output: Optional[str] None, # 输出掩码影像路径 foreground: bool True, # 是否只生成前景掩码 erosion_kernel: Optional[Tuple[int, int]] None, # 腐蚀核如 (3,3) 或 (5,5)用于过滤对象掩码并提取边界 mask_multiplier: int 255, # 掩码乘子通常把 [0,1] 二值掩码缩放到 [0,255] unique: bool True, # 是否给每个对象分配唯一值 min_size: int 0, # 对象最小面积像素过滤小对象 max_size: Optional[int] None, # 对象最大面积过滤大对象 output_args: Optional[Dict[str, Any]] None, # 输出影像的额外保存参数 **kwargs, # 透传给 mask generator 的其他参数 )其执行流程为读取影像若source为路径用 OpenCV 读取并完成 BGR→RGB 转换若为numpy数组则直接使用两者都不是则抛出ValueErrorgeoai/sam.py。注意这里使用了延迟导入import cv2以避免与 QGIS 环境中的 OpenCV 产生冲突见源码注释。推理调用mask_generator(source, **kwargs)从结果中提取masks与scores。格式化掩码将每个掩码整理为包含segmentation二值掩码数组、areaTrue 像素数与score置信度转为原生 Python float的字典列表geoai/sam.py。保存掩码调用save_masks()写入输出详见下文。3. 查看与交互式展示sam.show_masks() # 显示二值掩码或唯一值掩码 sam.show_anns(alpha0.6) # 在原图上叠加随机颜色注释show_masks()geoai/sam.py以matplotlib显示掩码结果默认figsize(12, 10)、cmapbinary_r、axisoff。若self.objects尚未生成会先调用save_masks()。show_anns()geoai/sam.py在原图上叠加带随机颜色的注释透明度由alpha0.35控制并可按min_size/max_size过滤对象传入output路径时可把注释图可选与原图blend融合保存为影像文件。4. 使用 leafmap 地理可视化验证示例 notebook 最后用 leafmap 生态的查看器验证地理参考是否正确写入geoai.view_raster(masks.tif, colormaptab20, opacity0.6, basemapurl) geoai.create_split_map( left_layermasks.tif, right_layerurl, left_args{colormap: tab20, opacity: 1}, )create_split_map生成左右分屏对比地图左侧显示掩码、右侧显示原始影像可直观验证分割结果与影像的地理对齐情况。5. 批量分割generate_batch()geoai/sam.py支持一次处理多张影像generate_batch( inputs: List[Union[str, np.ndarray]], # 输入路径或数组列表 output_dir: Optional[str] None, # 输出目录默认为当前工作目录 suffix: str _masks, # 输出文件名后缀默认 _masks foregroundTrue, erosion_kernelNone, # 与 generate() 语义一致 mask_multiplier255, uniqueTrue, min_size0, max_sizeNone, output_argsNone, **kwargs, )其对每个输入分别执行 mask 生成并以{原文件名}{suffix}{扩展名}命名输出例如image.tif→image_masks.tif适合批处理影像瓦片或无人机航片序列。实战二掩码保存与地理矢量化后处理save_masks()geoai/sam.py是掩码落盘的核心其输出有两种形态唯一值掩码每个对象一个整数 ID与二值掩码前景/背景由unique参数决定。唯一值掩码uniqueTrue先将所有掩码按面积降序排序生成与输入影像同尺寸的全零数组按count - index规则为每个对象赋唯一值——面积越大编号越大min_size/max_size过滤在赋值前生效geoai/sam.py。二值掩码uniqueFalse默认累加所有对象掩码并二值化得到resulting_mask若指定erosion_kernel如(3, 3)、(5, 5)用 OpenCVcv2.erode对掩码做腐蚀用「原掩码 − 腐蚀掩码」提取对象边界再从掩码中扣除边界geoai/sam.py最终结果乘以mask_multiplier默认 255即把 [0,1] 二值掩码缩放到 [0,255] 的 8bit 灰度范围foregroundFalse时输出背景掩码。自动数据类型选择一个值得注意的实现细节save_masks()会根据对象数量自动选择输出数组的数据类型geoai/sam.py对象数量数据类型 255np.uint8 65535np.uint16其他np.uint32这保证了唯一值掩码能容纳全部对象 ID 而不溢出。输出文件通过 leafmap 的array_to_image写入因此掩码会继承输入影像的地理参考可直接在 GIS 软件中叠加使用。栅格掩码 → 矢量save_prediction()geoai/sam.py在保存预测掩码的同时支持直接矢量化save_prediction( output: str, # 输出掩码影像路径 index: Optional[int] None, # 要保存的掩码索引None 表示保存得分最高的掩码 mask_multiplier: int 255, dtype: np.dtype np.float32, vector: Optional[str] None, # 输出矢量文件路径 simplify_tolerance: Optional[float] None, # 几何简化容差越大顶点越少 **kwargs, )当传入vector参数时内部调用 geoai/utils/raster.py 的raster_to_vector将掩码栅格转换为 GeoJSON 矢量simplify_tolerance控制几何简化的最大允许位移值越大结果几何顶点越少从而直接获得可进入 GIS 分析管线的面要素。实战三基于提示的分割点、框提示精准提取对象当需要分割指定对象而非整幅影像时使用提示模式。核心是set_image()predict()两阶段流程。第一步set_image() 计算影像嵌入set_image(image: Union[str, np.ndarray], **kwargs) - Nonegeoai/sam.py。该方法读取影像支持本地路径、HTTP URL 与 numpy 数组通过processor预处理后用predictor.get_image_embeddings()计算并缓存影像嵌入存于self.embeddings供后续多次提示推理复用——这是 SAM 高效提示分割的关键影像只编码一次多个提示共享同一组嵌入。第二步predict() 基于提示生成掩码predict( point_coordsNone, # 点提示矢量文件路径 / GeoJSON 字典 / [lon, lat] 坐标列表 / numpy 数组 point_labelsNone, # 点标签1 为前景点0 为背景点 boxesNone, # 框提示XYXY 格式的 [x1, y1, x2, y2] point_crsNone, # 点提示的坐标系CRS mask_inputNone, # 上一轮迭代的低分辨率掩码SAM 为 1x256x256 multimask_outputTrue, # True 时返回三个掩码适合单点等歧义提示多提示时可设 False 获得更优结果 return_logitsFalse, # True 时返回未阈值化的掩码 logits outputNone, indexNone, mask_multiplier255, dtypefloat32, return_resultsFalse, **kwargs, )geoai/sam.py。predict()的地理空间特色体现在对各类提示输入的归一化处理框提示支持矢量与 GeoJSONboxes可以是矢量文件路径用geopandas读取后统一转换到epsg:4326取几何外接矩形bounds或 GeoJSON 字典点提示支持多种来源矢量文件路径经vector_to_geojson、GeoJSON 字典经geojson_to_coords提取中心点坐标坐标到像素的转换当同时给定point_crs时调用 geoai/utils/conversion.py 的coords_to_xy()/bbox_to_xy()将地理坐标如经纬度转换为影像像素坐标并自动剔除超出影像范围的越界点out_of_bounds机制见 geoai/sam.py标签自动补齐point_labels缺省时自动补为全 1全部视为前景点。推理时通过processor组织输入并注入缓存的image_embeddings在torch.no_grad()下调用predictor最后用processor.image_processor.post_process_masks()将预测掩码还原到原始影像尺寸geoai/sam.py掩码存于self.masks、IoU 置信度存于self.scores。此外tensor_to_numpy()geoai/sam.py可将预测掩码张量转为 numpy 数组默认取索引1的掩码按(i 1)为每个框对应的对象赋唯一值再二值化可用于后续可视化或保存。源码与测试佐证单元测试覆盖的契约tests/test_sam.py 以轻量方式验证了SamGeo的公共契约TestSamGeoClass验证类可导入、__init__签名包含model/automatic/device/sam_kwargs并断言默认值modelfacebook/sam-vit-huge、automaticTrue、deviceNone、sam_kwargsNoneTestSamGeoMethods断言generate、set_image、save_masks、predict等方法存在TestSamGeoAttributes通过 mockpipeline与torch.cuda.is_available验证初始化后model等属性被正确赋值测试环境加载模型失败是可接受的情形见测试内注释。实现要点小结从源码结构可以推断SamGeo的几项工程化设计延迟导入策略cv2在generate()/show_masks()内延迟导入matplotlib在show_masks()/show_anns()内延迟导入注释明确说明是为了避免与 QGIS 等宿主环境中的 OpenCV 版本冲突——这与仓库内 qgis_plugin 的集成场景吻合推理与 I/O 解耦generate()推理 保存、save_masks()纯保存与show_*纯可视化职责分离用户可灵活组合例如先生成掩码、调整save_masks参数重新输出不同形态的掩码而无需重新推理地理坐标到像素坐标的完整链路从矢量文件 / GeoJSON / 经纬度列表 → 坐标提取 → CRS 转换 → 像素坐标 → 模型输入全部在类内完成用户无需接触rasterio的坐标变换 API。总结geoai.sam模块以单个SamGeo类封装了 SAM 在地理空间数据上的完整使用链路自动模式适合大范围地物普查与整景分割提示模式适合指定目标的精准提取掩码输出支持唯一值、二值、前景/背景与边界提取等多种形态且自动携带地理参考配合raster_to_vector可一键将分割结果转换为矢量要素进入 GIS 分析流程。结合 geoai/utils 的坐标转换工具它甚至可以接受纯经纬度坐标作为点提示真正实现「地理坐标驱动」的提示分割。如需深入了解可继续阅读 geoai/sam.py 源码、docs/examples/samgeo.ipynb 完整示例以及 tests/test_sam.py 中定义的公共 API 契约。赞分享人工智能计算机视觉GIS图像处理微调【免费下载链接】geoaiGeoAI: Artificial Intelligence for Geospatial Data项目地址https://gitcode.com/gh_mirrors/ge/geoai点击查看免费下载相关推荐GeoAI 中的 RF-DETR地理空间影像目标检测与实例分割完整实战指南GeoAI 中的 RF DETR地理空间影像目标检测与实例分割完整实战指南 RF DETR 是 Roboflow 基于 DINOv2 与 DETR 架构推出的人工智能计算机视觉GIS图像处理微调GeoAI 云检测指南基于 OmniCloudMask 的卫星影像云与云影分割实战GeoAI 云检测指南基于 OmniCloudMask 的卫星影像云与云影分割实战 本文以 GeoAI 仓库中的 geoai.tools.cloudmask人工智能计算机视觉GIS图像处理微调GeoAI 地理空间 Embeddings 模块实战指南基于 TorchGeo 基础模型的影像特征提取、检索与分析GeoAI 地理空间 Embeddings 模块实战指南基于 TorchGeo 基础模型的影像特征提取、检索与分析 导读 GeoAI 项目的 embeddin人工智能计算机视觉GIS图像处理微调创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考