GDAL幾何校正


GDAL幾何校正之Geoloc校正

1. 幾何校正原理

​ 常見的幾何校正方法有幾何多項式校正、有理函數模型校正、局部區域校正模型、地理查找表校正。GDAL庫中可以實現的校正方法有:幾何多項式校正、RPC校正(有理函數模型)、TPS(薄板函數模型)校正、Geoloc校正。

2. Geoloc校正(地理查找表校正)
2.1 直接校正

​ 對於自帶Geolocation元數據(lon/lat)的數據,可以查看波段信息(如子數據集路徑等),然后直接調用gdalwarp進行校正。

​ 比如對modis的mod02數據,我們分以下兩步進行幾何校正。

(1) 查看數據集路徑
from osgeo import gdal
datasets = gdal.Open(r"E:\Tablefile\modis\MOD021KM.A2020350.0325.061.2020350130838.hdf")
# 可以用這個來查找EV_1KM_RefSB數據集路徑
#  獲取hdf中的子數據集
SubDatasets = datasets.GetSubDatasets()
#  獲取子數據集的個數
SubDatasetsNum =  len(datasets.GetSubDatasets())
#  輸出各子數據集的信息
print("子數據集一共有{0}個: ".format(SubDatasetsNum))
for i in range(SubDatasetsNum):
    print(datasets.GetSubDatasets()[i])
    
(2) gdalwarp.exe
# mod02 --> ref(幾何校正正確,與heg/MRT結果相同)
gdalwarp.exe -geoloc -t_srs EPSG:4326 "HDF4_EOS:EOS_SWATH:"E:\Tablefile\modis\MOD021KM.A2020350.0325.061.2020350130838.hdf":MODIS_SWATH_Type_L1B:EV_1KM_RefSB" E:\Tablefile\MOD021KM.tif
            
(3) 此外可以通過gdalinfo.exe查看數據集信息
gdalinfo.exe HDF4_EOS:EOS_SWATH:"E:\Tablefile\modis\MOD021KM.A2020350.0325.061.2020350130838.hdf":MODIS_SWATH_Type_L1B:EV_1KM_RefSB

​ 但同時也發現了一點問題:

# mod03 --> sala/saza/sola/soza(幾何校正錯誤!!!猜測是lon/lat問題?)
# 同樣的方法對mod03地理定位文件進行幾何校正,校正明顯失敗,與HEG的結果不同。
gdalwarp.exe -geoloc -t_srs EPSG:4326 "HDF4_EOS:EOS_SWATH:"E:\\Tablefile\\modis\\MOD03.A2020350.0325.061.2020350090352.hdf":MODIS_Swath_Type_GEO:SensorZenith" E:\Tablefile\MOD03_salz.tif

​ 猜測是lon/lat不配對的原因,但是查看數據集后發現mod03(2030X1354)與其對應mod02(406X271)數據的lon/lat數值范圍基本相同,因此可能不是這個原因。求解?

2.2 調用VRT文件校正

​ 對於本身不帶lon/lat的數據,需要構建VRT文件進行校正。

​ 常用於風雲4A、Himawari-8等衛星數據,這兩種靜止軌道衛星的校正方法有兩種:

  1. 構建lon/lat數據集,進行地理查找表校正

  2. 根據行偏移、列偏移量,對不同分辨率數據的行列號和經緯度進行推導,以構建經緯度和值的對應關系,從而實現校正。(速度較慢)

    介紹第一種方法

    (以mod02為例,lon/lat讀取mod數據集中的lon/lat子數據集)

1. 查詢待幾何校正數據的路徑 以及 lon/lat 路徑(同上)

(1) 如果該衛星提供了行列號與經緯度的對應數據,如.raw(FY-4A),那么可以用np.fromfile進行讀取,生成lon/lat的柵格文件。
(2) 如果沒有提供這種數據,可以根據行列號建立經緯度數據集(行列號=>經緯度)。

2. 調用gdal_translate.exe,后接需要幾何校正的數據集路徑,生成VRT文件

