IDL实现火灾监测与火点提取


基于白天的MODIS数据提取森林火点信息。MODIS数据为6个波段的ENVI格式文件,分别为第1、2、7波段表观反射率以及第21、31、32波段表观辐亮度数据,需要从MOD021KM或者MYD021KM数据中做波段提取与合成。


代码及过程:


主过程文件:

Pro Zhushan_fire_detection
 

  fn=dialog_pickfile(title='选择MODIS数据',get_path=work_dir)
  cd,work_dir
  envi_open_file,fn,r_fid=fid
  envi_file_query,fid,ns=ns,nl=nl,nb=nb,dims=dims,$
    data_type=data_type,interleave=interleave,offset=offset
  map_info=envi_get_map_info(fid=fid)

  ;read 1 2 7 bands
  ;rad21=envi_get_data(fid=fid,dims=dims,pos=0)
  ;rad21=envi_get_data(fid=fid,dims=dims,pos=0)
  ;rad21=envi_get_data(fid=fid,dims=dims,pos=0)
  ;rad21=envi_get_data(fid=fid,dims=dims,pos=0)

  ;rad31=envi_get_data(fid=fid,dims=dims,pos=1)
  ;rad32=envi_get_data(fid=fid,dims=dims,pos=2)
  ref1=envi_get_data(fid=fid,dims=dims,pos=0)
  ref2=envi_get_data(fid=fid,dims=dims,pos=1)
  ref7=envi_get_data(fid=fid,dims=dims,pos=2)
  ;read 21 31 32 bands
  rad21=envi_get_data(fid=fid,dims=dims,pos=3)
  rad31=envi_get_data(fid=fid,dims=dims,pos=4)
  rad32=envi_get_data(fid=fid,dims=dims,pos=5)

  ;brightness temporature
  wv=[3.99157,11.0121,12.0159]
  tcs=[0.9998646,0.995608,0.9997256]
  tci=[0.09262664,0.1302699,0.07181833]

  tb21=cal_tb(temporary(rad21),wv[0],tcs[0],tci[0])
  tb31=cal_tb(temporary(rad31),wv[1],tcs[1],tci[1])
  tb32=cal_tb(temporary(rad32),wv[2],tcs[2],tci[2])


  ;Cloud detect
  cloud=ref1+ref2 gt 0.9 or tb32 lt 265 $
    or (ref1+ref2 gt 0.7 and tb32 lt 285)
  ;Water detect
  NDVI=(ref2-ref1)/(ref2+ref1)
  water=ref2 lt 0.15 and ref7 lt 0.05 and ndvi lt 0
  ;Water
  mask=cloud eq 0 and water eq 0
  fire=bytarr(ns,nl)

  ;extract fire
  w=where((Tb21 gt 310 or (Tb21 gt 300 and Tb21-tb31 gt 20))$
    and mask eq 1,count)
  if count gt 0 then fire[w]=1

  pfire_locations=where(Tb21 gt 310 and Tb21-Tb31 gt 10 and $
    ref2 lt 0.3 and mask eq 1 and fire eq 0,count)

  if count gt 0 then begin
    window_size=7
    for i=0,count-1 do begin
      fire_flg=fire_dect(Tb21,Tb31,mask,pfire_locations[i],$
        window_size)
      if fire_flg eq 1 then fire[pfire_locations[i]]=1
    endfor
  endif

  ;save fire point to *.evf'
  fire_location=where(fire eq 1,count)
  if count gt 0 then begin

    print,'The Number of Fire Points:',count

    xf=fire_location mod ns
    yf=fire_location/ns

    envi_convert_file_coordinates,fid,xf,yf,xmap,ymap,/to_map


    ;creat '.evf'
    o_fn=dialog_pickfile(title='Save the Result of Fire Points Monitoring')
    evf_ptr=envi_evf_define_init(o_fn+'.evf',data_type=4,$
      projection=map_info.proj,layer_name='Detected fires')

    ;add fire points to evf file
    pts_fires=[transpose(xmap),transpose(ymap)]
    for i=0,count-1 do begin
      envi_evf_define_add_record,evf_ptr,pts_fires[*,i]
    endfor

    ;save and close
    evf_id=envi_evf_define_close(evf_ptr,/return_id)
    envi_evf_close,evf_id

    ;edit atributes of *.evf file
    attributes=replicate({Name:'Fire',ID:0L},count)

    for i=0,count-1 do attributes[i].id=i+1
    envi_write_dbf_file,o_fn+'.dbf',attributes

  endif else begin

    print,'Did not Detect the Fire Points'

  endelse

end

火点检测函数文件:

function fire_dect,Tb21,Tb31,mask,pfire_location,window_size
  ;fire points or not
  sz=size(mask)
  ns=sz[1] & nl=sz[2]
  
  ;coordinate transport
  colu=pfire_location mod ns;column
  row =pfire_location/ns    ;row
  ;the beginning and ending of background windows
  col_s=colu-window_size/2 > 0
  col_e=colu+window_size/2 < ns-1
  row_s=row-window_size/2 > 0
  row_e=row+window_size/2 < ns-1

  Tb21_pfire=Tb21[colu,row]
  Tb31_pfire=Tb31[colu,row]
  dif_Tb_pfire=Tb21_pfire-Tb31_pfire

  tTb21=Tb21[col_s:col_e,row_s:row_e]
  tTb31=Tb31[col_s:col_e,row_s:row_e]
  dif_Tb=tTb21-tTb31
  tmask=mask[col_s:col_e,row_s:row_e]

  mask_bfire=Tb21 gt 325 and dif_Tb gt 20
  w_bfire=where(mask_bfire eq 1,nbfire)
  w_background=where(tmask eq 1 and mask_bfire eq 0,nbackground)

  if nbackground gt 0 then begin

    mean_Tb21=mean(tTb21[w_background])
    mean_Tb31=mean(tTb31[w_background])
    mean_dif_Tb=mean(dif_Tb[w_background])

    MAD_Tb21=mean(abs(tTb21[w_background]-mean_Tb21))
    MAD_Tb31=mean(abs(tTb31[w_background]-mean_Tb31))
    MAD_dif_Tb=mean(abs(dif_Tb[w_background]-mean_dif_Tb))
    if nbfire gt 0 then begin
      MAD_Tb21_bfire=mean(abs(dif_Tb[w_bfire]-mean(tTb21[w_bfire])))
    endif else begin
      MAD_Tb21_bfire=0

    endelse

    if dif_Tb_pfire gt (mean_dif_Tb+3.5*MAD_dif_Tb)and $
      dif_Tb_pfire gt (mean_dif_Tb+6) and $
      Tb21_pfire gt (mean_Tb21+3*MAD_Tb21)and $
      (Tb31_pfire gt (mean_Tb31+MAD_Tb31-4) or MAD_Tb21_bfire gt 5)$
      eq 1 then begin
      return,1
    endif else begin
      return,0
    endelse

  endif else begin
    return,0
  endelse
end

亮温计算函数文件:

;coculate the lightness temperature of thermal 
function cal_tb,radiance,wv,tcs,tci

  C1=1.1910659e8
  C2=1.438833e4
  x1= wv*alog(1+c1/(wv^5*radiance))
  result=(C2/x1 - tci ) / tcs
  return,result
end

简书分享

你可能感兴趣的:(可视化开发语言,遥感,IDL)