跳转至

SAR 强度分析自动化

原文链接: https://www.nv5geospatialsoftware.com/Learn/Blogs/Blog-Details/automating-sar-intensity-analysis

6082 评价本文:

4.9

SAR 强度分析自动化

作者:Daryl Atencio 日期:2022年7月5日,星期二

在我于 NV5 Geospatial 工作的 20 多年里,我接触过很多不同类型和模态的数据,但对合成孔径雷达(SAR)数据接触不多。这种情况直到最近几年才有所改变,我注意到人们对 SAR 数据的兴趣日益增长,这部分归功于免费提供的 Sentinel-1 数据以及更多商业化的高分辨率 SAR 小卫星。因此,我决定是时候深入学习,将 SAR 数据纳入我的技能范畴了。在学习 Sentinel-1 Intensity Analysis ENVI SARscape 教程时,我想到编写一个程序来自动化这些步骤将是一个很好的学习练习。

SAR 强度分析可用于多种应用,例如检测浮油、研究植被以及利用多幅图像随时间监测植被变化。在提取多幅强度图像时,自动化强度产品的提取尤其有用,因为它能提高处理速度并减少手动操作。

我使用 IDL® 8.8.2 和 ENVI® 5.6.2 编写了这个程序。要复现此方法,您需要从 ENVI 教程 网页获取“SAR Getting Started”数据文件。首先,将数据解压缩到本地驱动器的新目录中。

运行程序的步骤:

  1. 将以下代码复制到名为 "sar_intensityanalysis.pro" 的文件中
  2. 在 IDL 命令提示符下执行以下命令:

IDL> sar_intensityanalysis

运行程序后,系统会提示您选择数据目录。sar_intensityanalysis 过程有两个输入关键字。有关这些关键字的信息,请参见程序头的说明。







;------------------------------------------------------------------------------

;+

; 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 是 NV5 Geospatial 的解决方案交付工程师。他获得了科罗拉多大学的应用数学硕士学位。他于 2000 年 6 月加入 NV5,担任技术支持工程师。他于 2008 年加入解决方案交付团队。在解决方案交付期间,他利用 IDL 和 ENVI 在无损检测、矿物分析、天气、农业和海啸预报等多个领域创建了定制解决方案。

标签:SARscape Sentinel

世界范围的冲击波 利用 SAR 数据预测山体滑坡