【PythonRS】基于GDAL修改栅格数据的DN值

        遥感工作者离不开栅格数据,有时候我们可能需要修改栅格数据的值,但ENVI和ArcGIS中并没有直接修改DN值的工具,只有栅格计算器、Band math这些工具去计算整个波段的值,或者Edit Classification Image工具可以修改ENVI分类后的像元值,但这个工具只对分类格式有效,博主整不明白怎么把单波段数据转为分类格式,所以这些工具都无法满足我们的需求。

        今天跟大家分享一下如何使用Python的GDAL库将栅格数据中特定的DN值修改成我们想要的。

一、安装库

import os
import numpy as np
from osgeo import gdal

二、读取栅格数据信息

        这一步可有可无,只是让你了解一下栅格数据的基本信息,如投影信息、长度、宽度等。

def Get_data(filepath):ds = gdal.Open(filepath)  # 打开数据集datasetds_width = ds.RasterXSize  # 获取数据宽度ds_height = ds.RasterYSize  # 获取数据高度ds_bands = ds.RasterCount  # 获取波段数ds_geo = ds.GetGeoTransform()  # 获取仿射地理变换参数ds_prj = ds.GetProjection()  # 获取投影信息print("影像的宽度为:" + str(ds_width))print("影像的高度为:" + str(ds_height))print("仿射地理变换参数为:" + str(ds_geo))print("投影坐标系为:" + str(ds_prj))# data = ds.ReadAsArray(0, 0, ds_width, ds_height)  # 以数组的形式读取整个数据集

三、修改DN值

        我这里写的函数,只适用于修改单波段的栅格影像,如果需要修改多波段就自己加一个循环。其实原理都一样,就是将波段读成数组,然后通过索引读取第几行第几列像元的值,然后判断这个值是否为你想要修改的值,如果是,就将其赋予新的值。

def Modify_value(filepath, out_path, original, target):print("-----正在进行DN值的修改-----")ds = gdal.Open(filepath)  # 打开数据集datasetds_width = ds.RasterXSize  # 获取数据宽度ds_height = ds.RasterYSize  # 获取数据高度ds_geo = ds.GetGeoTransform()  # 获取仿射地理变换参数ds_prj = ds.GetProjection()  # 获取投影信息array_band = ds.GetRasterBand(1).ReadAsArray(0, 0, ds_width, ds_height).astype(np.float64)# 读取第一个波段全部for row in range(0, ds_height):# 循环当前波段的行for col in range(0, ds_width):# 循环当前波段的列if array_band[row][col] == original:# 判断第row行第col列的DN值是否为需要修改的值array_band[row][col] = target# 修改该值else:continuedriver = gdal.GetDriverByName('GTiff')  # 载入数据驱动,用于存储内存中的数组ds_result = driver.Create(out_path, ds_width, ds_height, bands=1, eType=gdal.GDT_Float64)# 创建一个数组,宽高为原始尺寸ds_result.SetGeoTransform(ds_geo)  # 导入仿射地理变换参数ds_result.SetProjection(ds_prj)  # 导入投影信息ds_result.GetRasterBand(1).SetNoDataValue(0)  # 将无效值设为0ds_result.GetRasterBand(1).WriteArray(array_band)  # 将结果写入数组del ds_result# 删除内存中的结果,否则结果不会写入图像中print("计算完成")

四、完整代码

