FY-4A建立中國區域圖像行列號轉經緯度的經緯度查找表進行幾何校正

自從數據發佈以來局部中國區域文件官方只給出了圖像文件,並未給出對應的經緯度查找表,而對於只研究中國區域的同學來說,下載全圓盤圖像文件顯得費時費力,然後處理起來又佔據內存。爲了對中國區域圖像文件進行幾何校正,將標稱投影轉爲等經緯度投影,博主和同學老王進行了交流,終成此文。

下面將利用Python實現區域圖像文件的經緯度查找表建立!~

將中國區域行列號轉爲經緯度查找表,並且存爲tiff文件,band1爲經度,band2爲緯度。在ENVI中建立GLT,rotation選擇0,即圖像正上爲正北方向,其他不變,然後利用GLT進行幾何校正,投影選擇等經緯度。其他不變。這是Python實現區域經緯度查找表tiff文件的程序。選擇文件爲中國區域GEO 4km定位文件。下載好4km定位文件後,自行修改後綴爲HDF5!

程序路徑的話,自行修改路徑~

# -*- coding: utf-8 -*-
"""
Created on Tue Apr 23 11:39:02 2019

@author: Administrator
"""


import os
import numpy as np 
import math
import h5py 
import gdal
import operator

#讀取FY4A-_AGRI--_N_DISK_1047E_L1-_GEO-_MULT_NOM文件,空間分辨率4km
#此程序僅限於此類文件

#該文件中僅用於獲得FY4A-_AGRI--_N_REGC_1047E_L1_***_4000M_***.HDF文件
#中數據的行列號轉換成經緯度

def Get_Line_Col_in_Disk(File_Full_Path):
    #print('#########################################')
    #判讀輸入文件是否爲FY4A-_AGRI--_N_REGC_1047E_L1_***_4000M_***.HDF文件
    #如果不是,則輸出文件是錯誤的,退出程序
    fname = os.path.basename(File_Full_Path)
    #print('fname =',fname)
                        
    str_GEO_value = fname.find('GEO')    
    #print(str_GEO_value)   
    str_REGC_value = fname.find('REGC')    
    #print(str_REGC_value) 
    str_4000M_value = fname.find('4000M')    
    #print(str_4000M_value)  
    if  str_GEO_value == -1 or str_REGC_value == -1 or str_4000M_value == -1:
        return None
    #以只讀的方式打開hdf5文件
    InFile_REGC_GEO_4KM = h5py.File(File_Full_Path,'r')

    #ColumnNumber對應的數據,以numpy.ndarray方式存儲
    #中國區域文件各個像點對應於全圓盤的列號
    Data_Col_Num_in_Disk_GDAL = InFile_REGC_GEO_4KM['ColumnNumber'][:]
    Data_Col_Num_in_Disk = Data_Col_Num_in_Disk_GDAL.astype('f4') 
    print(Data_Col_Num_in_Disk_GDAL.dtype)
    print(Data_Col_Num_in_Disk.dtype)
    
    #LineNumber對應的數據,以numpy.ndarray方式存儲
    #中國區域文件各個像點對應於全圓盤的行號
    Data_Line_Num_in_Disk_GDAL = InFile_REGC_GEO_4KM['LineNumber'][:]
    Data_Line_Num_in_Disk = Data_Line_Num_in_Disk_GDAL.astype('f4')
    
    InFile_REGC_GEO_4KM.close() 
    return Data_Line_Num_in_Disk,Data_Col_Num_in_Disk
    
def Convert_Line_Col_To_Lon_Lat(Data_Line_Num_in_Disk,Data_Col_Num_in_Disk):
    #print('##########################################')  
    ##根據中國區域在全圓盤中的行列號計算經緯度
    #注意:各個文件中在全圓盤的行列號會有所不同
    #中國區域內的有效行列號
           
    Valid_Value_Index = np.where(Data_Line_Num_in_Disk != -1.0 )
    Line = Data_Line_Num_in_Disk[Valid_Value_Index]     
    Column = Data_Col_Num_in_Disk[Valid_Value_Index] 
     
   
    #地球的長半軸,單位km
    ea = 6378.137
    #地球的短半軸,單位km
    eb = 6356.7523
    #地心到衛星質心的距離,單位km
    h = 42164
    #衛星星下點的經度
    Lon_Sate = 104.7
    #COFF全圓盤列偏移,4km對應的數值
    COFF = 1373.5
    #CFAC全圓盤列比例因子,4km對應的數值
    CFAC = 10233137
    #LOFF全圓盤行偏移,4km對應的數值
    LOFF = 1373.5
    #LFAC全圓盤列比例因子,4km對應的數值
    LFAC = 10233137
    
    tmp = np.pi/(180*math.pow(2,-16))
    #print('tmp =',tmp)
    
    x = tmp * (Column - COFF)/CFAC
    #print('x =',x)
    
    y = tmp * (Line - LOFF)/LFAC
    #print('y =',y)

    sinx = np.sin(x)
    cosx = np.cos(x)
    siny = np.sin(y)
    cosy = np.cos(y)
    
    cosxy = cosx * cosy
    tmp2 = cosy*cosy + siny*siny * ea*ea /(eb*eb) 
    #print('tmp2=',tmp)
    sd = np.power((h*cosxy)*(h*cosxy) - tmp2*(h*h-ea*ea),0.5)
    sn = ( h*cosxy - sd ) / tmp2
    s1 = h - sn * cosxy
    s2 = sn * sinx * cosy
    s3 = -sn * siny
    sxy = np.power(s1*s1 + s2*s2,0.5)
    
    tmp3 = 180 / np.pi
    lon = tmp3 * np.arctan(s2/s1) + Lon_Sate
    lat = tmp3 * np.arctan((ea*ea*s3)/(eb*eb*sxy))
    #print('lon =',lon)
    #print('lat =',lat)
    
    Data_Lon = np.zeros(Data_Line_Num_in_Disk.shape, dtype = np.float64,order = 'C' )
    Data_Lon[:,:] = 999    
    Data_Lon[Valid_Value_Index] = lon
        
    Data_Lat = np.zeros(Data_Line_Num_in_Disk.shape, dtype = np.float64,order = 'C' )
    Data_Lat[:,:] = 999
    Data_Lat[Valid_Value_Index] = lat 
    
    return Data_Lon,Data_Lat
    
