基于Gdal包在python中合成多波段图像,并给波段命名 [1]

在网上找资料的时候,发现了一位大神的个人网站(http://zhaoxuhui.top/),上面分享了许多有关地信知识的教程,非常inspiring,大家有兴趣的话可以去关注一下。但是,对于”基于Gdal包在python中合成多波段图像并给波段命名”的相关问题,我个人认为大神讲的有些绕。所以,此篇是对大神文章的进一步解释和总结(分别设定三个难度依次递增的情景)。我本身也只是一个初学者,疏漏之处在所难免,希望各位内行不要笑话,多多提建议,帮助小张提高自己!!!

本篇文章将不对gdal的基础语法进行过多的解释。不熟悉gdal的朋友们可以先看看犹他州里大学所编撰的这个手册(https://www.osgeo.cn/python_gdal_utah_tutorial/index.html#)。大概扫几眼后,就可以对gdal有个初步的认识。废话不再多说,进入正题。

情景:

一.现有多个单波段图像,需要将其合成为一个多波段图像并给每个波段命名

二.现有一个没有给每个波段命名的多波段图像,需要在原图形的基础上,给原图形的各波段命名

三.现有一个没有给每个波段命名的多波段图像,不能改变原图形,复制一个新图形后,再给新图形的各波段命名

———————————————————————————————————————————
一.现有多个单波段图像,需要将其合成为一个多波段图像并给每个波段命名
思路其实很简单。首先,生成一个“尺寸空间”等信息和单波段图像相同的“空的多波段图像”,然后逐个将单波段图像存储进“空的多波段图像”,同时给波段命名。例如,我们有有23张由modis13q1提取出的单波段ndvi图像(图一),现在想把他们合成为一张有名字的多波段的ndvi图像。让我们在代码中理解这个思路。

23张2001年的单波段NDVI图像

打开python,载入此操作需要的包

#####载入此操作需要的包#####
import glob
import os
import numpy as np
import pandas as pd
import os
import gdal
from osgeo import gdal
from gdalconst import *

定义一个返回为“栅格文件”,以及“栅格文件的一个band”的function

#返回的“栅格文件”以及”栅格文件的一个band”的信息将被用来创建“空的多波段图像”
#此function是直接用大神的,但其实可能很多人都用过类似的 
def get_dataset_band(bandfile):   
    input_dataset = gdal.Open(bandfile)
    input_band = input_dataset.GetRasterBand(1)
    return input_dataset, input_band

单波段NDVI数据,以及数据的名字分别储存在名为bandfilebandnames的list里

inws= "F:\\Modis\\NDVI" #请自行替换为自己单波段数据储存的位置    
NDVIS=glob.glob(os.path.join(inws, "*.tif")) 
bandfile = []  #bandfile为储存单波段NDVI数据的list
bandnames=[]  #bandnames为储存单波段NDVI数据名称的list,当然原名称太长,我们之后要改造
for ndvi in NDVIS:
       bandfile.append(ndvi)
       names=os.path.basename(ndvi).split('.')[0]+"_"+os.path.basename(ndvi).split('.')[1][1:8]+"_"+os.path.basename(ndvi).split('.')[2]+".tif" #对名字进行改造,这样的改造结果如'MOD13Q1_2011353_h25v04.tif'
       bandnames.append(names)

基于单波段的NDVI图像的信息创建空的多波段图像栅格文件

inputdata=[]
for i in range(len(bandfile)):
              inputdata.append(get_dataset_band(bandfile[i]))
inputdataset_1, inputband_1 = inputdata[0]  #inputdataset_1为栅格文件,inputband_1为栅格文件下波段的信息,之后我们要基于inputdataset_1和inputband_1这两个中间变量的信息(如尺寸,坐标等)来定义**空的多波段图像**栅格文件
#创建驱动
file_driver=gdal.GetDriverByName('Gtiff')
#定义**空的多波段图像**的存储路径
output_path="F:\\STSG\\reconstructedNDVI"
#定义**空的多波段图像**的名称
output_name="NDVI"+"_"+location+"_"+year
#创建**空的多波段图像**栅格文件
output_dataset = file_driver.Create(output_path+"\\"+output_name+".tif", inputband_1.XSize, inputband_1.YSize, 23, inputband_1.DataType)
#基于前述的栅格文件来定义**空的多波段图像**空间信息等等
output_dataset.SetProjection(inputdataset_1.GetProjection())
output_dataset.SetGeoTransform(inputdataset_1.GetGeoTransform())   

将23个单波段的NDVI逐个写入空的多波段图像栅格文件,并顺手建立一个同名的hdr头文件

for i in range(len(bandfile)):
     inputband_data = inputdata[i][1].ReadAsArray()
     raster_band =output_dataset.GetRasterBand(i + 1)
     raster_band.SetDescription(bandnames[i])  #写入各个波段的名字
     # 写入数据
     raster_band.WriteArray(inputband_data)
     output_dataset.BuildOverviews('average',[2,4,8,16,32])  #建立pyramid
     #截至到这里,数据以及名字都已经被写进**空的多波段图像**栅格文件里了,但是这样写入的名字无法在ENVI软件中被读取,所以还需要再顺手给这个**多波段图像**栅格文件写个hdr头文件
     # 写hdr头文件,bands_num(波段数)和bandnemes(波段名称)不能少;其他无所谓
     h1='ENVI'
     h2='description ={'
     h3='File Imported into ENVI. }'
     h4='img_width = '+str(inputband_1.XSize)    
     #inputband_1.XSize来求每一波段的列数,前面定义过
     h5='img_height = '+str(inputband_1.YSize)   
     #inputband_1.YSize来求每一波段的行数,前面定义过
     h6='bands = '+str(23)                               #23为波段数
     h7='header offset = 0'
     h8='file type =TIFF'
     h9='sensor type = Unknown'
     h10='band names = {'
     h11=','.join(bandnames)+'}'   #用这个join语句,删掉list两侧的[],以及波段名称两端的双引号""
     h=[h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11]
     doc = open(output_path+"\\"+output_name+".hdr", 'w')   
     for i in range (0,11):
              print(h[i], end='', file=doc)
              print('\n', end='', file=doc)
     doc.close()       
     #输出为同名的hdr头文件,并且此文件要与多波段栅格文件在一个文件夹里面。

让我们在ENVI中检验一下程序运行的结果,看是不是波段名称已经被写进去了

在ENVI中检验一下程序运行的结果,看是不是波段名称已经被写进去了

顺便看一看生成的hdr头文件的内容

看一看生成的hdr头文件的内容

总结
其实只是非常基础的一些地信知识,以及非常基础的python语句。希望可以帮助到像小张一样搞地貌水文环境等的学生们。写到这里感觉有点累了。今天就到此为止吧。(主要是急着去追综艺)情景二和三以后再更新。感谢阅读哈哈哈。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342