# -*- coding: utf-8 -*-
"""
@Time : 2023/9/8 8:51
@Auth : RS迷途小书童
@File :Modifying Raster Data DN Values.py
@IDE :PyCharm
@Purpose:修改栅格数据DN值
"""
import os
import numpy as np
from osgeo import gdaldef Get_data(filepath):ds = gdal.Open(filepath)  # 打开数据集datasetds_width = ds.RasterXSize  # 获取数据宽度ds_height = ds.RasterYSize  # 获取数据高度ds_bands = ds.RasterCount  # 获取波段数ds_geo = ds.GetGeoTransform()  # 获取仿射地理变换参数ds_prj = ds.GetProjection()  # 获取投影信息print("影像的宽度为:" + str(ds_width))print("影像的高度为:" + str(ds_height))print("仿射地理变换参数为:" + str(ds_geo))print("投影坐标系为:" + str(ds_prj))# data = ds.ReadAsArray(0, 0, ds_width, ds_height)  # 以数组的形式读取整个数据集def Modify_value(filepath, out_path, original, target):print("-----正在进行DN值的修改-----")ds = gdal.Open(filepath)  # 打开数据集datasetds_width = ds.RasterXSize  # 获取数据宽度ds_height = ds.RasterYSize  # 获取数据高度ds_geo = ds.GetGeoTransform()  # 获取仿射地理变换参数ds_prj = ds.GetProjection()  # 获取投影信息array_band = ds.GetRasterBand(1).ReadAsArray(0, 0, ds_width, ds_height).astype(np.float64)# 读取第一个波段全部for row in range(0, ds_height):# 循环当前波段的行for col in range(0, ds_width):# 循环当前波段的列if array_band[row][col] == original:# 判断第row行第col列的DN值是否为需要修改的值array_band[row][col] = target# 修改该值else:continuedriver = gdal.GetDriverByName('GTiff')  # 载入数据驱动,用于存储内存中的数组ds_result = driver.Create(out_path, ds_width, ds_height, bands=1, eType=gdal.GDT_Float64)# 创建一个数组,宽高为原始尺寸ds_result.SetGeoTransform(ds_geo)  # 导入仿射地理变换参数ds_result.SetProjection(ds_prj)  # 导入投影信息ds_result.GetRasterBand(1).SetNoDataValue(0)  # 将无效值设为0ds_result.GetRasterBand(1).WriteArray(array_band)  # 将结果写入数组del ds_result# 删除内存中的结果,否则结果不会写入图像中print("计算完成")if __name__ == "__main__":os.environ['PROJ_LIB'] = 'G:/Anaconda/envs/pyDL/Lib/site-packages/osgeo/data/proj'os.environ['GDAL_DATA'] = 'G:/Anaconda/envs/pyDL/Lib/site-packages/osgeo/data'# 添加PROJ至环境变量,消除警告file_path = r"B:\1m_xiugai.tif"  # 输入的栅格数据路径out_path1 = r"B:\1m_xiugai1.tif"  # 导出的文件路径data1 = int(input("请输入需要修改的DN值:"))data2 = int(input("请输入目标DN值     :"))Get_data(file_path)  # 执行函数,获取影像基本信息print("\n")print("--------------DN值修改--------------")Modify_value(file_path, out_path1, data1, data2)  # 执行函数,修改DN值

        今天的分享就到这里了,大家需要注意的是,我这段代码只适用于单波段数据且想要修改的值只有一种时,如你想要将所有DN值等于1的像元全部改成0,就可以直接使用我的点吗改数据路径,然后再输入1和0就可以了(因为我的任务就是将分类数据(DN值为0,1,2,3,4)中分错的部分改成正确的)。不要问为什么不使用工具,因为我手里的分类数据不是ENVI支持的分类格式(泪目)。

        如果大家在学习Python或者RS时有什么问题,可以随时留言交流!如果大家对批量处理有兴趣同样可以留言给博主,博主会分享相关代码以供学习!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/73056.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

查看视频文件关键帧间隔

一、Elecard StreamEye Tools拖放视频文件查看。 红的是I帧;蓝的是P帧;绿的是B帧。 二、ffprobe -show_streams统计。 1、统计视频关键帧、非关键帧 ffprobe.exe -i 1.mp4 -show_streams v -show_packets -print_format json > d:\1.json 再统计1.j…

[SSM]MyBatisPlus拓展

五、拓展篇 5.1逻辑删除 在电商网站中,我们会上架很多商品,这些商品下架以后,我们如果将这些商品从数据库中删除,那么在年底统计商品的时候,这个商品要统计的,所以这个商品信息我们是不能删除的。 如果商城…

如何判断bug是前端bug还是后端bug

1.前后端bug 特征: 前端主要负责显示数据,后端主要负责处理数据、存储数据,前后端主要通过接口进行数据交换。 前端bug的特征: 界面显示类问题:如文字大小不一,控件颜色不搭,控件不整齐&#x…

分布式锁怎么抗高并发 redis

比如,多个人下单某一个商品 怎么处理 分段加锁 合并扣减。 这里首先要让redis是集群,避开单机性能问题。 大概意思就是将商品分摊到多个服务器上,这样就减轻了单台的压力

网桥、路由器和网关有什么区别?

网桥、路由器和网关是网络设备中的三种重要类型,在OSI模型中,它们分别位于不同的层次。 网桥:工作在OSI模型的第二层,即数据链路层。网桥的主要功能是根据MAC地址转发和过滤帧,当帧到达网桥的接口,网桥不…

Chat GPT 使用教学,文字创作、学习

目录 文章长篇文章学习任何东西文章 大纲、目录、标题、内容 写出10个即将被AI取代的工作的文章标题 当然,以下是一些可能会被AI取代的工作的文章标题:"未来十年,AI将如何改变传统制造业的就业格局?" "智能客服崛起:人工智能如何重塑客户服务行业?"…

EXPLAIN概述与字段剖析

6. 分析查询语句:EXPLAIN(重点) 6.1 概述 定位了查询慢的sQL之后,我们就可以使用EXPLAIN或DESCRIBE 工具做针对性的分析查询语句。DESCRIBE语句的使用方法与EXPLAIN语句是一样的,并且分析结果也是一样的。 MySQL中有专门负责优化SELECT语句…

Alins - 化繁为简、极致优雅的WebUI框架

最近造了个js框架 Alins,分享一下: 🚀 Alins: 最纯粹优雅的WebUI框架 English | 文档 | 演练场 | 更新日志 | 反馈错误/缺漏 | Gitee | 留言板 0 简介 0.1 前言 Alins是一款极致纯粹、简洁、优雅的Web UI框架。秉持0-API、Less is More 的…

