利用IDL二次开发编写Envi扩展工具进行河流边滩提取的实验操作
程序员文章站
2022-05-21 21:28:54
...
河流边滩提取
该实验是学长学姐比赛的,老师给我们试试手,纯粹为学习用,不为任何商业用途[/滑稽]
主要是调用ENVITASK进行编写二次开发工具
河流边滩:指与河岸相连的,枯水期裸露出来,丰水期淹没的泥沙淤积体
实验思路:
利用枯水期和丰水期光学遥感影像进行预处理,再计算MNDWI(修正归一化水体差异指数),再确定阈值,对MNDWI二值化,水体为1,非水体为0,因为部分水洼等与河流反射特性相同,所以值为1的既有河流也有陆地上的水,因此再利用面向对象分类提取河道,形态学滤波过滤细碎像元,最后将丰水期河道与枯水期河道相减,得到河流边滩,最后矢量化,完成。
成果展示:
数据准备(预处理后的影像):
丰水:
枯水:
点击(已建好的ENVI拓展):
打开(选择要处理的两幅影像并输入二值化的阈值):
开始运行:
输入规则文件(输入两次):在这里插入图片描述
选择输出结果路径:
作品成果(河流边滩提取后的矢量化图):
放大看:
ENVI拓展程序:
主程序源码:
pro tests,higwater=higwater,$
lowwater=lowwater,$
higthreshold=higthreshold,$
lowthreshold=lowthreshold
;
rulewater=rulewater
COMPILE_OPT idl2
;-----MNDWI计算------
higmndwi=MNDWI(higwater)
lowmndwi=MNDWI(lowwater)
;-----MNDWI的二值化-----
higtwo=TWOVALUE(raster=higmndwi,higthreshold)
lowtwo=TWOVALUE(raster=lowmndwi,lowthreshold)
;------------------分类出浅滩------------------------
;
-----------形态学滤波---------
higfil=DO_FILTER(raster=higtwo)
lowfil=DO_FILTER(raster=lowtwo)
;-----面向对象规则分类提取河道----
higobj=FACEOBJ(higfil)
lowobj=FACEOBJ(lowfil)
;-----河流浅滩提取------
diff=DIFFERENT(lowobj,higobj)
;----自动阈值分割------
fenge=AUTOFENGGE(diff)
;-----转换为矢量文件-----
shp=CLASSTOSHAPE(fenge)
;显示
e=ENVI(/current)
View1 = e.GETVIEW()
Layer1 = View1.CREATELAYER(shp)
;删除缓存图像
IF STRMATCH(output_raster_uri,'*envitempfile*') THEN BEGIN
;
dataCol = e.DATA
dataCol.REMOVE, ClassRaster, error=err
ENDIF
END
;------------MNDWI-----------------------------
FUNCTION MNDWI,raster
e=ENVI(/current)
Task=ENVITASK('SpectralIndex')
; 定义输入
Task.INDEX = 'Modified Normalized Difference Water Index'
Task.INPUT_RASTER = raster
; 定义输出
Task.OUTPUT_RASTER_URI = e.GETTEMPORARYFILENAME()
; 执行task
Task.EXECUTE
; Get the
data collection
DataColl = e.DATA
DataColl.ADD, Task.OUTPUT_RASTER
Raster = Task.OUTPUT_RASTER
RETURN,Raster
END
;------------二值化--------------------
FUNCTION TWOVALUE,raster=higmndwi,t=t,thresholdwater
e=ENVI(/current)
Task = ENVITASK('BinaryGTThresholdRaster')
Task.INPUT_RASTER = higmndwi
Task.THRESHOLD = [thresholdwater]
; Define
outputs
Task.OUTPUT_RASTER_URI = e.GETTEMPORARYFILENAME()
Task.EXECUTE; Run the task
DataColl = e.DATA
DataColl.ADD, Task.OUTPUT_RASTER
raster=Task.OUTPUT_RASTER
RETURN,raster
END
;-----------------形态滤波-----------------
FUNCTION DO_FILTER,raster=raster
e = ENVI(/current)
OutFile = e.GETTEMPORARYFILENAME()
fid = ENVIRASTERTOFID(Raster)
; Apply an
open morphological filter.
ENVI_FILE_QUERY, fid, DIMS=dims, NB=nb
ENVI_DOIT,'Morph_Doit',$
FID = fid, $
DIMS = dims, $
POS = LINDGEN(nb), $
METHOD = 2, $
GRAY = 1,$
KERNEL = FLTARR(3,3)+1 , $
OUT_NAME = OutFile, $
R_FID = r_fid
; Pass the
R_FID to an ENVIRaster object.
OutRaster = ENVIFIDTORASTER(R_FID)
RETURN,OutRaster
END
;--------------------面向对象-------------------
FUNCTION FACEOBJ,raster
COMPILE_OPT IDL2
e = ENVI(/current)
fid = ENVIRASTERTOFID(raster)
rule_file=DIALOG_PICKFILE(title='请输入规则文件')
; Set
output filenames
newFile = e.GETTEMPORARYFILENAME()
temp_dir = NEWFILE
report_filename = temp_dir+'report2.txt'
confidence_raster_filename = temp_dir+'confidence2.dat'
classification_raster_filename = temp_dir+'class2.dat'
segmentation_raster_filename = temp_dir+'segmentation2.dat'
; Set the
keywords.
dims = [-1L, 0, raster.NCOLUMNS-1, 0, raster.NROWS-1] ;范围
pos = LINDGEN(raster.NBANDS); process all bands ;波段数
; Perform
rule-based classification
ENVI_DOIT, 'envi_fx_rulebased_doit', $
fid=fid, pos=pos, dims=dims, $
r_fid=r_fid, $
merge_level=80, $
scale_level=40.0, $
rule_filename=rule_file, $
segmentation_raster_filename=segmentation_raster_filename, $
report_filename=report_filename, $
confidence_raster_image=confidence_raster_filename, $
classification_raster_filename=classification_raster_filename
; get the
returned file ID (R_FID)
segmentation_raster = ENVIFIDTORASTER(r_fid)
segmentation_raster_URI =
segmentation_raster.URI
raster2 = e.OPENRASTER(classification_raster_filename)
RETURN,raster2
END
;----------------差值---------------------------
FUNCTION DIFFERENT,image1,image2
e=ENVI(/current)
; Get the
task from the catalog of ENVITasks
Task = ENVITASK('ImageBandDifference')
; Define
inputs
Task.INPUT_RASTER1 = Image1
Task.INPUT_RASTER2 = Image2
; Define
outputs
Task.OUTPUT_RASTER_URI = e.GETTEMPORARYFILENAME()
; Run the
task
Task.EXECUTE
; Get the
data collection
DataColl = e.DATA
; Add the
output to the data collection
DataColl.ADD, Task.OUTPUT_RASTER
raster=Task.OUTPUT_RASTER
RETURN,raster
END
;--------------------自动阈值分割------------------
FUNCTION AUTOFENGGE,img1
; Start the
application
e = ENVI(/current)
newfile = e.GETTEMPORARYFILENAME()
; IF FILE_TEST(newFile) THEN FILE_DELETE,
newFile
; Get the
task from the catalog of ENVITasks
ChangeThresholdTask = ENVITASK('ChangeThresholdClassification')
; Define
inputs
ChangeThresholdTask.INPUT_RASTER =
img1
; Define
outputs
ChangeThresholdTask.OUTPUT_RASTER_URI
=newFile
; Define
increase and/or decrease values
ChangeThresholdTask.INCREASE_THRESHOLD
= 0.5
ChangeThresholdTask.DECREASE_THRESHOLD
= 1.
; Run the
task
ChangeThresholdTask.EXECUTE
; Get the
data collection
DataColl = e.DATA
; Add the
output to the data collection
DataColl.ADD, ChangeThresholdTask.OUTPUT_RASTER
Raster=ChangeThresholdTask.OUTPUT_RASTER
RETURN,raster
END
;---------------转矢量----------------
FUNCTION CLASSTOSHAPE,img1
e=ENVI(/current)
newFile = ENVI_PICKFILE(title='输出矢量文件',/output)
newfile=newfile+'.shp'
ClassToVectorTask = ENVITASK('ClassificationToShapefile')
; Define
inputs
ClassToVectorTask.INPUT_RASTER = img1
; Define
outputs
ClassToVectorTask.OUTPUT_VECTOR_URI
= newfile
; Run the
task
ClassToVectorTask.EXECUTE
RETURN,ClassToVectorTask.OUTPUT_VECTOR
END
调用程序:
ui=e.UI
task = ENVITASK('beachtoextract')
r = ui.SELECTTASKPARAMETERS(task)
IF r NE 'OK' THEN RETURN
task.EXECUTE
自定义ENVITask参数文件:
{
"name":"beachtoextract",
"baseClass":"ENVITaskFromProcedure",
"routine":"tests",
"displayName":"Indies4Classify",
"version":"5.3",
"description":"This task performs Classification via NDVI and
CRI2.",
"parameters":[
{
"name":"higwater",
"displayName":"many water raster",
"dataType":"ENVIRaster",
"direction":"input",
"parameterType":"required",
"description":"Specify the input raster."
},
{
"name":"lowwater",
"displayName":"less water raster",
"dataType":"ENVIRaster",
"direction":"input",
"parameterType":"required",
"description":"Specify the input raster."
},
{
"name":"higthreshold",
"displayName":"higthreshold",
"dataType":"double",
"direction":"input",
"parameterType":"required",
"description":"Specify the threshold value.",
"defaultValue":0.18
},
{
"name":"lowthreshold",
"displayName":"lowthreshold",
"dataType":"double",
"direction":"input",
"parameterType":"required",
"description":"Specify the threshold value.",
"defaultValue":0.24
}
]
}
遥感菜菜一枚,第一次发这种学习类的博客,请多指教