Himawari-8葵花八HSD数据处理——几何校正
发布日期:2021-07-25 13:05:06 浏览次数:47 分类:技术文章

本文共 7501 字,大约阅读时间需要 25 分钟。

Himawari-8的影像是个大圆盘,看起来就是这样:

在这里插入图片描述
要把这个大圆盘展开,需要对它进行几何校正。
IDL几何校正的思路如下:
1.利用行列号生成像元对应坐标(cols,lines->lon,lat)
2.利用坐标文件生成GLT
3.应用GLT文件对影像进行校正
几何校正的代码见下方
一些解释:
1.生成像元坐标时,cols,rows,LOFF,COFF,LAFC,CAFC参数根据分辨率不同有所区别。
2.生成GLT直接在ENVI里面做,注意像元大小(0.01或0.02)和旋转角度(0.0)设置,GLT生成好后对所有全云盘影像都可以用,一次生成,一直能用。

PRO Himawari8_LOC  COMPILE_OPT idl2  e=envi(/headless)  ;输入分辨率,10——1km,20——2km  resolution='10'    if resolution eq '20' then begin    rows=5500 & cols=5500    pixel_size=0.02    COFF=2750.5 & CFAC=20466275    LOFF=2750.5 & LFAC=20466275  endif else if resolution eq '10' then begin    rows=11000 & cols=11000    pixel_size=0.01    COFF=5500.5 & CFAC=40932549    LOFF=5500.5 & LFAC=40932549  endif  root_Dir=e.root_dir  demfile=filepath('GMTED2010.jp2',root_Dir=root_Dir,subdirectory=['data'])  demraster=e.OpenRaster(demfile)  demdata=demraster.getdata()  demspatial=[-180.00014,0.0083333,83.99986,-0.008333]  locdata=make_array(cols,rows,3,/float)  ;i,j从0开始校正后的影像偏差大概2个像元,这里从1开始找补一点偏差  for i=1,cols do begin    for j=1,rows do begin      ll=cl2ll(i,j,COFF,CFAC,LOFF,LFAC)      locdata[i-1,j-1,*]=ll      lon=ll[0]      if ll[0] le 360.0+demspatial[0] then begin        lon=ll[0]-360.0         endif      h=demdata[long((lon-demspatial[0])/demspatial[1]),long((ll[1]-demspatial[2])/demspatial[3])]      locdata[i,j,2]=h/1000.0    endfor  endfor  ;填补数据  fill_data=filldata(locdata=locdata)  ;导出保存在ENVI中生成GLT  fillraster=ENVIRaster(fill_data,URI='**loc_R'+resolution+'.dat')  fillraster.save  locraster.Close  fillraster.Close      e.CloseEND

将行列号转为经纬度的代码参照Himawari官网的代码,看截图:

在这里插入图片描述
翻译成IDL的代码是这样:

;行列号转经纬度function cl2ll,c,l,COFF,CFAC,LOFF,LFAC  COMPILE_OPT idl2  d2r=0.01745329252d  r2d=57.295779513d  scal=65536;2^(-16)=1/(2^16)  x=d2r*(c-COFF)*65536/CFAC  y=d2r*(l-LOFF)*65536/LFAC  ;'Distance from Earth's center to virtual satellite' =42164km  ;R(eq)^2 / R(pol)^2=1.006739501  ;'Coefficient for sd'=1737122264  rs= 42164.0  sd=sqrt((rs*rs*cos(x)*cos(x)*cos(y)*cos(y))-(cos(y)*cos(y)+ 1.006739501*sin(y)*sin(y))*1737122264)  sn=(rs*cos(x)*cos(y)-sd)/(cos(y)*cos(y)+ 1.006739501*sin(y)*sin(y))  s1=rs-sn*cos(x)*cos(y)  s2=sn*sin(x)*cos(y)  s3=-sn*sin(y)  sxy=sqrt(s1*s1+s2*s2)  lon=atan2(s1,s2)*r2d+140.7  lat=atan2(sxy,1.006739501*s3)*r2d  return,[lon,lat]   END

