自动化SAR强度分析

在工作的 20 多年中,我处理过许多不同的数据类型和数据模式,但对合成孔径雷达 (SAR) 的了解并不多。直到最近几年,我发现人们对 SAR 数据的兴趣越来越大,这部分归功于免费提供的 Sentinel-1 数据以及更多商业化的高分辨率 SAR 小型卫星。因此,我决定是时候冒险一试,将 SAR 数据添加到我的技能包中。在学习ENVI SARscape 教程中的 Sentinel-1 强度分析时,我想到编写一个自动执行这些步骤的程序将是一个很好的学习练习。

SAR 强度分析用于多种应用,例如检测浮油、研究植被以及使用多个图像随时间监测植被。在提取多张强度图像时,自动提取强度产品特别有用,因为它可以提高处理速度并减少按钮点击次数。

我使用 IDL 8.8.2、ENVI5.6.2 和SARscape5.6.2编写了这个程序。数据可从如下链接获取,下载后解压到本地目录。

链接:https://pan.baidu.com/s/1wsLJO0DQUZTiejuPFvTZUQ?pwd=envi

提取码:envi

SARscape5.6.2软件的试用请浏览:https://www.cnblogs.com/enviidl/p/16266813.html 

运行程序:

  • 将下面的代码复制到名为“sar_intensityanalysis.pro”的文件中,在IDL上方工具栏点击编译按钮。
  • 在 IDL 命令提示符下执行以下命令:
IDL> sar_intensityanalysis

运行该程序后,系统将提示您选择数据目录。sar_intensityanalysis 有两个输入关键字。有关这些关键字的信息,请参阅pro例程的开头注释。

;------------------------------------------------------------------------------
;+
; This helper routine allows the user to toggle between two ENVIRasterLayers
; in the ENVI display.
;-
pro SAR_ToggleLayers, eLayer, $
  DESCRIPTION=desc, $
  DESTROY=destroy, $
  END_DESCRIPTION=descEnd, $
  TITLE=title, $
  TOP_LEVEL_BASE=tlb
  compile_opt idl2, logical_predicate
  if (n_elements(eLayer) NE 2) then begin
    print, 'Invalid input: ELAYER must contain two ENVIRASTERLAYERs'
    return
  endif
  for i = 0, 1 do eLayer[i]->SetProperty, HIDE=i
  if ((n_elements(tlb) EQ 0) || ~widget_info(tlb, /VALID_ID)) then begin
    e = envi(/CURRENT)
    e->GetProperty, WIDGET_ID=wENVI
    tlb = widget_base(/COLUMN, GROUP_LEADER=wENVI, /FLOATING, $
      TITLE='Intensity Data', TLB_FRAME_ATTR=9)
    wBase = widget_base(tlb, /ALIGN_CENTER, /ROW)
    wLabel = widget_label(wBase, /DYNAMIC_RESIZE, UNAME='label', VALUE=' ')
    wBaseControl = widget_base(tlb, /COLUMN, UNAME='controls', XPAD=0, YPAD=0)
    wBase = widget_base(wBaseControl, /EXCLUSIVE, /ROW)
    wButton = [ $
      widget_button(wBase, VALUE='cross-polarized (VH)', UNAME='button_0', UVALUE=eLayer[0]), $
      widget_button(wBase, VALUE='co-polarized (VV)', UNAME='button_1', UVALUE=eLayer[1])]
    widget_control, wButton[0], /SET_BUTTON
    wBase = widget_base(wBaseControl, /ALIGN_RIGHT, /ROW)
    wButtonClose = widget_button(wBase, UNAME='button_continue', VALUE='Continue')
    widget_control, tlb, /REALIZE
  endif else begin
    widget_control, tlb, /MAP
    wBaseControl = widget_info(tlb, FIND_BY_UNAME='controls')
    wLabel = widget_info(tlb, FIND_BY_UNAME='label')
    wButton = [widget_info(tlb, FIND_BY_UNAME='button_0'), $
      widget_info(tlb, FIND_BY_UNAME='button_1')]
    wButtonClose = widget_info(tlb, FIND_BY_UNAME='button_continue')
  endelse
  widget_control, wBaseControl, /SENSITIVE
  for i = 0, 1 do widget_control, wButton[i], SET_BUTTON=(1-i)
  if (n_elements(title) EQ 1) then widget_control, tlb, BASE_SET_TITLE=title
  widget_control, wLabel, SET_VALUE=((n_elements(desc) GT 0) ? desc[0] : ' ')
  if keyword_set(destroy) then widget_control, wButtonClose, SET_VALUE='Close'
  active = !true
  while (active) do begin
    sEvent = widget_event(tlb, /NOWAIT)
    switch sEvent.id of
      wButton[0]: index = 0
      wButton[1]: begin
        if (sEvent.select EQ 1) then begin
          if (n_elements(index) EQ 0) then index = 1
          eLayer[index]->SetProperty, HIDE=0
          eLayer[1-temporary(index)]->SetProperty, HIDE=1
        endif else [] = temporary(index)
        break
      end

      wButtonClose: begin
        active = !false
        break
      end

      else:
    endswitch
  endwhile
  if keyword_set(destroy) then begin
    widget_control, tlb, /DESTROY
  endif else begin
    widget_control, wBaseControl, SENSITIVE=0
    if (n_elements(descEnd) GT 0) then begin
      widget_control, wLabel, SET_VALUE=descEnd[0]
    endif
  endelse
