当前位置: 首页 > news >正文

处理 DEM 数据 0 值插值的 Python 代码

以下代码基于rasterio读取 / 写入 TIFF、scipy实现插值,可对 DEM 中的 0 值(异常值)进行邻近插值或反距离加权插值(IDW)修复。

步骤说明:
  1. 读取 DEM 数据,提取有效数据(非 0 值)和待插值的 0 值位置;
  2. 可选两种插值方式:邻近插值(快速)、反距离加权插值(更平滑);
  3. 插值修复 0 值区域后,保存为新的 TIFF 文件;
  4. 增加数据范围校验(确保插值结果在合理区间)。
import numpy as np import rasterio from scipy.interpolate import NearestNDInterpolator, RBFInterpolator from rasterio.transform import from_origin def repair_dem_zero_values(input_tif, output_tif, method="nearest", power=2): """ 修复DEM中0值(异常值)的函数 :param input_tif: 输入DEM文件路径(dem.tif) :param output_tif: 输出修复后的DEM文件路径 :param method: 插值方法,可选 "nearest"(邻近插值)或 "idw"(反距离加权) :param power: IDW插值的幂次(默认2,值越大近点权重越高) """ # 1. 读取DEM数据 with rasterio.open(input_tif) as src: dem_data = src.read(1) # 读取第一波段 profile = src.profile # 获取影像元数据(投影、分辨率、变换等) transform = src.transform # 地理变换参数 nodata = src.nodata # 原始nodata值(若有) # 2. 标记有效数据和待插值位置 # 有效数据:非0值(0为异常值),且在合理范围0-5500m valid_mask = (dem_data != 0) & (dem_data >= 0) & (dem_data <= 5500) # 待插值位置:0值且在影像范围内 interpolate_mask = dem_data == 0 # 检查是否有需要插值的点 if not np.any(interpolate_mask): print("无0值需要插值,直接保存原始数据") with rasterio.open(output_tif, "w", **profile) as dst: dst.write(dem_data, 1) return # 3. 提取有效数据的坐标和值 # 获取行列坐标(可转换为地理坐标,此处用行列坐标插值更高效) rows, cols = np.meshgrid(np.arange(dem_data.shape[0]), np.arange(dem_data.shape[1]), indexing="ij") # 有效数据的行列坐标 valid_rows = rows[valid_mask] valid_cols = cols[valid_mask] valid_values = dem_data[valid_mask] # 待插值的行列坐标 interp_rows = rows[interpolate_mask] interp_cols = cols[interpolate_mask] # 组合坐标为N×2的数组(适配scipy插值接口) valid_points = np.column_stack((valid_rows, valid_cols)) interp_points = np.column_stack((interp_rows, interp_cols)) # 4. 执行插值 if method == "nearest": # 邻近插值(快速,适合大区域) interpolator = NearestNDInterpolator(valid_points, valid_values) interp_values = interpolator(interp_points) elif method == "idw": # 反距离加权插值(更平滑,计算稍慢) # 用RBFInterpolator模拟IDW:函数类型选"inverse_multiquadric"等价IDW interpolator = RBFInterpolator( valid_points, valid_values, function="inverse_multiquadric", smoothing=0, # 无平滑,纯IDW kernel_size=None ) # 计算IDW权重(幂次power) interp_values = interpolator(interp_points, norm=power) else: raise ValueError("method仅支持 'nearest' 或 'idw'") # 5. 修正插值结果(确保在0-5500m范围内) interp_values = np.clip(interp_values, 0, 5500) # 6. 替换0值为插值结果 dem_repaired = dem_data.copy() dem_repaired[interpolate_mask] = interp_values # 7. 保存修复后的DEM with rasterio.open(output_tif, "w", **profile) as dst: dst.write(dem_repaired, 1) print(f"修复完成!输出文件:{output_tif}") print(f"插值点数:{len(interp_values)}") print(f"有效数据占比:{np.sum(valid_mask)/dem_data.size*100:.2f}%") # -------------------------- 调用示例 -------------------------- if __name__ == "__main__": # 输入输出路径(根据实际情况修改) input_dem = "dem.tif" # 原始DEM文件 output_dem = "dem_repaired.tif" # 修复后的DEM文件 # 方法1:邻近插值(快速,推荐先试用) repair_dem_zero_values(input_dem, output_dem, method="nearest") # 方法2:反距离插值(更平滑,计算稍慢) # repair_dem_zero_values(input_dem, output_dem, method="idw", power=2)