代理模式简介

概念: 代理模式(Proxy Pattern)是一种结构型设计模式,它允许通过创建一个代理对象来控制对原始对象的访问。代理对象充当了客户端和目标对象之间的中介,可以在不改变目标对象的情况下增加额外的功能或限制访问。 特点…

wx:for 微信小程序双重for嵌套如何获取内层的迭代对象

wx:for 微信小程序双重for嵌套如何获取内层的迭代对象 思路就是&#xff0c;外层for直接通过默认的item进行迭代&#xff0c;然后内层的for&#xff0c;通过wx:for-item"xxx"的方式指定内部迭代名称。 <view wx:for"{{modulesList}}" ><text>{…

【操作系统】电脑上没有IIS怎么办

文章目录 前言一、查看二、解决 前言 有的新机刚开始在计算机-管理-服务下没有IIS网络服务怎么办。 一、查看 桌面计算机/此电脑 鼠标右键&#xff1a;管理 服务和应用 发现没有IIS 二、解决 控制面板 程序和功能 启动或关闭Windows功能 IIS相关的所有功能选中&#xff…

鼠标键盘自动化工具pyautogui

安装 pip install pyautogui pip install keyboard获取鼠标实时位置 import pyautogui pyautogui.displayMousePosition()样例代码 # https://pyautogui.readthedocs.org/ # https://github.com/asweigart/pyautogui# 紧急停止&#xff0c;手动将鼠标移动到屏幕的4个角落imp…

2023年9月8日

1> 自行封装一个栈的类&#xff0c;包含私有成员属性&#xff1a;栈的数组、记录栈顶的变量 成员函数完成&#xff1a;构造函数、析构函数、拷贝构造函数、入栈、出栈、清空栈、判空、判满、获取栈顶元素、求栈的大小 #include <iostream>using namespace std;class…

selenium的Chrome116版驱动下载

这里写自定义目录标题 下载地址https://googlechromelabs.github.io/chrome-for-testing/#stable 选择chromedriver 对应的平台和版本 国内下载地址 https://download.csdn.net/download/dongtest/88314387

hive 分隔符

在 Hive 中,分隔符用于指定数据文件中字段之间的分隔符。当你创建外部表或加载数据文件时,你可以指定分隔符,以便 Hive 正确地解析文件中的数据。 1. 创建外部表时指定分隔符: 当你创建外部表时,可以使用 ROW FORMAT 子句来指定数据文件中字段的分隔符。例如,如果你的数…

WorkPlus AI助理,基于ChatGPT的企业级知识问答机器人

随着人工智能技术的发展&#xff0c;WorkPlus AI助理以ChatGPT对话能力为基础&#xff0c;将企业数据与人工智能相结合&#xff0c;推出了面向企业的知识问答机器人。这一创新性的解决方案帮助企业高效管理和利用自身的知识资产&#xff0c;助力企业级人工智能的构建。与传统的…

【MySQL】数据库的约束

MySQL 数据库的约束 文章目录 MySQL 数据库的约束01 数据库的约束1.1 约束类型1.1.1 NOT NULL1.1.2 UNIQUE1.1.3 DEFAULT1.1.4 PRIMARY KEY1.1.5 FOREIGN KEY1.1.6 CHECK 继上文 MySQL基础&#xff08;一&#xff09;&#xff0c; MySQL基础&#xff08;二&#xff09;&#…

介绍串行和并行两种通信方式

前言 参考文章&#xff1a; 串行和并行- CSDN搜索 并行传输和串行传输的区别_金陵大掌柜的博客-CSDN博客 串行和并行介绍 &#xff08;1&#xff09;串行和并行是计算机领域中两个重要的概念。串行是指在计算机中&#xff0c;任务按照顺序一个一个执行&#xff0c;每个任务执行…

详解初阶数据结构之顺序表(SeqList)——单文件文件实现SeqList的增删查改

目录 一、线性表 二、顺序表 2.1概念及结构 2.2接口实现 2.3动态顺序表的创建 2.3动态顺序表的初始化 2.3.1传值初始化 2.3.2传址初始化 2.4动态顺序表的清空 2.5动态顺序表的扩容 2.6动态顺序表内容的打印 三、动态顺序表的使用 3.1尾插尾删 3.1.1尾插 3.1.2尾删…

基于Bert+Attention+LSTM智能校园知识图谱问答推荐系统——NLP自然语言处理算法应用(含Python全部工程源码及训练模型)+数据集

目录 前言总体设计系统整体结构图系统流程图 运行环境Python 环境服务器环境 模块实现1. 构造数据集2. 识别网络3. 命名实体纠错4. 检索问题类别5. 查询结果 系统测试1. 命名实体识别网络测试2. 知识图谱问答系统整体测试 工程源代码下载其它资料下载 前言 这个项目充分利用了…