1.问题由来
在对MODIS数据进行FLAASH大气校正后,本想查看一下校正后的波谱曲线,但是在ENVI中的打开结果却是:
由于MODIS的波段没有按照波长进行存储,因此出现了以上的情况。为了更方便的查看波谱曲线,这里使用Python+GDAL对MODIS数据进行波段顺序调整。
2.调整顺序的程序
代码根据波长进行顺序调整,并且输出了新的文件。详细介绍见注释。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | from osgeo import gdal import numpy as np from osgeo.gdal import GDT_Float32 driver = gdal.GetDriverByName("ENVI") origfilename='F:/SomeData/MODIS/Reflectence4/MOD021KM.A2020134.0235_ref4.dat' #原始文件 savefilename='F:/SomeData/MODIS/Reflectence4/MOD021KM.A2020134.0235_ref44.dat' #处理后文件 origdataset = gdal.Open(origfilename) im_width=origdataset.RasterXSize #列 im_height=origdataset.RasterYSize #行 bandcount=origdataset.RasterCount #波段数 datatype=GDT_Float32 #设置输出文件的数据类型 metadatalist=[] #记录原始数据中的metadata descriptionlist=[] #记录原始数据中的description bl=[] #记录原始数据中的波长 alldata=np.zeros((bandcount,im_height,im_width)) #记录原始影像的所有数据 for i in range(1,bandcount+1): #波段顺序,从1开始 origband=origdataset.GetRasterBand(i) #获取波段 metadatalist.append(origband.GetMetadata()) #波段的metadata bl.append(float(origband.GetMetadata()['wavelength'])) #metadata中波长的信息 descriptionlist.append(origband.GetDescription()) #波段的description信息 alldata[i-1]=origband.ReadAsArray()*0.0001 #数据矩阵,用来保存数据的矩阵的索引从0开始 这里做了一个计算 nbl=np.asarray(bl).argsort() #波长按照从小到大的顺序排列,返回索引号 savedataset=driver.Create(savefilename,im_width,im_height,bandcount,datatype) #构建输出数据集 hdrtxt='wavelength = {' #准备向hdr文件中写入的波长信息 for j in range(1,bandcount+1): saveband=savedataset.GetRasterBand(j) #设置输出数据的波段信息 saveband.WriteArray(alldata[nbl[j-1]],0,0) saveband.SetMetadata(metadatalist[nbl[j-1]]) saveband.SetDescription(descriptionlist[nbl[j-1]]) hdrtxt=hdrtxt+str(bl[nbl[j-1]])+',' hdrtxt=hdrtxt[:-1]+'}' #丢弃最后一个逗号,否则ENVI打开会报警告 savedataset.SetGeoTransform(origdataset.GetGeoTransform()) #设置输出数据集的地理信息,与原始文件一致 savedataset.SetProjection(origdataset.GetProjection()) del savedataset savefilehdr='.'.join(savefilename.split('.')[:-1])+'.hdr' with open(savefilehdr,'a+') as sfh: sfh.writelines(hdrtxt) #在hdr文件中加入一行关于波长的信息 |
程序运行后,输出数据在ENVI中打开,可查看到按波长大小排列的正常波谱曲线:
3.程序说明
1.在编程时发现:SetMetadata()方法无法将原始的波长信息写入’.hdr’文件中(写入的信息会在程序生成的‘.xml’文件中出现)。这样的话,使用ENVI无法读取生成数据的波长信息,在查看波谱曲线的时候,x轴也不会代表波长。所以本人在程序中设有一个字符串变量hdrtxt,该变量是为了在生成的‘.hdr’文件中加入波长信息。该操作本人暂未找到替代的方法,希望大家不吝赐教。
2.在hdrtxt字符串变量中,本来最后一个波长后还有一个逗号。如果加了该逗号,在ENVI中打开数据时,就会出现警告(如图)。因此要把最后一个逗号去掉。
3.关于在MODIS数据中的Band_13lo、Band_13hi、Band_14lo、Band_14hi的解释,可以参见:https://oceancolor.gsfc.nasa.gov/forum/oceancolor/topic_show.pl?tid=2859