依赖安装

执行代码前需安装以下库:

pip install rasterio scipy numpy

关键参数说明

  1. method
    • nearest:邻近插值,速度极快,结果为最近有效像素的值,适合快速修复;
    • idw:反距离加权插值,结果更平滑,符合地形连续性,适合对精度要求高的场景。
  2. power(仅 IDW):反距离的幂次,默认 2,值越大,近点对插值结果的影响越大(通常取 1-3)。
  3. clip:强制插值结果在 0-5500m 范围内,避免插值出现异常值。

注意事项

  1. 若 DEM 中 0 值区域过大(无邻近有效数据),插值结果可能不准确,建议先检查数据有效性;
  2. 地理坐标插值:若需基于经纬度 / 投影坐标插值,可将rows/cols转换为地理坐标(通过transform参数),代码中已预留地理变换接口;
  3. 大文件优化:若 DEM 文件超大(如 GB 级),可分块处理(参考rasteriowindow功能),避免内存溢出。

验证结果

修复后可通过以下方式验证:

# 读取修复后的数据,检查0值是否被替换 with rasterio.open("dem_repaired.tif") as src: data = src.read(1) print(f"修复后0值数量:{np.sum(data == 0)}") print(f"数据范围:{np.min(data)} - {np.max(data)}")
http://www.cnnetsun.cn/news/137003.html

相关文章:

  • 数字孪生可视化模板怎么用?5大行业Demo拆解,帮你快速复用提效
  • 必藏!程序员转型AI大模型:机遇、路径与成功率拆解
  • 《智构空间:AIOS 与全时域 3D 交互范式》第 0 篇:前言 —— 触摸语义的厚度
  • 如何将照片从 Android 传输到 Android
  • 前端Vue使用js-audio-plugin实现录音功能
  • 测试用例之翻页功能详解
  • 音乐平台歌曲盗版维权全攻略:权利卫士录屏取证+可信时间戳认证实操指南
  • 根据您提供的 package.json 片段,涉及的 @vue/cli-plugin-babel 和 @vue/cli-service 版本为 ~4.2.0。以下是针对该版本的详细解决方案,结合相关依
  • electron-egg打包win7
  • 8种网络故障分析及测试命令大全
  • 新人必看盘点知名CTF练习靶场,从零基础入门到精通,收藏这一篇就够了!
  • Pythonselenium自动化测试实战项目
  • 关于Comtos Linux (朱雀)主体源码的选择
  • 超级Mini小车功能说明
  • STC32G12单片机替换成STC32F12单片机,直接替换的结果
  • SIEMENS 6SL3210-1PE33-0CL0 变频器
  • 软件测试常用的7种方法,最后一个是升职加薪关键!(零基础小白转行IT互联网高效进阶)
  • 【RTOS】EasyLog的移植与使用
  • 在数据库里玩“平行宇宙”:MatrixOne Data Branch 让数据也拥有Git 的分支/合并/对比/回滚(含跨集群同步)
  • 基于单片机的全自动洗衣机系统的设计
  • 5.6 模型部署与智能体集成实战
  • 基于单片机的球赛计分牌的设计
  • ArcGIS Pro 从入门到实战基础篇(10):地图菜单
  • Kotaemon与Redis/Memcached集成:构建高速缓存层
  • 【鸿蒙三方库编译】lycium_plusplus(lycium++)高效完成鸿蒙C/C++编译
  • 2025年度GEO服务商权威甄选指南:技术深度与商业价值的双重考量
  • 收藏备用!Java程序员转AI大模型:从技术沉淀到AI爆发的进阶之路
  • Python 爬虫实战:Session 会话维持爬取需登录内容
  • 基于移相全桥变换器的电池充电仿真模型,采用电压电流双闭环PI控制。 电池先经历CC模式而后进入...
  • 基于COMSOL模拟的水力压裂技术研究:固体力学与达西定理的应用