def writeTiff(im_data,im_width,im_height,im_bands,path):#im_geotrans,im_proj,path):
    if 'int8' in im_data.dtype.name:
        datatype = gdal.GDT_Byte
    elif 'int16' in im_data.dtype.name:
        datatype = gdal.GDT_UInt16
    else:
        datatype = gdal.GDT_Float64

    if len(im_data.shape) == 3:
        im_bands, im_height, im_width = im_data.shape
    elif len(im_data.shape) == 2:
        im_data = np.array([im_data])
    else:
        im_bands, (im_height, im_width) = 1,im_data.shape
        #創建文件
    driver = gdal.GetDriverByName("GTiff")
    dataset = driver.Create(path, im_width, im_height, im_bands, datatype)
    #if(dataset!= None):
        #dataset.SetGeoTransform(im_geotrans) #寫入仿射變換參數
        #dataset.SetProjection(im_proj) #寫入投影
    for i in range(im_bands):
        dataset.GetRasterBand(i+1).WriteArray(im_data[i])
    del dataset
     

#主程序
if __name__ =='__main__': 
    
    GEO_File_Full_Path = 'E:\FY-4A大創\幾何校正\python_FY-4A\FY4A-_AGRI--_N_REGC_1047E_L1-_GEO-_MULT_NOM_20190310003000_20190310003416_4000M_V0001.HDF5'   
    GEO_file_name = os.path.basename(GEO_File_Full_Path)
    first = GEO_file_name[44:57]
    print(first)
    second = GEO_file_name[73:79]
    print(second)
    out_name = first + second + '經緯度查找表'
  
    Data_line_col = Get_Line_Col_in_Disk(GEO_File_Full_Path)      
    Lon_Lat = Convert_Line_Col_To_Lon_Lat(Data_line_col[0],Data_line_col[1])

       
    #print(type(Lon_Lat))
    if Lon_Lat is None :
        print ('wrong file')
    #elif (id(GEO_file_name[44:73]) is not id(Ocean_file_name[44:73])):
        #print(type(GEO_file_name[44:73]))
        #print('Geo file does not match Ocean file')
    else:
        
        Lon = Lon_Lat[0] 
        Lat = Lon_Lat[1]        
    
    im_data = np.array([Lon,Lat])
    im_bands, im_height, im_width = im_data.shape
    
    #保存tif文件函數
    path = 'E:\FY-4A大創\幾何校正\python_FY-4A\\'+ out_name + '.tif'
    writeTiff(im_data, im_width, im_height,im_bands,path) 

tif命名爲:成像時間+空間分辨率+經緯度查找表,例如 2019031000300_4000M經緯度查找表.tif

生成的查找表如圖:
在這裏插入圖片描述
band1爲經度,band2爲緯度
建立GLT的過程參考鏈接[3],在建立GLT的過程中一定要注意,要先對生成的經緯度查找表做一個感興趣區域的裁剪,用ENVI Resize Data(special/spectral)工具進行,裁剪一個矩形的就好,既包括研究區又要大一些,不可以取到外圍999的無效值,ENVI在建立GLT的過程中,一旦有外圍999的無效值在,建立GLT時就會產生一個巨大無比的文件,並且一段時間後磁盤爆滿,電腦未響應死機。
在這裏插入圖片描述
利用GLT工具幾何校正結果如圖:
在這裏插入圖片描述
在這裏插入圖片描述
這樣的話整個過程不超過5分鐘!
博主用的是4km區域定位文件(GEO文件):
FY4A-_AGRI–_N_REGC_1047E_L1-_GEO-_MULT_NOM_20190310003000_20190310003416_4000M_V0001

博主用的3月10號的定位文件對3月8號的區域圖像進行的幾何校正,效果完全可以。不過據說,每次的區域文件嚴格地講,其大小會有一兩個像元的偏差。

寫入tiff部分的程序鳴謝train_for_skills參考:
[1]: https://blog.csdn.net/t46414704152abc/article/details/77482747
[2]:http://satellite.nsmc.org.cn/PortalSite/StaticContent/DocumentDownload.aspx?TypeID=3
[3]:http://blog.sina.com.cn/s/blog_764b1e9d0101da96.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章