end

;------------------------------------------------------------------------------
;+
; This program performs all of the steps done in the Sentinel-1 Intensity
; Analysis in ENVI SARscape Tutorial
;
; :Keywords:
;   DIRECTORY: in, optional, type="string"
;     Set this to the full path of the directory containing the tutorial data.
;     If this is not set, a dialog will be presented for the user to select
;     this folder.
;   SHOW_TOGGLE_DIALOG: in, optional, type="boolean"
;     Set this keyword to have a dialog displayed that will cause the halt
;     execution at the end of each step.  The dialog will allow the user to
;     toggle between the VH and VV data in the ENVI display.
;
;-
pro SAR_IntensityAnalysis, $
  DIRECTORY=dirRoot, $
  SHOW_TOGGLE_DIALOG=showDialog
  compile_opt idl2, logical_predicate
  err = 0
  catch, err
  if (err NE 0) then begin
    catch, /CANCEL
    help, /LAST_MESSAGE
    return
  endif
  if (n_elements(dirRoot) EQ 0) then begin
    dirRoot = dialog_pickfile(/DIRECTORY, /MUST_EXIST, $
      TITLE='Select the Tutorial Data Directory')
  endif
  ;
  ; Open and display the raw intensity data.
  ;
  file = filepath('sentinel1_83_20171212_095750732_IW_SIW1_D_'+['VH','VV']+'_slc_list_pwr', $
    ROOT_DIR=dirRoot, SUBDIR='2017-12-12-SLC-Power')
  if ~(total(file_test(file, /REGULAR)) EQ 2) then begin
    print, 'Input directory is missing data files'
    return
  endif
  e = envi(/CURRENT)
  if ~obj_valid(e) then e = envi()
  eView = e->GetView()
  eRaster = [e->OpenRaster(file[0]), e->OpenRaster(file[1])]
  eLayer = [eView->CreateLayer(eRaster[0]), eView->CreateLayer(eRaster[1])]
  eView->Zoom, LAYER=eLayer[0], /FULL_EXTENT
  if keyword_set(showDialog) then begin
    SAR_ToggleLayers, eLayer, END_DESCRIPTION='Creating subset...', $
      TITLE='Raw Intensity Data', TOP_LEVEL_BASE=tlb
  endif
  ;
  ; Create spatial subsets of the VH and VV intensity images.
  ;
  fileAOI = filepath('StudySite.shp', ROOT_DIR=dirRoot)
  fileCut = filepath(file_basename(file)+'_cut', ROOT_DIR=dirRoot)
  eTaskCut = envitask('SARsToolsManualSelection')
  eTaskCut.input_sarscapedata = file
  eTaskCut.cut_shape_file = fileAOI
  eTaskCut.output_sarscapedata = fileCut
  eTaskCut.cut_is_georeferenced = !false
  eTaskCut.USE_only_shape_corners = !true
  eTaskCut.sarscape_preference = 'Sentinel TOPSAR (IW - EW)'
  eTaskCut->Execute
  eRasterCut = [e->OpenRaster(fileCut[0]), e->OpenRaster(fileCut[1])]
  eLayerCut = [eView->CreateLayer(eRasterCut[0]), $
    eView->CreateLayer(eRasterCut[1])]
  eView->Zoom, LAYER=eLayerCut[0], /FULL_EXTENT
  for i = 0, 1 do eLayer[i]->Close
  if keyword_set(showDialog) then begin
    SAR_ToggleLayers, eLayerCut, END_DESCRIPTION='Filtering data...', $
      TITLE='Cut Intensity Data', TOP_LEVEL_BASE=tlb
  endif
  ;
  ; Apply a filter to reduce speckling noise in the VH and VV images.
  ;
  fileFilter = filepath(file_basename(fileCut)+'_fil', ROOT_DIR=dirRoot)
  eTaskFilter = envitask('SARsWF_ToolsGenericFilterSingleImage')
  eTaskFilter.filt_type = 'Gamma APM'
  eTaskFilter.sarscape_preference = 'Sentinel TOPSAR (IW - EW)'
  for i = 0, 1 do begin
    eTaskFilter.input_sarscapedata = fileCut[i]
    eTaskFilter.output_sarscapedata = fileFilter[i]
    eTaskFilter->Execute
  endfor
  eRasterFilter = [e->OpenRaster(fileFilter[0]), e->OpenRaster(fileFilter[1])]
  eLayerFilter = [eView->CreateLayer(eRasterFilter[0]), $
    eView->CreateLayer(eRasterFilter[1])]
  for i = 0, 1 do eLayerCut[i]->SetProperty, HIDE=1
  if keyword_set(showDialog) then begin
    SAR_ToggleLayers, eLayerFilter, $
      END_DESCRIPTION='Geocoding and radiometric correction...', $
      TITLE='Filtered Cut Data', TOP_LEVEL_BASE=tlb
  endif
  ;
  ; Create a DEM file for georeferencing.
  ;
  fileDEM = filepath(file_basename(fileFilter[0])+'_srtm3_dem', ROOT_DIR=dirRoot)
  eTaskDEM = envitask('SARsToolsDEMExtractionSRTM4')
  eTaskDEM.output_cartographic_system = ['GEO-GLOBAL','','GEO','','WGS84','','0.00']
  eTaskDEM.reference_sarscapedata = fileFilter
  eTaskDEM.output_sarscapedata = fileDEM
  eTaskDEM.sarscape_preference = 'Sentinel TOPSAR (IW - EW)'
  eTaskDEM->Execute
  ;
  ; Georeference the VH and VV images to a standard map projection, also called
  ; geocoding. As part of this step, radiometric calibration and normalization
  ; also will be done.
  ;
  fileGeo = filepath(file_basename(fileFilter)+'_geo', ROOT_DIR=dirRoot)
  eTaskGeo = envitask('SARsBasicGeocoding')
  eTaskGeo.input_sarscapedata = fileFilter
  eTaskGeo.output_sarscapedata = fileGeo
  eTaskGeo.sarscape_preference = 'Sentinel TOPSAR (IW - EW)'
  eTaskGeo.dem_sarscapedata = fileDEM
  eTaskGeo->Execute
  eRasterGeo = [e->OpenRaster(fileGeo[0]), e->OpenRaster(fileGeo[1])]
  eLayerGeo = [eView->CreateLayer(eRasterGeo[0]), $
    eView->CreateLayer(eRasterGeo[1])]
  eView->Zoom, LAYER=eLayerGeo[0], /FULL_EXTENT
  foreach eLayerClose, [eLayerCut,eLayerFilter] do eLayerClose->Close
  if keyword_set(showDialog) then begin
    SAR_ToggleLayers, eLayerGeo, /DESTROY, $
      TITLE='Georeferenced Images', TOP_LEVEL_BASE=tlb
  endif
  ;
  ; Create a color composite image from the VH and VV images.
  ;
  fileColor = filepath(file_basename(fileGeo[0])+'_color', ROOT_DIR=dirRoot)
  vh = eRasterGeo[0]->GetData()
  vv = eRasterGeo[1]->GetData()
  dim = size(vh, /DIMENSIONS)
  rgb = fltarr(dim[0],dim[1],3)
  rgb[*,*,0] = vv
  rgb[*,*,1] = vh
  rgb[*,*,2] = vv/vh
  eRasterColor = enviraster(rgb, URI=fileColor)
  eRasterColor->Save
  eLayerColor = eView->CreateLayer(eRasterColor)
  eView->Zoom, LAYER=eLayerColor, /FULL_EXTENT
  for i = 0, 1 do eLayerGeo[i]->SetProperty, HIDE=1
end

此示例演示了以编程方式调用ENVI SARscape任务以自动运行强度分析。如果您正在寻找 SAR 数据的自动化工作流程,ENVI SARscape Analytics将引导用户完成使用 SAR 数据执行的一些最常见的处理任务。而且,如果您认为可以使用 SAR 数据解决问题,请联系我们——我们可以与您合作,根据您的特定项目要求创建自定义工作流。

作者:Daryl Atencio

翻译、代码校验:马宇龙

posted @ 2023-01-03 17:23  ENVI-IDL技术殿堂  阅读(585)  评论(0编辑  收藏  举报