網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
Python利用GDAL模塊實(shí)現(xiàn)讀取柵格數(shù)據(jù)并對(duì)指定數(shù)據(jù)加以篩選掩膜_python
作者:瘋狂學(xué)習(xí)GIS ? 更新時(shí)間: 2023-06-05 編程語(yǔ)言本文介紹基于Python語(yǔ)言中gdal
模塊,對(duì)遙感影像數(shù)據(jù)進(jìn)行柵格讀取與計(jì)算,同時(shí)基于QA波段對(duì)像元加以篩選、掩膜的操作。
本文所要實(shí)現(xiàn)的需求具體為:現(xiàn)有自行計(jì)算的全球葉面積指數(shù)(LAI).tif
格式柵格產(chǎn)品(下稱“自有產(chǎn)品”),為了驗(yàn)證其精確度,需要與已有學(xué)者提出的成熟產(chǎn)品——GLASS全球LAI.hdf
格式柵格產(chǎn)品(下稱“GLASS產(chǎn)品”)進(jìn)行做差對(duì)比;其中,自有產(chǎn)品除了LAI波段外,還有一個(gè)質(zhì)量評(píng)估波段(QA),即自有產(chǎn)品在后期使用時(shí),還需結(jié)合QA波段進(jìn)行篩選、掩膜等處理。其中,二者均為基于MODIS?hv
分幅的產(chǎn)品。
本文分為兩部分,第一部分為代碼的詳細(xì)分段講解,第二部分為完整代碼。
1 代碼分段講解
1.1 模塊與路徑準(zhǔn)備
首先,需要對(duì)用到的模塊與存放柵格圖像的各類路徑加以準(zhǔn)備。
import os import copy import numpy as np import pylab as plt from osgeo import gdal # rt_file_path="G:/Postgraduate/LAI_Glass_RTlab/Rc_Lai_A2018161_h12v03.tif" # gl_file_path="G:/Postgraduate/LAI_Glass_RTlab/GLASS01E01.V50.A2018161.h12v03.2020323.hdf" # out_file_path="G:/Postgraduate/LAI_Glass_RTlab/test.tif" rt_file_path="I:/LAI_RTLab/A2018161/" gl_file_path="I:/LAI_Glass/2018161/" out_file_path="I:/LAI_Dif/"
其中,rt_file_path
為自有產(chǎn)品的存放路徑,gl_file_path
為GLASS產(chǎn)品的存放路徑,out_file_path
為最終二者柵格做完差值處理后結(jié)果的存放路徑。
1.2 柵格圖像文件名讀取與配對(duì)
接下來(lái),需要將全部待處理的柵格圖像用os.listdir()
進(jìn)行獲取,并用for
循環(huán)進(jìn)行循環(huán)批量處理操作的準(zhǔn)備。
rt_file_list=os.listdir(rt_file_path) for rt_file in rt_file_list: file_name_split=rt_file.split("_") rt_hv=file_name_split[3][:-4] gl_file_list=os.listdir(gl_file_path) for gl_file in gl_file_list: if rt_hv in gl_file: rt_file_tif_path=rt_file_path+rt_file gl_file_tif_path=gl_file_path+gl_file
其中,由于本文需求是對(duì)兩種產(chǎn)品做差,因此首先需要結(jié)合二者的hv
分幅編號(hào),將同一分幅編號(hào)的兩景遙感影像放在一起;因此,依據(jù)自有產(chǎn)品文件名的特征,選擇.split()
進(jìn)行字符串分割,并隨后截取獲得遙感影像的hv
分幅編號(hào)。
1.3 輸出文件名稱準(zhǔn)備
前述1.1部分已經(jīng)配置好了輸出文件存放的路徑,但是還沒(méi)有進(jìn)行輸出文件文件名的配置;因此這里我們需要配置好每一個(gè)做差后的遙感影像的文件存放路徑與名稱。其中,我們就直接以遙感影像的hv
編號(hào)作為輸出結(jié)果文件名。
DRT_out_file_path=out_file_path+"DRT/" if not os.path.exists(DRT_out_file_path): os.makedirs(DRT_out_file_path) DRT_out_file_tif_path=os.path.join(DRT_out_file_path,rt_hv+".tif") eco_out_file_path=out_file_path+"eco/" if not os.path.exists(eco_out_file_path): os.makedirs(eco_out_file_path) eco_out_file_tif_path=os.path.join(eco_out_file_path,rt_hv+".tif") wat_out_file_path=out_file_path+"wat/" if not os.path.exists(wat_out_file_path): os.makedirs(wat_out_file_path) wat_out_file_tif_path=os.path.join(wat_out_file_path,rt_hv+".tif") tim_out_file_path=out_file_path+"tim/" if not os.path.exists(tim_out_file_path): os.makedirs(tim_out_file_path) tim_out_file_tif_path=os.path.join(tim_out_file_path,rt_hv+".tif")
這一部分代碼分為了四個(gè)部分,是因?yàn)樽杂挟a(chǎn)品的LAI是分別依據(jù)四種算法得到的,在做差時(shí)需要每一種算法分別和GLASS產(chǎn)品進(jìn)行相減,因此配置了四個(gè)輸出路徑文件夾。
1.4 柵格文件數(shù)據(jù)與信息讀取
接下來(lái),利用gdal
模塊對(duì).tif
與.hdf
等兩種柵格圖像加以讀取。
rt_raster=gdal.Open(rt_file_path+rt_file) rt_band_num=rt_raster.RasterCount rt_raster_array=rt_raster.ReadAsArray() rt_lai_array=rt_raster_array[0] rt_qa_array=rt_raster_array[1] rt_lai_band=rt_raster.GetRasterBand(1) # rt_lai_nodata=rt_lai_band.GetNoDataValue() # rt_lai_nodata=32767 # rt_lai_mask=np.ma.masked_equal(rt_lai_array,rt_lai_nodata) rt_lai_array_mask=np.where(rt_lai_array>30000,np.nan,rt_lai_array) rt_lai_array_fin=rt_lai_array_mask*0.001 gl_raster=gdal.Open(gl_file_path+gl_file) gl_band_num=gl_raster.RasterCount gl_raster_array=gl_raster.ReadAsArray() gl_lai_array=gl_raster_array gl_lai_band=gl_raster.GetRasterBand(1) gl_lai_array_mask=np.where(gl_lai_array>1000,np.nan,gl_lai_array) gl_lai_array_fin=gl_lai_array_mask*0.01 row=rt_raster.RasterYSize col=rt_raster.RasterXSize geotransform=rt_raster.GetGeoTransform() projection=rt_raster.GetProjection()
首先,以上述代碼的第一段為例進(jìn)行講解。其中,gdal.Open()
讀取柵格圖像;.RasterCount
獲取柵格圖像波段數(shù)量;.ReadAsArray()
將柵格圖像各波段的信息讀取為Array
格式,當(dāng)波段數(shù)量大于1
時(shí),其共有三維,第一維為波段的個(gè)數(shù);rt_raster_array[0]
表示取Array
中的第一個(gè)波段,在本文中也就是自有產(chǎn)品的LAI波段;rt_qa_array=rt_raster_array[1]
則表示取出第二個(gè)波段,在本文中也就是自有產(chǎn)品的QA波段;.GetRasterBand(1)
表示獲取柵格圖像中的第一個(gè)波段(注意,這里序號(hào)不是從0
開(kāi)始而是從1
開(kāi)始);np.where(rt_lai_array>30000,np.nan,rt_lai_array)
表示利用np.where()
函數(shù)對(duì)Array
中第一個(gè)波段中像素>30000
加以選取,并將其設(shè)置為nan
,其他值不變。這一步驟是消除圖像中填充值、Nodata
值的方法。最后一句*0.001
是將圖層原有的縮放系數(shù)復(fù)原。
其次,上述代碼第三段為獲取柵格行、列數(shù)與投影變換信息。
1.5 差值計(jì)算與QA波段篩選
接下來(lái),首先對(duì)自有產(chǎn)品與GLASS產(chǎn)品加以做差操作,隨后需要對(duì)四種算法分別加以提取。
lai_dif=rt_lai_array_fin-gl_lai_array_fin lai_dif=lai_dif*1000 rt_qa_array_bin=copy.copy(rt_qa_array) rt_qa_array_row,rt_qa_array_col=rt_qa_array.shape for i in range(rt_qa_array_row): for j in range(rt_qa_array_col): rt_qa_array_bin[i][j]="{:012b}".format(rt_qa_array_bin[i][j])[-4:] # DRT_pixel_pos=np.where((rt_qa_array_bin>=100) & (rt_qa_array_bin==11)) # eco_pixel_pos=np.where((rt_qa_array_bin<100) & (rt_qa_array_bin==111)) # wat_pixel_pos=np.where((rt_qa_array_bin<1000) & (rt_qa_array_bin==1011)) # tim_pixel_pos=np.where((rt_qa_array_bin<1100) & (rt_qa_array_bin==1111)) # colormap=plt.cm.Greens # plt.figure(1) # # plt.subplot(2,4,1) # plt.imshow(rt_lai_array_fin,cmap=colormap,interpolation='none') # plt.title("RT_LAI") # plt.colorbar() # plt.figure(2) # # plt.subplot(2,4,2) # plt.imshow(gl_lai_array_fin,cmap=colormap,interpolation='none') # plt.title("GLASS_LAI") # plt.colorbar() # plt.figure(3) # dif_colormap=plt.cm.get_cmap("Spectral") # plt.imshow(lai_dif,cmap=dif_colormap,interpolation='none') # plt.title("Difference_LAI (RT-GLASS)") # plt.colorbar() DRT_lai_dif_array=np.where((rt_qa_array_bin>=100) | (rt_qa_array_bin==11), np.nan,lai_dif) eco_lai_dif_array=np.where((rt_qa_array_bin<100) | (rt_qa_array_bin==111), np.nan,lai_dif) wat_lai_dif_array=np.where((rt_qa_array_bin<1000) | (rt_qa_array_bin==1011), np.nan,lai_dif) tim_lai_dif_array=np.where((rt_qa_array_bin<1100) | (rt_qa_array_bin==1111), np.nan,lai_dif) # plt.figure(4) # plt.imshow(DRT_lai_dif_array) # plt.colorbar() # plt.figure(5) # plt.imshow(eco_lai_dif_array) # plt.colorbar() # plt.figure(6) # plt.imshow(wat_lai_dif_array) # plt.colorbar() # plt.figure(7) # plt.imshow(tim_lai_dif_array) # plt.colorbar()
其中,上述代碼前兩句為差值計(jì)算與數(shù)據(jù)化整。將數(shù)據(jù)轉(zhuǎn)換為整數(shù),可以減少結(jié)果數(shù)據(jù)圖層的數(shù)據(jù)量(因?yàn)椴恍枰鎯?chǔ)小數(shù)了)。
隨后,開(kāi)始依據(jù)QA波段進(jìn)行數(shù)據(jù)篩選與掩膜。其實(shí)各類遙感影像(例如MODIS、Landsat等)的QA波段都是比較近似的:通過(guò)一串二進(jìn)制碼來(lái)表示遙感影像的質(zhì)量、信息等,其中不同的比特位往往都代表著一種特性。例如下圖所示為Landsat Collection 2 Level-2的QA波段含義。
在這里,QA波段原本為十進(jìn)制(一般遙感影像為了節(jié)省空間,QA波段都是寫(xiě)成十進(jìn)制的形式),因此需要將其轉(zhuǎn)換為二進(jìn)制;隨后通過(guò)獲取指定需要的二進(jìn)制數(shù)據(jù)位數(shù)(在本文中也就是能確定自有產(chǎn)品中這一像素來(lái)自于哪一種算法的二進(jìn)制位數(shù)),從而判斷這一像素所得LAI是通過(guò)哪一種算法得到的,從而將每種算法對(duì)應(yīng)的像素分別放在一起處理。DRT_lai_dif_array
等四個(gè)變量分別表示四種算法中,除了自己這一種算法得到的像素之外的其他所有像素;之所以選擇這種方式,是因?yàn)楹笃谖覀兛梢詫⑵渲苯友谀さ簦敲词O碌木褪沁@種算法自身的像素了。
其中,上述代碼注釋掉的plt
相關(guān)內(nèi)容可以實(shí)現(xiàn)繪制空間分布圖,大家感興趣可以嘗試使用。
1.6 結(jié)果柵格文件寫(xiě)入與保存
接下來(lái),將我們完成上述差值計(jì)算與依據(jù)算法進(jìn)行篩選后的圖像保存。
driver=gdal.GetDriverByName("Gtiff") out_DRT_lai=driver.Create(DRT_out_file_tif_path,row,col,1,gdal.GDT_Float32) out_DRT_lai.SetGeoTransform(geotransform) out_DRT_lai.SetProjection(projection) out_DRT_lai.GetRasterBand(1).WriteArray(DRT_lai_dif_array) out_DRT_lai=None driver=gdal.GetDriverByName("Gtiff") out_eco_lai=driver.Create(eco_out_file_tif_path,row,col,1,gdal.GDT_Float32) out_eco_lai.SetGeoTransform(geotransform) out_eco_lai.SetProjection(projection) out_eco_lai.GetRasterBand(1).WriteArray(eco_lai_dif_array) out_eco_lai=None driver=gdal.GetDriverByName("Gtiff") out_wat_lai=driver.Create(wat_out_file_tif_path,row,col,1,gdal.GDT_Float32) out_wat_lai.SetGeoTransform(geotransform) out_wat_lai.SetProjection(projection) out_wat_lai.GetRasterBand(1).WriteArray(wat_lai_dif_array) out_wat_lai=None driver=gdal.GetDriverByName("Gtiff") out_tim_lai=driver.Create(tim_out_file_tif_path,row,col,1,gdal.GDT_Float32) out_tim_lai.SetGeoTransform(geotransform) out_tim_lai.SetProjection(projection) out_tim_lai.GetRasterBand(1).WriteArray(tim_lai_dif_array) out_tim_lai=None print(rt_hv)
其中,.GetDriverByName("Gtiff")
表示保存為.tif
格式的GeoTIFF文件;driver.Create(DRT_out_file_tif_path,row,col,1,gdal.GDT_Float32)
表示按照路徑、行列數(shù)、波段數(shù)與數(shù)據(jù)格式等建立一個(gè)新的柵格圖層,作為輸出圖層的框架;其后表示分別將地理投影轉(zhuǎn)換信息與像素具體數(shù)值分別賦予這一新建的柵格圖層;最后=None
表示將其從內(nèi)存空間中釋放,完成寫(xiě)入與保存工作。
2 完整代碼
本文所需完整代碼如下:
# -*- coding: utf-8 -*- """ Created on Thu Jul 15 19:36:15 2021 @author: fkxxgis """ import os import copy import numpy as np import pylab as plt from osgeo import gdal # rt_file_path="G:/Postgraduate/LAI_Glass_RTlab/Rc_Lai_A2018161_h12v03.tif" # gl_file_path="G:/Postgraduate/LAI_Glass_RTlab/GLASS01E01.V50.A2018161.h12v03.2020323.hdf" # out_file_path="G:/Postgraduate/LAI_Glass_RTlab/test.tif" rt_file_path="I:/LAI_RTLab/A2018161/" gl_file_path="I:/LAI_Glass/2018161/" out_file_path="I:/LAI_Dif/" rt_file_list=os.listdir(rt_file_path) for rt_file in rt_file_list: file_name_split=rt_file.split("_") rt_hv=file_name_split[3][:-4] gl_file_list=os.listdir(gl_file_path) for gl_file in gl_file_list: if rt_hv in gl_file: rt_file_tif_path=rt_file_path+rt_file gl_file_tif_path=gl_file_path+gl_file DRT_out_file_path=out_file_path+"DRT/" if not os.path.exists(DRT_out_file_path): os.makedirs(DRT_out_file_path) DRT_out_file_tif_path=os.path.join(DRT_out_file_path,rt_hv+".tif") eco_out_file_path=out_file_path+"eco/" if not os.path.exists(eco_out_file_path): os.makedirs(eco_out_file_path) eco_out_file_tif_path=os.path.join(eco_out_file_path,rt_hv+".tif") wat_out_file_path=out_file_path+"wat/" if not os.path.exists(wat_out_file_path): os.makedirs(wat_out_file_path) wat_out_file_tif_path=os.path.join(wat_out_file_path,rt_hv+".tif") tim_out_file_path=out_file_path+"tim/" if not os.path.exists(tim_out_file_path): os.makedirs(tim_out_file_path) tim_out_file_tif_path=os.path.join(tim_out_file_path,rt_hv+".tif") rt_raster=gdal.Open(rt_file_path+rt_file) rt_band_num=rt_raster.RasterCount rt_raster_array=rt_raster.ReadAsArray() rt_lai_array=rt_raster_array[0] rt_qa_array=rt_raster_array[1] rt_lai_band=rt_raster.GetRasterBand(1) # rt_lai_nodata=rt_lai_band.GetNoDataValue() # rt_lai_nodata=32767 # rt_lai_mask=np.ma.masked_equal(rt_lai_array,rt_lai_nodata) rt_lai_array_mask=np.where(rt_lai_array>30000,np.nan,rt_lai_array) rt_lai_array_fin=rt_lai_array_mask*0.001 gl_raster=gdal.Open(gl_file_path+gl_file) gl_band_num=gl_raster.RasterCount gl_raster_array=gl_raster.ReadAsArray() gl_lai_array=gl_raster_array gl_lai_band=gl_raster.GetRasterBand(1) gl_lai_array_mask=np.where(gl_lai_array>1000,np.nan,gl_lai_array) gl_lai_array_fin=gl_lai_array_mask*0.01 row=rt_raster.RasterYSize col=rt_raster.RasterXSize geotransform=rt_raster.GetGeoTransform() projection=rt_raster.GetProjection() lai_dif=rt_lai_array_fin-gl_lai_array_fin lai_dif=lai_dif*1000 rt_qa_array_bin=copy.copy(rt_qa_array) rt_qa_array_row,rt_qa_array_col=rt_qa_array.shape for i in range(rt_qa_array_row): for j in range(rt_qa_array_col): rt_qa_array_bin[i][j]="{:012b}".format(rt_qa_array_bin[i][j])[-4:] # DRT_pixel_pos=np.where((rt_qa_array_bin>=100) & (rt_qa_array_bin==11)) # eco_pixel_pos=np.where((rt_qa_array_bin<100) & (rt_qa_array_bin==111)) # wat_pixel_pos=np.where((rt_qa_array_bin<1000) & (rt_qa_array_bin==1011)) # tim_pixel_pos=np.where((rt_qa_array_bin<1100) & (rt_qa_array_bin==1111)) # colormap=plt.cm.Greens # plt.figure(1) # # plt.subplot(2,4,1) # plt.imshow(rt_lai_array_fin,cmap=colormap,interpolation='none') # plt.title("RT_LAI") # plt.colorbar() # plt.figure(2) # # plt.subplot(2,4,2) # plt.imshow(gl_lai_array_fin,cmap=colormap,interpolation='none') # plt.title("GLASS_LAI") # plt.colorbar() # plt.figure(3) # dif_colormap=plt.cm.get_cmap("Spectral") # plt.imshow(lai_dif,cmap=dif_colormap,interpolation='none') # plt.title("Difference_LAI (RT-GLASS)") # plt.colorbar() DRT_lai_dif_array=np.where((rt_qa_array_bin>=100) | (rt_qa_array_bin==11), np.nan,lai_dif) eco_lai_dif_array=np.where((rt_qa_array_bin<100) | (rt_qa_array_bin==111), np.nan,lai_dif) wat_lai_dif_array=np.where((rt_qa_array_bin<1000) | (rt_qa_array_bin==1011), np.nan,lai_dif) tim_lai_dif_array=np.where((rt_qa_array_bin<1100) | (rt_qa_array_bin==1111), np.nan,lai_dif) # plt.figure(4) # plt.imshow(DRT_lai_dif_array) # plt.colorbar() # plt.figure(5) # plt.imshow(eco_lai_dif_array) # plt.colorbar() # plt.figure(6) # plt.imshow(wat_lai_dif_array) # plt.colorbar() # plt.figure(7) # plt.imshow(tim_lai_dif_array) # plt.colorbar() driver=gdal.GetDriverByName("Gtiff") out_DRT_lai=driver.Create(DRT_out_file_tif_path,row,col,1,gdal.GDT_Float32) out_DRT_lai.SetGeoTransform(geotransform) out_DRT_lai.SetProjection(projection) out_DRT_lai.GetRasterBand(1).WriteArray(DRT_lai_dif_array) out_DRT_lai=None driver=gdal.GetDriverByName("Gtiff") out_eco_lai=driver.Create(eco_out_file_tif_path,row,col,1,gdal.GDT_Float32) out_eco_lai.SetGeoTransform(geotransform) out_eco_lai.SetProjection(projection) out_eco_lai.GetRasterBand(1).WriteArray(eco_lai_dif_array) out_eco_lai=None driver=gdal.GetDriverByName("Gtiff") out_wat_lai=driver.Create(wat_out_file_tif_path,row,col,1,gdal.GDT_Float32) out_wat_lai.SetGeoTransform(geotransform) out_wat_lai.SetProjection(projection) out_wat_lai.GetRasterBand(1).WriteArray(wat_lai_dif_array) out_wat_lai=None driver=gdal.GetDriverByName("Gtiff") out_tim_lai=driver.Create(tim_out_file_tif_path,row,col,1,gdal.GDT_Float32) out_tim_lai.SetGeoTransform(geotransform) out_tim_lai.SetProjection(projection) out_tim_lai.GetRasterBand(1).WriteArray(tim_lai_dif_array) out_tim_lai=None print(rt_hv)
原文鏈接:https://www.cnblogs.com/fkxxgis/p/17147496.html
- 上一篇:沒(méi)有了
- 下一篇:沒(méi)有了
相關(guān)推薦
- 2022-06-18 Elasticsearch之文檔批量操作示例_其它綜合
- 2022-04-23 Python繪制燈籠的示例代碼_python
- 2022-10-09 基于Redission的分布式鎖實(shí)戰(zhàn)_Redis
- 2022-05-20 ASP.NET?MVC模式中應(yīng)用程序結(jié)構(gòu)詳解_基礎(chǔ)應(yīng)用
- 2022-09-15 Go語(yǔ)言中Goroutine的設(shè)置方式_Golang
- 2022-01-05 npm ERR! code ENOENT npm ERR! syscall open npm ERR
- 2022-06-01 Python+Opencv實(shí)現(xiàn)計(jì)算閉合區(qū)域面積_python
- 2023-03-18 pandas數(shù)據(jù)聚合與分組運(yùn)算的實(shí)現(xiàn)_python
- 欄目分類
-
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門(mén)
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支