里面有用一个atan2函数,这个是另一个博文里写的:

;atan2函数function atan2,x,y ;此函数和matlab中的atan2输入的xy是相反的x=x*1d0 & y=y*1d0 absy = 0d & absx = 0d & val = 0dIF(x eq 0 and y eq 0)THEN BEGIN return, 0 ; ERROR! ENDIFabsy = abs(y) & absx = abs(x)IF(absy - absx eq absy)THEN BEGIN IF(y lt 0)THEN BEGIN return, -!pi/2 ENDIF ELSE BEGIN return, !pi/2 ENDELSE ENDIFIF(absx - absy eq absx)THEN BEGIN val = 0d0 ENDIF ELSE BEGIN val = atan(y/x) ENDELSEIF(x gt 0)THEN BEGIN return, val ENDIFIF(y lt 0)THEN BEGIN return, val-!pi ENDIFreturn, val+!piEND

计算出来的经纬度是个大圆盘,下面看图,生成GLT需要把圆盘边角全部填满,使数组没有无效值(0/NAN)和错值(经度大于360.0,纬度超出[-90.0,90.0]等)。

在这里插入图片描述

这里我定义填补后的经度范围为[60,222],纬度填补后的范围是[-90.0,90.0],填补代码如下:

;填补数据function filldata,locdata=locdata    cols=(locdata.dim)[0]  rows=(locdata.dim)[1]  ;填补经度数据  ;经度  londata=locdata[*,*,0]  ;中间列  lon0=londata[fix(cols/2),*]  lon0idx=where(finite(lon0))  ;缺值补值  lon0top=lon0idx.min()  lon0bottom=lon0idx.max()  londata[fix(cols/2),*]=[[make_array(1,lon0top,value=lon0[lon0top])],[rotate(lon0[lon0top:lon0bottom],1)],$    [make_array(1,rows-lon0bottom-1,value=lon0[lon0bottom])]]    ;中间行  lon1=londata[*,fix(rows/2)]  lon1idx=where(finite(lon1))  ;缺值位置  lon1left=lon1idx.min()  lon1right=lon1idx.max()  ;等差数列补值  lon1left_ps=(lon1[lon1left]-60.0)/lon1left  lon1right_ps=(222.0-lon1[lon1right])/(cols-1-lon1right)  print,lon1left_ps,lon1right_ps  ;缺处补值  londata[*,fix(rows/2)]=[lon1[lon1left]-(lon1left-findgen(lon1left))*lon1left_ps,$    lon1[lon1left:lon1right],lon1[lon1right]+(findgen(cols-lon1right-1)+1)*lon1right_ps]  ;纬度补值  latdata=locdata[*,*,1]  ;中间列  lat0=latdata[fix(cols/2),*]  lat0idx=where(finite(lat0))  lat0top=lat0idx.min()  lat0bottom=lat0idx.max()  lat0top_ps=(90.0-lat0[lat0top])/lat0top  lat0bottom_ps=(lat0[lat0bottom]+90.0)/(rows-1-lat0bottom)  print,lat0top_ps,lat0bottom_ps  latdata[fix(cols/2),*]=[[rotate(lat0[lat0top]+(lat0top-findgen(lat0top))*lat0top_ps,1)],$    [rotate(lat0[lat0top:lat0bottom],1)],[rotate(lat0[lat0bottom]-(findgen(cols-lat0bottom-1)+1)*lat0bottom_ps,1)]]     ;中间行  lat1=latdata[*,fix(rows/2)]  lat1idx=where(finite(lat1))  lat1left=lat1idx.min()  lat1right=lat1idx.max()  latdata[*,fix(rows/2)]=[make_array(lat1left,1,value=lat1[lat1left]),lat1[lat1left:lat1right],make_array(cols-lon1right-1,1,value=lat1[lat1right])]  ;全部补值     for i=0,cols-1 do begin            lonidx=where(finite(londata[i,*]))      lontop=lonidx.min()    lonbottom=lonidx.max()      if (lontop gt 0) then begin      londata[i,0:lontop-1]=rebin([londata[i,lontop]],1,lontop)    endif     if (lonbottom lt rows-1) then begin             londata[i,lonbottom+1:-1]=rebin([londata[i,lonbottom]],1,rows-lonbottom-1)     endif      latidx=where(finite(latdata[*,i]))    latleft=latidx.min()    latright=latidx.max()    if (latleft gt 0) then begin             latdata[0:latleft-1,i]=rebin([latdata[latleft,i]],latleft,1)    endif    if (latright lt cols-1) then begin           latdata[latright+1:-1,i]=rebin([latdata[latright,i]],cols-latright-1,1)    endif          endfor   locdata[*,*,0]=londata  locdata[*,*,1]=latdata    return,locdata  END