gdal_translate.exe -of VRT HDF4_EOS:EOS_SWATH:"E:\\Tablefile\\modis\\MOD021KM.A2020350.0325.061.2020350130838.hdf":MODIS_SWATH_Type_L1B:EV_1KM_RefSB E:/Tablefile/back.vrt
           
3. 修改VRT文件的X_DATASET/Y_DATASET => lon/lat,調用gdalwarp

gdalwarp.exe -geoloc -t_srs EPSG:4326 E:\Tablefile\back.vrt E:\Tablefile\warp.tif 
# vrt文件內容 
  
  
    <MDI key="LINE_OFFSET">2</MDI>
    <MDI key="LINE_STEP">5</MDI>
    <MDI key="PIXEL_OFFSET">2</MDI>
    <MDI key="PIXEL_STEP">5</MDI>
    <MDI key="SRS">GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]</MDI>
    <MDI key="X_BAND">1</MDI>
    <MDI key="X_DATASET">HDF4_SDS:UNKNOWN:"E:\\Tablefile\\modis\\MOD03.A2020350.0325.061.2020350090352.hdf":1</MDI>
    <MDI key="Y_BAND">1</MDI>
    <MDI key="Y_DATASET">HDF4_SDS:UNKNOWN:"E:\\Tablefile\\modis\\MOD03.A2020350.0325.061.2020350090352.hdf":0</MDI>
  
3. VRT校正的調用代碼
def bulidVRT(warpFile, gltFile, vrtFile, outfile, warpWord):
    '''
    @desc:VRT調用gdalwarp.exe幾何校正
    '''
    datasets = gdal.Open(warpFile)
    SubDatasetsNum =  len(datasets.GetSubDatasets())
    infoList = []
    for i in range(SubDatasetsNum):
        eachLine = datasets.GetSubDatasets()[i]
        if warpWord in eachLine[1]:       # 需要校正的數據集的路徑
            infoList.append(eachLine[0])
        if 'Latitude' in eachLine[1]:
            infoList.append(eachLine[0])
        if 'Longitude' in eachLine[1]:
            infoList.append(eachLine[0])
    print(infoList)

    datasets2 = gdal.Open(gltFile)
    SubDatasetsNum2 =  len(datasets2.GetSubDatasets())
    infoList2 = []
    for i in range(SubDatasetsNum2):
        eachLine2 = datasets2.GetSubDatasets()[i]
        if 'Latitude' in eachLine2[1]:
            infoList2.append(eachLine2[0])
        if 'Longitude' in eachLine2[1]:
            infoList2.append(eachLine2[0])
    print(infoList2)

    cmd = 'D:/Anaconda/Lib/site-packages/osgeo/gdal_translate.exe -of VRT %s %s' % (
        infoList[0], vrtFile
    )
    os.system(cmd)

    f = open(vrtFile) 
    newf = open(vrtFile.replace('.vrt', 'new.vrt'), 'w')
    lines = f.readlines()
    for line in lines:
        if ('<MDI key="X_DATASET">' in line):
            newf.write('    <MDI key="X_DATASET">'+ str(infoList2[1]) +'</MDI>\n')
        elif ('<MDI key="Y_DATASET">' in line):
            newf.write('    <MDI key="Y_DATASET">'+ str(infoList2[0]) +'</MDI>\n')
        else:
            newf.write(line)
    newf.close()
    f.close()   

    cmd2 = 'D:/Anaconda/Lib/site-packages/osgeo/gdalwarp.exe -geoloc -t_srs EPSG:4326 %s %s'%(
        vrtFile.replace('.vrt', 'new.vrt'), outfile
    )

    os.system(cmd2)
    os.remove(vrtFile)
    os.remove(vrtFile.replace('.vrt', '.tif.aux.xml'))
    os.rename(vrtFile.replace('.vrt', 'new.vrt'), vrtFile)
4. 后記
  1. 思考mod03數據幾何校正失敗的原因
  2. 需要熟悉dom解析模塊/re表達式,以提高文檔的解析力
  3. 后續補充RPC校正、TPS校正的原理及調用


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM