IDL学习——哨兵2 L1C数据辐射定标

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
从官网下载的哨兵2 L1C数据是大气表观反射率产品,而大气校正输入数据必须为辐射亮度数据,大气表观反射率和辐射亮度值存在以下数学关系:

转换公式

  • 辐射亮度转换为大气表观反射率公式:

    ρ λ = π L λ d 2 / E S U N λ s i n θ \rho_{\lambda}={\pi L_{\lambda}d^2}/{ESUN_{\lambda}sin\theta} ρλ=πLλd2/ESUNλsinθ

  • 大气表观反射率转换为辐射亮度公式
      L λ = ρ λ E S U N λ s i n θ / π d 2 \ L_{\lambda}={\rho_{\lambda}ESUN_{\lambda}sin\theta}/{\pi d^2}  Lλ=ρλESUNλsinθ/πd2
    参数说明:
    ρ λ :大气表观反射率; L λ :辐射亮度; d :日地距离; E S U N λ :太阳辐照度; θ : 太阳高度角 \rho_{\lambda}:大气表观反射率;L_{\lambda}:辐射亮度;d:日地距离;ESUN_{\lambda}:太阳辐照度;\theta:太阳高度角 ρλ:大气表观反射率;Lλ:辐射亮度;d:日地距离;ESUNλ:太阳辐照度;θ:太阳高度角

参数查找

日地距离、太阳辐照度

xml文件

将哨兵2MTD_MSIL1C.xml以notepad++打开,日地距离可从文件中节点为U得知,太阳辐照度—Solar_Irradiance就在下面几行。
IDL学习——哨兵2 L1C数据辐射定标_第1张图片

IDL读取

栅格元信息中 ‘EARTH SUN DISTANCE’即为日地距离,Solar_Irradiance即为太阳辐照度,这里注意IDL读哨兵2xml数据读出来是3个栅格对象——10米(B2,B3,B4,B8波段);20米(B5,B6,B7,B8A,B11,B12波段);60米(B1,B9,B10波段),我这里只对10米进行数据转换,只读取了10米波段的栅格数据,所以这里太阳辐照度顺序对应为—B2,B3,B4,B8.

file = 'G:\L1C_T49SCC_A037624_20220905T033145\S2A_MSIL1C_20220905T032531_N0400_R018_T49SCC_20220905T052134.SAFE\MTD_MSIL1C.xml'
raster = (e.openraster(file))[0]
print,raster.metadata

IDL学习——哨兵2 L1C数据辐射定标_第2张图片

太阳高度角

xml文件

在相对路径如GRANULE/L1C_T51RTQ_A015101_20180514T024123下包含另一个名为MTD_TL的xml文件,在节点Mean Sun Angle下有两个值,太阳天顶角(ZENITH ANGLE);太阳方位角(AZIMUTH_ANGLE),太阳高度角和太阳天顶角互余,所以就为90-太阳天顶角。
IDL学习——哨兵2 L1C数据辐射定标_第3张图片

IDL读取

同样读取10米栅格的元信息,SUN ELEVATION即为太阳高度角。
IDL学习——哨兵2 L1C数据辐射定标_第4张图片

代码实现

file = 'G:\L1C_T49SCC_A037624_20220905T033145\S2A_MSIL1C_20220905T032531_N0400_R018_T49SCC_20220905T052134.SAFE\MTD_MSIL1C.xml'
 inopenraster = e.openraster(file)
  metadata = inopenraster[0].metadata
  sun_eleva = metadata['SUN ELEVATION']
  sun_distance = metadata['EARTH SUN DISTANCE']
  ;创建对象存储转换之后的每个波段数据
  band_arr = objarr(4)
  for i=1,4 do begin
    ;进行表观反射率转换为辐射亮度转换
    ;公式构建
    band_SOLAR = (metadata['SOLAR IRRADIANCE'])[i-1]
    expression1 = 'b'+strtrim(string(i),2) + '*'
    expression2 = band_SOLAR * sin(sun_eleva/180 * !PI)
    expression3 = !DPI * sun_distance*sun_distance * 100000
    expression = expression1+strcompress(string(expression2))+'/'+strcompress(string(expression3))
    print,expression
    ;进行band math计算
    band_Task=ENVITask('PixelwiseBandMathRaster')
    band_Task.INPUT_RASTER = inopenraster[0]
    band_Task.EXPRESSION = expression
;    ndvi_Task.output_raster_uri = 'G:\Sentinel2_Radio\' + 'b'+strtrim(string(i),2) + '_final5.dat'
    band_Task.Execute
    band_arr[i-1] =  band_Task.output_raster

  endfor
  ;波段组合
  gridTask = ENVITask('BuildGridDefinitionFromRaster')
  gridTask.INPUT_RASTER = inopenraster[0]
  gridTask.Execute
  stackTask = ENVITask('BuildLayerStack')
  stackTask.INPUT_RASTERS = band_arr
  stackTask.GRID_DEFINITION = gridTask.OUTPUT_GRIDDEFINITION
  stackTask.Execute
  print,stackTask.output_raster_uri

对比该结果和ENVI官方哨兵2辐射定标插件结果,出来是一样的,那就没得问题。
参考资料:
https://blog.csdn.net/u013471015/article/details/88663209
https://www.cnblogs.com/enviidl/p/16386359.html

你可能感兴趣的:(数据处理,IDL,哨兵2,IDL,遥感数据处理)