填上边角的经纬度文件长这样:

在这里插入图片描述

在ENVI中生成GLT文件:

在这里插入图片描述
注意pixel_size和rotation改好,rotation是0,pixel_size根据分辨率确定,2KM填0.02,1KM填0.01
在这里插入图片描述
生成的GLT长这样:
在这里插入图片描述
给影像应用GLT进行校正——ENVI里进行
在这里插入图片描述
也可以用IDL代码:

;应用GLT校正e=envi(/headless)inputraster=e.openraster('*****H8全云盘影像')fid=ENVIRasterToFID(inputraster)out_name='***给投影完了的文件起个名'#不想起名就用e.GetTemporaryFilename()ENVI_DOIT,'ENVI_GEOREF_FROM_GLT_DOIT',FID=fid,GLT_DIMS=glt_dims,GLT_FID=glt_id,OUT_NAME=out_name,pos=lindgen(bands)

校正后的影像长这样:

在这里插入图片描述
小小的偏移(i,j循环从0开始)
在这里插入图片描述
更小的偏移(i,j循环从1开始),找补回来一点了:
在这里插入图片描述
到这里影像投影完成了,再来美化一点点就是把它裁剪一下了:

outraster=e.OpenRaster(out_name)#out_name就是上面GLT校正完的影像SpatialRef = outraster.SPATIALREFSpatialRef.ConvertLonLatToMap, 80.0, 60.0, MapX, MapYSpatialRef.ConvertLonLatToMap, 200.0, -60.0, MapX2, MapY2subraster = outraster.Subset(SPATIALREF=SpatialRef,SUB_RECT=[MapX, MapY2, MapX2, MapY])

裁剪完输出一下:

subraster .Export,'****给个输出路径','ENVI'

到这里影像的投影就完事了,没别的需求的就不用往下看了。

.
.
.
别的需求就是生成角度数据集,具体就是:卫星天顶角、方位角,太阳天顶角、方位角。
但是这里都不讲这些,计算卫星天顶角、方位角看这:
https://blog.csdn.net/qq_33339770/article/details/103023725
计算太阳天顶角、方位角看这:
https://blog.csdn.net/qq_33339770/article/details/104710136
这里要对生成的坐标文件做一点处理,才能应用在角度数据集生成里,具体的操作就是:重投影+裁剪。
执行的步骤是和对影像的操作是一样的,先应用GLT投影成这样:
在这里插入图片描述
然后用上面的裁剪代码把它裁了,使同分辨率的坐标文件和同分辨率的影像完全贴合对应,这样就能作为角度数据集生成的输入文件来计算各个位置的卫星/太阳角度了。
.
.
.
一点废话
Himawari8官网还给出了经纬度反算行列号的代码,看图:
在这里插入图片描述
我也翻译成了IDL代码:

;经纬度转行列号function ll2cl,lon,lat,COFF,CFAC,LOFF,LFAC  COMPILE_OPT idl2  d2r=0.01745329252d  r2d=57.295779513d  scal=1d0/65536;2^(-16)=1/(2^16)  if lon gt 180.0 then begin    lon -= 360.0  endif  if lon lt -180.0 then begin    lon += 360.0  endif  ;phi = arctan( (Rpol^2)/(Req^2) * tan(lat) )  ;;rpol^2/req^2 =0.993305616  phi=atan(0.993305616 * tan(lat*d2r))  ;Re = (Rpol) / sqrt( 1 - (Req^2 - Rpol^2) / Req^2 * cos^2(phi) )  ;;earth's polar radius=6356.7523km  Re=6356.7523/sqrt(1- 0.00669438444*cos(phi)*cos(phi))  ;'Distance from Earth's center to virtual satellite' =42164km  ;sub_lon=140.7  r1=42164-Re*cos(phi)*cos(lon*d2r-140.7*d2r)  r2=-Re*cos(phi)*sin(lon*d2r-140.7*d2r)  r3=Re*sin(phi)  if r1*(r1-42164)+(r2*r2)+(r3*r3) le 0 then begin    rn=sqrt(r1*r1+r2*r2+r3*r3)    x=atan2(r1,-r2)*r2d    y=asin(-r3/rn)*r2d    c=long(COFF + x * CFAC * scal)    l=long(LOFF + y * LFAC * scal)    return,[c,l]  endifEND

但是我用代码试了,反算不回去ORZ,有0.2到0.5的差。

转载地址:https://blog.csdn.net/qq_33339770/article/details/102957857 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:IDL处理葵花8Himawari-8标准HSD数据——制作大气校正数据集(卫星角度数据)
下一篇:python读取Himawari-8葵花8标准数据(HSD)

发表评论

最新留言

不错!
[***.144.177.141]2024年03月31日 08时33分04秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

大数据_Hbase-API访问_Java操作Hbase_MR-数据迁移-代码测试---Hbase工作笔记0017 2019-04-26
大数据_Hbase-内容回顾和补充---Hbase工作笔记0018 2019-04-26
大数据_Hbase-内容回顾_知识点补充_线程安全与wait的区别---Hbase工作笔记0019 2019-04-26
大数据_Hbase-Filter & 索引(优化)_根据column查询---Hbase工作笔记0020 2019-04-26
大数据_MapperReduce_从CSV文件中读取数据到Hbase_自己动手实现Mapper和Reducer---Hbase工作笔记0021 2019-04-26
大数据_MapperReduce_协处理器_类似Mysql的触发器---Hbase工作笔记0024 2019-04-26
大数据_MapperReduce_Hbase的优化_存数据_自动计算分区号 & 自动计算分区键---Hbase工作笔记0027 2019-04-26
大数据_MapperReduce_Hbase的优化_RowKey设计原则---Hbase工作笔记0028 2019-04-26
大数据_MapperReduce_Hbase的优化和Hbase相关面试题_以及hbase的javaapi的一部分源码---Hbase工作笔记0029 2019-04-26
大数据_MapperReduce_Hbase配置参数说明_以及部分源码说明---Hbase工作笔记0031 2019-04-26
Vue介绍---vue工作笔记0001 2019-04-26
Vue基本使用---vue工作笔记0002 2019-04-26
微信公众号介绍_以及注册订阅号---微信公众号开发工作笔记0001 2019-04-26
Vue模板语法---vue工作笔记0003 2019-04-26
Vue计算属性之基本使用---vue工作笔记0004 2019-04-26
Vue监视---vue工作笔记0005 2019-04-26
Vue条件渲染---vue工作笔记0008 2019-04-26
Vue事件处理_vue的事件处理超级方便_功能强大---vue工作笔记0011 2019-04-26
Vue表单数据自动收集---vue工作笔记0012 2019-04-26
Vue生命周期---vue工作笔记0013 2019-04-26