;=====================================================================================
; 水体动态变化遥感监测系统 - 增强版
; 功能:
; 1. 基于ENVI二次开发的水体提取
; 2. 多时相水体变化检测
; 3. 变化统计与可视化
; 4. 结果导出功能
; 使用方法:在ENVI+IDL环境中编译运行
;=====================================================================================
; 主程序入口
PRO WaterMonitoring_System
COMPILE_OPT idL2
; 检查ENVI环境
IF ~ISA(ENVI(/HEADLESS)) THEN BEGIN
MESSAGE, '请确保在ENVI环境中运行此程序'
RETURN
ENDIF
; 创建ENVI风格的UI
envi_create_widget, '水体动态监测系统', tlb, /FLOAT, $
WIDTH=800, HEIGHT=600, /NO_OFFSET
; 添加菜单栏
menu_bar = WIDGET_BASE(tlb, /MENU_BAR)
file_menu = WIDGET_BUTTON(menu_bar, VALUE='文件', /MENU)
WIDGET_CONTROL, file_menu, MENU_ADD=WIDGET_BUTTON(file_menu, VALUE='打开影像...', $
UVALUE='open_image')
WIDGET_CONTROL, file_menu, MENU_ADD=WIDGET_BUTTON(file_menu, VALUE='退出', $
UVALUE='exit')
process_menu = WIDGET_BUTTON(menu_bar, VALUE='处理', /MENU)
WIDGET_CONTROL, process_menu, MENU_ADD=WIDGET_BUTTON(process_menu, VALUE='计算NDWI', $
UVALUE='calc_ndwi')
WIDGET_CONTROL, process_menu, MENU_ADD=WIDGET_BUTTON(process_menu, VALUE='变化检测', $
UVALUE='change_detect')
; 主界面布局
main_base = WIDGET_BASE(tlb, /COLUMN, FRAME=1, SPACE=5)
; 影像选择区域
file_group = WIDGET_BASE(main_base, /ROW, FRAME=1, TITLE='影像选择')
WIDGET_CONTROL, file_group, SET_BUTTON=1
file_label = WIDGET_LABEL(file_group, VALUE='影像文件:')
file_text = WIDGET_TEXT(file_group, XSIZE=50)
file_button = WIDGET_BUTTON(file_group, VALUE='浏览...')
; 波段选择区域
band_group = WIDGET_BASE(main_base, /ROW, FRAME=1, TITLE='波段选择')
WIDGET_CONTROL, band_group, SET_BUTTON=1
green_label = WIDGET_LABEL(band_group, VALUE='绿波段:')
green_combo = WIDGET_DROPLIST(band_group, /EDITABLE)
nir_label = WIDGET_LABEL(band_group, VALUE='近红外波段:')
nir_combo = WIDGET_DROPLIST(band_group, /EDITABLE)
; 参数设置区域
param_group = WIDGET_BASE(main_base, /ROW, FRAME=1, TITLE='参数设置')
WIDGET_CONTROL, param_group, SET_BUTTON=1
thresh_label = WIDGET_LABEL(param_group, VALUE='水体阈值:')
thresh_slider = WIDGET_SLIDER(param_group, MINIMUM=0.0, MAXIMUM=1.0, VALUE=0.2, $
XSIZE=200, /FLOAT)
thresh_text = WIDGET_TEXT(param_group, VALUE='0.2', XSIZE=5)
; 结果显示区域
result_group = WIDGET_BASE(main_base, /ROW, FRAME=1, TITLE='结果')
WIDGET_CONTROL, result_group, SET_BUTTON=1
result_label = WIDGET_LABEL(result_group, VALUE='水体面积:')
result_text = WIDGET_TEXT(result_group, VALUE='', XSIZE=15, /READ_ONLY)
unit_label = WIDGET_LABEL(result_group, VALUE='平方公里')
; 按钮区域
button_group = WIDGET_BASE(main_base, /ROW)
calc_button = WIDGET_BUTTON(button_group, VALUE='计算')
export_button = WIDGET_BUTTON(button_group, VALUE='导出结果')
; 显示窗口
WIDGET_CONTROL, tlb, /REALIZE
; 事件循环
XMANAGER, 'WaterMonitoring_System', tlb, /NO_BLOCK
END
; 计算NDWI
PRO ComputeNDWI_Wrapper
COMPILE_OPT idL2
; 获取UI控件值
WIDGET_CONTROL, file_text, GET_VALUE=filename
WIDGET_CONTROL, green_combo, GET_VALUE=green_band
WIDGET_CONTROL, nir_combo, GET_VALUE=nir_band
WIDGET_CONTROL, thresh_slider, GET_VALUE=threshold
; 检查输入
IF (filename EQ '') THEN BEGIN
MESSAGE, '请选择输入影像文件!'
RETURN
ENDIF
; 使用ENVI DOIT处理
envi_doit, 'ENVI_OPEN_FILE', FID=fid, /IN_MEMORY, $
INPUT=filename, /NO_REALIZE
IF (fid EQ -1) THEN RETURN
; 获取波段信息
envi_doit, 'ENVI_FILE_QUERY', FID=fid, NS=ns, NL=nl, NB=nb, $
DIMS=dims, /NO_REALIZE
; 计算NDWI
envi_doit, 'NDWI_DOIT', FID=fid, GREEN_BAND=green_band, $
NIR_BAND=nir_band, OUT_NAME='NDWI_Result', $
/IN_MEMORY, /NO_REALIZE
; 二值化提取水体
envi_doit, 'ENVI_THRESHOLD_DOIT', INPUT='NDWI_Result', $
THRESHOLD=threshold, VALUE=1, OUT_NAME='Water_Mask', $
/IN_MEMORY, /NO_REALIZE
; 计算水体面积
envi_doit, 'ENVI_STATISTICS_DOIT', INPUT='Water_Mask', $
POS=0, /NO_REALIZE, STATS=stats
water_pixels = stats[1] ; 假设1表示水体
pixel_size = envi_get_pixel_size(fid)
water_area = water_pixels * pixel_size[0] * pixel_size[1] / 1e6 ; 转换为平方公里
; 更新UI显示
WIDGET_CONTROL, result_text, SET_VALUE=STRTRIM(STRING(water_area, FORMAT='(F10.2)'), 2)
; 显示结果
envi_doit, 'ENVI_DISPLAY', DATA='NDWI_Result', /ADD_TO_NEW, /NO_REALIZE
envi_doit, 'ENVI_DISPLAY', DATA='Water_Mask', /ADD_TO_NEW, /NO_REALIZE
; 添加ROI用于可视化
envi_doit, 'ENVI_CONVERT_TO_ROI', INPUT='Water_Mask', $
VALUE=1, ROI_NAME='Water_Area', COLOR='blue', /NO_REALIZE
END
; 多时相变化检测
PRO ChangeDetection_Wrapper
COMPILE_OPT idL2
; 获取两个时相的影像
file1 = DIALOG_PICKFILE(TITLE='选择第一期影像')
file2 = DIALOG_PICKFILE(TITLE='选择第二期影像')
IF (file1 EQ '' OR file2 EQ '') THEN RETURN
; 处理第一期影像
envi_doit, 'ENVI_OPEN_FILE', FID=fid1, /IN_MEMORY, $
INPUT=file1, /NO_REALIZE
envi_doit, 'NDWI_DOIT', FID=fid1, GREEN_BAND=green_band, $
NIR_BAND=nir_band, OUT_NAME='NDWI_Time1', $
/IN_MEMORY, /NO_REALIZE
envi_doit, 'ENVI_THRESHOLD_DOIT', INPUT='NDWI_Time1', $
THRESHOLD=threshold, VALUE=1, OUT_NAME='Water_Mask1', $
/IN_MEMORY, /NO_REALIZE
; 处理第二期影像
envi_doit, 'ENVI_OPEN_FILE', FID=fid2, /IN_MEMORY, $
INPUT=file2, /NO_REALIZE
envi_doit, 'NDWI_DOIT', FID=fid2, GREEN_BAND=green_band, $
NIR_BAND=nir_band, OUT_NAME='NDWI_Time2', $
/IN_MEMORY, /NO_REALIZE
envi_doit, 'ENVI_THRESHOLD_DOIT', INPUT='NDWI_Time2', $
THRESHOLD=threshold, VALUE=1, OUT_NAME='Water_Mask2', $
/IN_MEMORY, /NO_REALIZE
; 计算变化
envi_doit, 'ENVI_MATH_DOIT', EXPRESSION='Water_Mask2 - Water_Mask1', $
OUT_NAME='Water_Change', /IN_MEMORY, /NO_REALIZE
; 显示变化结果
envi_doit, 'ENVI_DISPLAY', DATA='Water_Change', /ADD_TO_NEW, /NO_REALIZE
; 添加变化图例
envi_doit, 'ENVI_LOAD_COLORS', INPUT='Water_Change', $
COLORS=[[255,0,0], [0,0,255], [0,255,0]], /NO_REALIZE
envi_doit, 'ENVI_ADD_LEGEND', TITLE='水体变化', $
LABELS=['减少', '增加', '未变化'], /NO_REALIZE
; 计算变化统计
envi_doit, 'ENVI_STATISTICS_DOIT', INPUT='Water_Change', $
POS=0, /NO_REALIZE, STATS=change_stats
decreased = change_stats[0] ; -1表示水体减少
increased = change_stats[2] ; 1表示水体增加
; 显示统计结果
WINDOW, /FREE, XSIZE=400, YSIZE=300
PLOT, [0,1,2], [0, ABS(decreased), increased], /BAR, $
XTITLE='变化类型', YTITLE='像元数量', $
TITLE='水体变化统计', XTICKNAME=[' ', '减少', '增加', ' ']
END
; 导出结果
PRO ExportResults_Wrapper
COMPILE_OPT idL2
output_dir = DIALOG_PICKFILE(/DIRECTORY, TITLE='选择输出目录')
IF (output_dir EQ '') THEN RETURN
; 导出NDWI结果
IF (ENVI_QUERY_DATA('NDWI_Result') NE '') THEN BEGIN
envi_doit, 'ENVI_EXPORT_DATA', INPUT='NDWI_Result', $
OUTPUT=output_dir+'ndwi_result.dat', /NO_REALIZE
ENDIF
; 导出水体掩膜
IF (ENVI_QUERY_DATA('Water_Mask') NE '') THEN BEGIN
envi_doit, 'ENVI_EXPORT_DATA', INPUT='Water_Mask', $
OUTPUT=output_dir+'water_mask.dat', /NO_REALIZE
ENDIF
; 导出变化检测结果
IF (ENVI_QUERY_DATA('Water_Change') NE '') THEN BEGIN
envi_doit, 'ENVI_EXPORT_DATA', INPUT='Water_Change', $
OUTPUT=output_dir+'water_change.dat', /NO_REALIZE
ENDIF
MESSAGE, '结果已成功导出到: '+output_dir
END
; 事件处理程序
PRO WaterMonitoring_System_EVENT, event
COMPILE_OPT idL2
CASE event.ID OF
file_button: BEGIN
filename = DIALOG_PICKFILE(FILTER='*.dat;*.tif;*.img')
IF (filename NE '') THEN BEGIN
WIDGET_CONTROL, file_text, SET_VALUE=filename
; 自动填充波段信息
envi_doit, 'ENVI_OPEN_FILE', FID=fid, /IN_MEMORY, $
INPUT=filename, /NO_REALIZE
IF (fid NE -1) THEN BEGIN
envi_doit, 'ENVI_FILE_QUERY', FID=fid, NB=nb, /NO_REALIZE
bands = LINDGEN(nb)+1
WIDGET_CONTROL, green_combo, SET_VALUE=3, SET_DROPLIST_VALUE=STRARR(bands)
WIDGET_CONTROL, nir_combo, SET_VALUE=5, SET_DROPLIST_VALUE=STRARR(bands)
ENDIF
ENDIF
END
calc_button: ComputeNDWI_Wrapper
export_button: ExportResults_Wrapper
thresh_slider: BEGIN
WIDGET_CONTROL, thresh_slider, GET_VALUE=val
WIDGET_CONTROL, thresh_text, SET_VALUE=STRING(val, FORMAT='(F4.2)')
END
thresh_text: BEGIN
WIDGET_CONTROL, thresh_text, GET_VALUE=val
IF (VERIFY(val, '.0123456789') EQ -1) THEN $
WIDGET_CONTROL, thresh_slider, SET_VALUE=FLOAT(val)
END
; 菜单事件
'open_image': BEGIN
filename = DIALOG_PICKFILE(FILTER='*.dat;*.tif;*.img')
IF (filename NE '') THEN WIDGET_CONTROL, file_text, SET_VALUE=filename
END
'calc_ndwi': ComputeNDWI_Wrapper
'change_detect': ChangeDetection_Wrapper
'exit': WIDGET_CONTROL, event.TOP, /DESTROY
ENDCASE
END改善该代码使其按要求设计水体动态变化遥感监测的遥感可视化系统开发设计
要求有:IDL编程+ENVI二次开发(ENVI doit)+编写界面(ENVI界面)