ENVI二次开发综述与代码分享
ENVI具备了丰富的二次开发功能函数接口,基本涵盖了ENVI下所有的功能,且通过IDL语言有输出助手(导出为COM或JAVA类)、Callable、IDLDrawWidget和COM_IDL_CONNECT等多种方式与其他语言进行集成。
遥感与GIS一体化的应用模式如下:
下表对ENVI二次开发中常用的功能代码进行汇总。
功 能
|
源码名称
|
初始化ENVI
|
startENVI.pro
|
定标
|
cal_calibration.pro
|
大气校正
|
cal_quac.pro
|
融合
|
cal_sharpen.pro
|
镶嵌
|
cal_mosaic.pro
|
裁剪
|
cal_subset.pro
|
分类(监督+非监督)
|
cal_class.pro
|
面向对象特征提取
|
cal_fx.pro
|
结束ENVI
|
endENVI.pro
|
二次开发的基本流程框架图如下:
附各个模块的源代码
初始化ENVI
;+
;ENVI二次开发功能代码
;
;Author: DYQ
;问题讨论:
; http://hi.baidu.com/dyqwrp
; http://bbs.esrichina-bj.cn/ESRI/?fromuid=9806
;描述:
; 初始化ENVI
;
;调用方法:
;(1) ENVI的处理过程中不显示进度条
; startEnvi
;(2) ENVI的处理过程中显示进度条
; startEnvi,/ShowProcess
;-
PRO startENVI, showProcess = showProcess
compile_opt idl2
ENVI, /restore_base_save_files
ENVI_BATCH_INIT, NO_STATUS_WINDOW = 1- keyWord_set(showProcess)
END
定标
;+
;ENVI二次开发功能代码
;
;Author: DYQ
;问题讨论:
; http://bbs.esrichina-bj.cn/ESRI/?fromuid=9806
; http://hi.baidu.com/dyqwrp
;描述:
; 定标
;
;调用方法:
; cal_Calibration, 'c:\temp\can_tmr.img','c:\temp\result.img',[[2,2,2,2,2,2],[1,1,1,1,1,1]]
;注意事项:
; gainoffset参数与波段个数一一对应
;
;-
Pro cal_calibration, infile, outFile, gainOffset,wl = wv;(可选关键字,wv是定标后单位)
COMPILE_OPT idl2
CATCH, Error_status
errorshow = 'Sorry to see the error,'+ $
' please send the error Information to "dongyq@esrichina-bj.cn"'
IF Error_status NE 0 THEN BEGIN
tmp = DIALOG_MESSAGE(errorshow+STRING(13b)+$
!ERROR_STATE.MSG,/error,title = '错误提示!')
return
ENDIF
;获取ENVI的配置参数
cfg = envi_get_configuration_values()
tmppath = cfg.DEFAULT_TMP_DIRECTORY
;是否设置了输出文件名
IF N_ELEMENTS(outFile) EQ 0 THEN out_name=tmppath+PATH_SEP()+'void.tmp'
ENVI_OPEN_FILE,infile,R_fid= fid
;获取信息
ENVI_FILE_QUERY, FID, $
dims = dims, $
BNAMES = BNAMEs, $
NB = NB
;定标功能
ENVI_DOIT,'gainoff_doit', fid=fid, pos=LINDGEN(nb), dims=dims, out_name=outFile, $
gain=1./gainOffset[*,0], offset=gainOffset[*,1], r_fid=r_fid, in_memory=0,$
OUT_DT = 4
ENVI_FILE_QUERY, r_fid, $
dims = dims, $
DATA_TYPE = 4, $
INTERLEAVE = INTERLEAVE, $
NB = NB, $
NL = NL, $
NS=NS ,$
OFFSET = OFFSET
map_info = ENVI_GET_MAP_INFO(fid=r_fid)
;先关掉文件
ENVI_FILE_MNG, id = fid,/Remove
ENVI_FILE_MNG, id = r_fid,/Remove
;再写入头文件
ENVI_SETUP_HEAD, $
DATA_TYPE = DATA_TYPE, $
BNAMES = '定标后:'+BNAMES, $
DESCRIP = '定标公式 y=x/gain+offset', $
FNAME=outFile,$
INTERLEAVE = INTERLEAVE, $
MAP_INFO = map_info, $
wl = wv, $
NB = NB, $
NL = NL, $
NS=NS ,$
OFFSET = OFFSET,$
/Write
END
大气校正
;+
;ENVI二次开发功能代码
;
;Author: DYQ
;问题讨论:
; http://hi.baidu.com/dyqwrp
; http://bbs.esrichina-bj.cn/ESRI/?fromuid=9806
;描述:
; 大气校正
;
;调用方法:
;cal_QUAC,inputfile,outputfile
;
;-
PRO CAL_QUAC,inputfile,outputfile
COMPILE_OPT idl2
CATCH, Error_status
errorshow = 'Sorry to see the error,'+ $
' please send the error Information to "dongyq@esrichina-bj.cn"'
IF Error_status NE 0 THEN BEGIN
tmp = DIALOG_MESSAGE(errorshow+STRING(13b)+$
!ERROR_STATE.MSG,/error,title = '错误提示!')
return
ENDIF
ENVI_OPEN_FILE, inputfile, r_fid=fid
IF (fid EQ -1) THEN BEGIN
RETURN
ENDIF
ENVI_FILE_QUERY, fid, dims=dims, nb=nb, sensor_type=sensor_type
pos = LINDGEN(nb)
sensor = envi_sensor_type(sensor_type)
; Perform QUick Atmospheric Correction
ENVI_DOIT, 'envi_quac_doit', $
fid=fid, pos=pos, dims=dims, $
quac_sensor=sensor, $
out_name=outputfile, r_fid=r_fid
;
END
融合
;+
;ENVI二次开发功能代码
;
;Author: DYQ
;问题讨论:
; http://hi.baidu.com/dyqwrp
; http://bbs.esrichina-bj.cn/ESRI/?fromuid=9806
;描述:
;图像融合
;
;调用方法:
;CAL_SHARPEN,inputfileMulti,inputfilePan,outputfile,method
;inputfileMulti是低分辨率的多光谱影像
;inputfilePan是高分全色影像
;
;Method : 0-HSV融合
; 1-color-normalized融合
; 2-Gram-Schmidt融合
; 3-主成份分析融合
;-
PRO CAL_SHARPEN,inputfileMulti,inputfilePan,outputfile,method
COMPILE_OPT idl2
CATCH, Error_status
errorshow = 'Sorry to see the error,'+ $
' please send the error Information to "dongyq@esrichina-bj.cn"'
IF Error_status NE 0 THEN BEGIN
tmp = DIALOG_MESSAGE(errorshow+STRING(13b)+$
!ERROR_STATE.MSG,/error,title = '错误提示!')
return
ENDIF
;打开全色影像
ENVI_OPEN_FILE, inputfilePan, r_fid=h_fid
IF (h_fid EQ -1) THEN BEGIN
ENVI_BATCH_EXIT
RETURN
ENDIF
;获取影像参数 ;
ENVI_FILE_QUERY, h_fid, ns=h_ns, nl=h_nl,$
dims = h_dims,nb = h_nb
; 打开多光谱影像
ENVI_OPEN_FILE, inputfileMulti, r_fid=m_fid
IF (m_fid EQ -1) THEN BEGIN
ENVI_BATCH_EXIT
RETURN
ENDIF
;获取影像参数
ENVI_FILE_QUERY, m_fid, dims=m_dims, $
bnames=m_bnames,nb = m_nb
IF method LT 2 THEN BEGIN
; Set the keywords
f_dims = [-1l, 0, h_ns-1, 0, h_nl-1]
f_pos = [0]
;
rgb_fid = [m_fid,m_fid,m_fid]
out_bname = ['3','2','1']
;ENVI的融合功能
ENVI_DOIT, 'sharpen_doit', $
fid=rgb_fid, pos=lindgen(m_nb), f_fid=h_fid, $
f_dims=f_dims, f_pos=f_pos, $
out_name=outputfile, method=1, $
interp=0, out_bname=out_bname
RETURN
ENDIF
CASE method OF
;
2: BEGIN
out_bname = 'GS_Sharpen_band_'+STRTRIM(LINDGEN(m_nb),2)
ENVI_DOIT, 'ENVI_GS_SHARPEN_DOIT', $
DIMS= m_dims, $
fID = m_fid, $
HIRES_DIMS = h_dims, $
HIRES_FID = h_fid,$
HIRES_POS = LINDGEN(h_nb),$
INTERP = 2,$
LORES_DIMS = m_dims,$
LORES_FID = m_fid, $
LORES_POS = LINDGEN(m_nb), $
METHOD = 0 ,$
OUT_BNAME = out_bname , $
OUT_NAME = outputfile,$
POS =LINDGEN(m_nb)
END
3: BEGIN
out_bname = 'PC_Sharpen_band_'+STRTRIM(LINDGEN(m_nb),2)
ENVI_DOIT, 'ENVI_PC_SHARPEN_DOIT', $
DIMS= m_dims, $
fID = m_fid, $
HIRES_DIMS = h_dims, $
HIRES_FID = h_fid,$
HIRES_POS = LINDGEN(h_nb),$
INTERP = 2,$
LORES_DIMS = m_dims,$
LORES_FID = m_fid, $
LORES_POS = LINDGEN(m_nb), $
METHOD = 0 ,$
OUT_BNAME = out_bname , $
OUT_NAME = outputfile,$
POS =LINDGEN(m_nb)
END
ELSE:
ENDCASE
END
镶嵌
;+
;ENVI二次开发功能代码
;
;Author: DYQ
;问题讨论:
; http://hi.baidu.com/dyqwrp
; http://bbs.esrichina-bj.cn/ESRI/?fromuid=9806
;描述:
; 镶嵌
;
;调用方法:
; cal_mosaic, txtFile
; 输入为txt配置文件完整路径
;
;-
PRO georef_mosaic_setup, fids=fids, dims=dims, out_ps=out_ps, $
xsize=xsize, ysize=ysize, x0=x0, y0=y0, map_info=map_info
COMPILE_OPT IDL2
IF KEYWORD_SET(dims) THEN $
IF N_ELEMENTS(fids) NE N_ELEMENTS(dims[0,*]) THEN dims=0
;
IF N_ELEMENTS(fids) LT 2 THEN BEGIN
xsize = -1
ysize = -1
x0 = -1
y0 = -1
RETURN
ENDIF
; if no DIMS passed in
;
nfiles = N_ELEMENTS(fids)
IF (KEYWORD_SET(dims) EQ 0) THEN BEGIN
dims = FLTARR(5, nfiles)
FOR i=0, nfiles-1 DO BEGIN
ENVI_FILE_QUERY, fids[i], ns=ns, nl=nl
dims[*,i] = [-1L, 0, ns-1, 0, nl-1]
ENDFOR
ENDIF
UL_corners_X = DBLARR(nfiles)
UL_corners_Y = DBLARR(nfiles)
east = -1e34
west = 1e34
north = -1e34
south = 1e34
FOR i=0,nfiles-1 DO BEGIN
pts = [ [dims[1,i], dims[3,i]], $ ; UL
[dims[2,i], dims[3,i]], $ ; UR
[dims[1,i], dims[4,i]], $ ; LL
[dims[2,i], dims[4,i]] ] ; LR
ENVI_CONVERT_FILE_COORDINATES, fids[i], pts[0,*], pts[1,*], xmap, ymap, /to_map
UL_corners_X[i] = xmap[0]
UL_corners_Y[i] = ymap[0]
east = east > MAX(xmap)
west = west < MIN(xmap)
north = north > MAX(ymap)
south = south < MIN(ymap)
ENDFOR
xsize = east - west
ysize = north - south
;
xsize_pix = FIX( xsize/out_ps[0] )+1
ysize_pix = FIX( ysize/out_ps[1])+1
;
proj = ENVI_GET_PROJECTION(fid=fids[0])
map_info = ENVI_MAP_INFO_CREATE(proj=proj, mc=[0,0,west,north], ps=out_ps)
temp = BYTARR(10,10)
ENVI_ENTER_DATA, temp, map_info=map_info, /no_realize, r_fid=tmp_fid
; find the x and y offsets for the images
;
x0 = LONARR(nfiles)
y0 = LONARR(nfiles)
FOR i=0,nfiles-1 DO BEGIN
ENVI_CONVERT_FILE_COORDINATES, tmp_fid, xpix, ypix, UL_corners_X[i], UL_corners_Y[i]
x0[i] = xpix
y0[i] = ypix
ENDFOR
; delete the tmp file
ENVI_FILE_MNG, id=tmp_fid, /remove, /no_warning
END
;
PRO mosaic_files,info,pos=pos,rasterfilenames=rasterfilenames,output=output,crop=crop,$
file_pattern=file_pattern
COMPILE_OPT idl2
IF N_ELEMENTS(background) EQ 0 THEN background=0
IF N_ELEMENTS(crop) NE 4 THEN crop=[0,0,0,0,0] ELSE crop=[0,crop]*[0,-1,1,-1,1]
IF N_ELEMENTS(rasterfilenames) EQ 0 AND N_ELEMENTS(file_pattern) EQ 0 THEN BEGIN
IF rasterfilenames[0] EQ '' THEN RETURN
ENDIF
IF N_ELEMENTS(file_pattern) NE 0 THEN BEGIN
rasterfilenames=FILE_SEARCH(file_pattern)
ENDIF
numfiles=N_ELEMENTS(rasterfilenames)
rasterfids=LONARR(numfiles)
IF N_ELEMENTS(output) EQ 0 THEN BEGIN
output=ENVI_PICKFILE(title='Output Mosaick Filename:')
IF output EQ '' THEN RETURN
ENDIF
;
tlb = WIDGET_AUTO_BASE(title='镶嵌参数设置')
we = WIDGET_PARAM(tlb, dt=4, field=3, $
default=-999., uvalue='param', /auto, $
PROMPT ='忽略数据值')
result = AUTO_WID_MNG(tlb)
IF (result.accept EQ 0) THEN RETURN
ignoreValue = result.param
ENVI_OPEN_FILE, rasterfilenames[0], r_fid=tempfid
rasterfids[0]=tempfid
ENVI_FILE_QUERY,tempfid,nb=nb,ns=tempns,nl=tempnl,data_type=data_type
map_info = ENVI_GET_MAP_INFO(fid=tempfid)
out_ps=map_info.ps[0:1]
IF N_ELEMENTS(pos) EQ 0 OR N_ELEMENTS(pos) GT nb THEN pos=LINDGEN(nb)
posarr=LONARR(N_ELEMENTS(pos),numfiles)
FOR i=0,numfiles-1 DO posarr[*,i]=pos
dimsarr=LONARR(5,numfiles)
dimsarr[*,0]=[-1,0, tempns-1,0, tempnl-1]-crop
use_see_through = LONARR(numfiles)
FOR i=1,numfiles-1 DO BEGIN
ENVI_OPEN_FILE, rasterfilenames[i], r_fid=tempfid
rasterfids[i]=tempfid
ENVI_FILE_QUERY,tempfid,nb=nb,ns=tempns,nl=tempnl
dimsarr[*,i]=[-1,0, tempns-1,0, tempnl-1]-crop
ENDFOR
georef_mosaic_setup, fids=rasterfids, out_ps=out_ps, dims=dimsarr, xsize=xsize, ysize=ysize,$
x0=x0, y0=y0, map_info=map_info ;
USE_SEE_THROUGH = INTARR(N_ELEMENTS(rasterfids))+1
seeTv = MAKE_ARRAY(N_ELEMENTS(rasterfids),value =ignoreValue )
ENVI_DOIT, 'mosaic_doit', fid=rasterfids, pos=posarr, $
dims=dimsarr, out_name=output, xsize=xsize, $
ysize=ysize, x0=x0, y0=y0, georef=1, $
out_dt=data_type, pixel_size=out_ps, $
background=ignoreValue,SEE_THROUGH_VAL=seeTv,$
USE_SEE_THROUGH = USE_SEE_THROUGH,$
map_info=map_info
END
PRO cal_mosaic, txtFile
COMPILE_OPT idl2
CATCH, Error_status
errorshow = 'Sorry to see the error,'+ $
' please send the error Information to "dongyq@esrichina-bj.cn"'
IF Error_status NE 0 THEN BEGIN
tmp = DIALOG_MESSAGE(errorshow+STRING(13b)+$
!ERROR_STATE.MSG,/error,title = '错误提示!')
return
ENDIF
;如果文件不存在则返回
IF ~FILE_TEST(txtFile) THEN RETURN;
;解析
nFiles = FILE_LINES(txtFile)
;
filenames = STRARR(nFiles)
OPENR,lun,txtfile,/get_
READF,lun,filenames
FREE_LUN,lun
;
mosaic_files,rasterfilenames = filenames[0:nFiles-2],output = filenames[nFiles-1]
END
裁剪
;+
;ENVI二次开发功能代码
;
;Author: DYQ
;问题讨论:
; http://hi.baidu.com/dyqwrp
; http://bbs.esrichina-bj.cn/ESRI/?fromuid=9806
;描述:
; 基于shape矢量文件裁剪
;
;调用方法:
; cal_subset,infile, shapefile, resultfile
; infile:待裁剪的栅格文件
; shapefile:矢量文件
; resultfile:裁剪后存储结果
;-
PRO cal_subset,infile, shapefile, resultfile
compile_opt idl2
CATCH, Error_status
errorshow = 'Sorry to see the error,'+ $
' please send the error Information to "dongyq@esrichina-bj.cn"'
IF Error_status NE 0 THEN BEGIN
tmp = DIALOG_MESSAGE(errorshow+STRING(13b)+$
!ERROR_STATE.MSG,/error,title = '错误提示!')
return
ENDIF
shapeobj = OBJ_NEW('IDLffShape', shapefile)
ENVI_OPEN_FILE,infile,r_fid = fid
ENVI_FILE_QUERY, fid, ns = ns, nb = nb, nl = nl, dims = dims,BNAMES = BNAMES
shapeobj->GETPROPERTY, N_Entities = nEntities
;
; shape_type =5--多边形 8-- 多个多边形
;BOUNDS 边界值
;
roi_ids = LONARR(nEntities>1)
FOR i=0, nEntities-1 DO BEGIN
entitie = shapeobj->GETENTITY(i)
;多边形则进行转换,否则不做任何操作
IF (entitie.SHAPE_TYPE EQ 5) THEN BEGIN
record = *(entitie.VERTICES)
;转换为文件坐标
ENVI_CONVERT_FILE_COORDINATES,fid,xmap,ymap,record[0,*],record[1,*]
;创建ROI
roi_ids[i] = ENVI_CREATE_ROI(color=4, $
ns = ns , nl = nl)
ENVI_DEFINE_ROI, roi_ids[i], /polygon, xpts=REFORM(xMap), ypts=REFORM(yMap)
;roi_ids[i] = roi_id
;记录XY的区间,裁剪用
;记录XY的区间,裁剪用
IF i EQ 0 THEN BEGIN
xmin = ROUND(MIN(xMap,max = xMax))
yMin = ROUND(MIN(yMap,max = yMax))
ENDIF ELSE BEGIN
xmin = xMin < ROUND(MIN(xMap))
xMax = xMax > ROUND(MAX(xMap))
yMin = yMin < ROUND(MIN(yMap))
yMax = yMax > ROUND(MAX(yMap))
ENDELSE
ENDIF
shapeobj->DESTROYENTITY, entitie
ENDFOR
OBJ_DESTROY, shapeobj
;
xMin = xMin >0
xmax = xMax < ns-1
yMin = yMin >0
ymax = yMax < nl-1
out_dims = [-1,xMin,xMax,yMin,yMax]
;获取ENVI的配置参数
cfg = envi_get_configuration_values()
tmppath = cfg.DEFAULT_TMP_DIRECTORY
;创建掩膜,裁剪后掩
ENVI_MASK_DOIT,$
AND_OR =1, $
OUT_NAME = tmppath+path_sep()+'void.mask', $
ROI_IDS= roi_ids, $ ;ROI的ID
ns = ns, nl = nl, $
/inside, $ ;区域内或外
r_fid = m_fid
ENVI_MASK_APPLY_DOIT, FID = fid, POS = INDGEN(nb), DIMS = out_dims, $
M_FID = m_fid, M_POS = [0], VALUE = 0, $
out_name = resultfile;,$
;out_bnames = BNAMES+"("+"subset by "+STRTRIM(FILE_BASENAME(shapefile),2)+")"
;掩膜文件ID移除
ENVI_FILE_MNG, id =m_fid,/remove
END
监督与非监督分类
;+
;ENVI二次开发功能代码
;
;Author: DYQ
;问题讨论:
; http://hi.baidu.com/dyqwrp
; http://bbs.esrichina-bj.cn/ESRI/?fromuid=9806
;描述:
; 分类处理,包括监督分类和非监督分类
;
;调用方法:
;
;CAL_CLASS,inputfile,outputfile, method,...
;
;inputFile:待分类影像
;outpurfile:分类结果;
;Method : 0--5为监督分类,6、7为非监督分类
;
; 1-最小距离 1
; 2-最大似然 2
; 3-马氏距离 5
; 4-神经元网络 ENVI_NEURAL_NET_DOIT
; 5-向量机 ENVI_SVM_DOIT
; 6-IsoData 4
; 7-K-Means 7
;注意:每一种算法需要使用的参数说明可参考ENVI帮助文档
;
PRO CAL_CLASS,inputfile,outputfile, method,$
;感兴趣区文件
roifile = roifile,$
;平行六面体分类算法可选参数
STDV = stdv, $
STD_MULT =STD_MULT,$
;神经元网络分类算法参数
theta = theta, $
eta = eta, $
alpha = alpha, $
act_type = act_type, $
rms_crit = rms_crit, $
num_layers = num_layers, $
num_sweeps = num_sweeps, $
;向量机
thresh = thresh, $
penalty = penalty, $
kernel_type = kernel_type, $
kernel_degree = kernel_degree, $
kernel_bias = kernel_bias ,$
;K-Means 算法可选参数
ITERATIONS = ITERATIONS, $
NUM_CLASSES = NUM_CLASSES , $
;ISO算法参数
CHANGE_THRESH = CHANGE_THRESH, $
ISO_MERGE_DIST = ISO_MERGE_DIST, $
ISO_MERGE_PAIRS = ISO_MERGE_PAIRS, $
ISO_MIN_PIXELS = ISO_MIN_PIXELS, $
ISO_SPLIT_SMULT = ISO_SPLIT_SMULT, $
ISO_SPLIT_STD = ISO_SPLIT_STD, $
MIN_CLASSES = MIN_CLASSES
COMPILE_OPT idl2
CATCH, Error_status
errorshow = 'Sorry to see the error,'+ $
' please send the error Information to "dongyq@esrichina-bj.cn"'
IF Error_status NE 0 THEN BEGIN
tmp = DIALOG_MESSAGE(errorshow+STRING(13b)+$
!ERROR_STATE.MSG,/error,title = '错误提示!')
return
ENDIF
;输入数据预处理
ENVI_OPEN_FILE, inputfile, r_fid=fid
IF (fid EQ -1) THEN BEGIN
RETURN
ENDIF
;获取文件信息
ENVI_FILE_QUERY, fid, dims=dims, nb=nb
pos = LINDGEN(nb)
out_name = outputfile
CASE method OF
;-IsoData 4
6: BEGIN
IF ~KEYWORD_SET(CHANGE_THRESH) THEN CHANGE_THRESH = .05
IF ~KEYWORD_SET(NUM_CLASSES) THEN NUM_CLASSES = 10
IF ~KEYWORD_SET(ITERATIONS) THEN ITERATIONS = 1
IF ~KEYWORD_SET(ISO_MERGE_DIST) THEN ISO_MERGE_DIST = 1
IF ~KEYWORD_SET(ISO_MERGE_PAIRS) THEN ISO_MERGE_PAIRS = 2
IF ~KEYWORD_SET(ISO_MIN_PIXELS) THEN ISO_MIN_PIXELS = 1
IF ~KEYWORD_SET(ISO_SPLIT_SMULT) THEN ISO_SPLIT_SMULT = 1
IF ~KEYWORD_SET(ISO_SPLIT_STD) THEN ISO_SPLIT_STD = 1
IF ~KEYWORD_SET(MIN_CLASSES) THEN MIN_CLASSES = 5
out_bname = 'IsoData'
ENVI_DOIT, 'class_doit', fid=fid, pos=pos, dims=dims, $
out_bname=out_bname, out_name=out_name, method=4, $
r_fid=r_fid, $
NUM_CLASSES = NUM_CLASSES, $
ITERATIONS = ITERATIONS, $
in_memory=0, $
CHANGE_THRESH = CHANGE_THRESH, $
ISO_MERGE_DIST = ISO_MERGE_DIST, $
ISO_MERGE_PAIRS = ISO_MERGE_PAIRS, $
ISO_MIN_PIXELS = ISO_MIN_PIXELS, $
ISO_SPLIT_SMULT = ISO_SPLIT_SMULT, $
ISO_SPLIT_STD = ISO_SPLIT_STD, $
MIN_CLASSES = MIN_CLASSES
END
;-K-Means 7
7: BEGIN
IF ~KEYWORD_SET(NUM_CLASSES) THEN NUM_CLASSES = 5
IF ~KEYWORD_SET(CHANGE_THRESH) THEN CHANGE_THRESH = .5
IF ~KEYWORD_SET(ITERATIONS) THEN ITERATIONS = 1
out_bname = 'K-Means'
thresh=REPLICATE(0.05,num_classes)
ENVI_DOIT, 'class_doit', fid=fid, pos=pos, dims=dims, $
out_bname=out_bname, out_name=out_name, method=7, $
r_fid=r_fid, $
lookup = BYTARR(3,num_classes+1), $
NUM_CLASSES = NUM_CLASSES, $
in_memory=0, CHANGE_THRESH=CHANGE_THRESH,$
ITERATIONS = ITERATIONS
END
;-平行六面体 0
0: BEGIN
ENVI_RESTORE_ROIS, roifile
roi_ids = ENVI_GET_ROI_IDS(fid=fid, $
roi_colors=roi_colors, roi_names=class_names)
class_names = ['Unclassified', class_names]
num_classes = N_ELEMENTS(roi_ids)
; Set the unclassified class to black and use roi colors
lookup = BYTARR(3,num_classes+1)
lookup[0,1] = roi_colors
; 计算类ROI的基本统计信息
mean = FLTARR(N_ELEMENTS(pos), num_classes)
stdv = FLTARR(N_ELEMENTS(pos), num_classes)
cov = FLTARR(N_ELEMENTS(pos),N_ELEMENTS(pos),num_classes)
FOR j=0, num_classes-1 DO BEGIN
;
roi_dims=[ENVI_GET_ROI_DIMS_PTR(roi_ids[j]),0,0,0,0]
ENVI_DOIT, 'envi_stats_doit', fid=fid, pos=pos, $
dims=roi_dims, comp_flag=4, mean=c_mean, $
stdv=c_stdv, cov=c_cov
MEAN[0,j] = c_mean
stdv[0,j] = c_stdv
cov[0,0,j] = c_cov
ENDFOR
;
thresh=REPLICATE(0.05,num_classes)
out_bname = 'parallelepiped'
ENVI_DOIT, 'class_doit', fid=fid, pos=pos, dims=dims, $
out_bname=out_bname, out_name=out_name, method=0, $
mean=mean, stdv=stdv, std_mult=st_mult, $
lookup=lookup, class_names=class_names, $
in_memory=0;, thresh=thresh
END
;-最小距离 1
1: BEGIN
ENVI_RESTORE_ROIS, roifile
roi_ids = ENVI_GET_ROI_IDS(fid=fid, $
roi_colors=roi_colors, roi_names=class_names)
class_names = ['Unclassified', class_names]
num_classes = N_ELEMENTS(roi_ids)
; Set the unclassified class to black and use roi colors
lookup = BYTARR(3,num_classes+1)
lookup[0,1] = roi_colors
; 计算类ROI的基本统计信息
;
mean = FLTARR(N_ELEMENTS(pos), num_classes)
stdv = FLTARR(N_ELEMENTS(pos), num_classes)
cov = FLTARR(N_ELEMENTS(pos),N_ELEMENTS(pos),num_classes)
FOR j=0, num_classes-1 DO BEGIN
;
roi_dims=[ENVI_GET_ROI_DIMS_PTR(roi_ids[j]),0,0,0,0]
ENVI_DOIT, 'envi_stats_doit', fid=fid, pos=pos, $
dims=roi_dims, comp_flag=4, mean=c_mean, $
stdv=c_stdv, cov=c_cov
MEAN[0,j] = c_mean
stdv[0,j] = c_stdv
cov[0,0,j] = c_cov
ENDFOR
;
thresh=REPLICATE(0.05,num_classes)
out_bname = 'MinimumDistance'
ENVI_DOIT, 'class_doit', fid=fid, pos=pos, dims=dims, $
out_bname=out_bname, out_name=out_name, method=1, $
mean=mean, stdv=stdv, std_mult=st_mult, $
lookup=lookup, class_names=class_names, $
in_memory=0
END
;-最大似然 2
2: BEGIN
ENVI_RESTORE_ROIS, roifile
roi_ids = ENVI_GET_ROI_IDS(fid=fid, $
roi_colors=roi_colors, roi_names=class_names)
class_names = ['Unclassified', class_names]
num_classes = N_ELEMENTS(roi_ids)
; Set the unclassified class to black and use roi colors
lookup = BYTARR(3,num_classes+1)
lookup[0,1] = roi_colors
; 计算类ROI的基本统计信息
;
mean = FLTARR(N_ELEMENTS(pos), num_classes)
stdv = FLTARR(N_ELEMENTS(pos), num_classes)
cov = FLTARR(N_ELEMENTS(pos),N_ELEMENTS(pos),num_classes)
FOR j=0, num_classes-1 DO BEGIN
;
roi_dims=[ENVI_GET_ROI_DIMS_PTR(roi_ids[j]),0,0,0,0]
ENVI_DOIT, 'envi_stats_doit', fid=fid, pos=pos, $
dims=roi_dims, comp_flag=4, mean=c_mean, $
stdv=c_stdv, cov=c_cov
MEAN[0,j] = c_mean
stdv[0,j] = c_stdv
cov[0,0,j] = c_cov
ENDFOR
;
thresh=REPLICATE(0.05,num_classes)
out_bname = 'MaximumLikelihood'
ENVI_DOIT, 'class_doit', fid=fid, pos=pos, dims=dims, $
out_bname=out_bname, out_name=out_name, method=2, $
mean=mean, stdv=stdv, std_mult=st_mult, $
lookup=lookup, class_names=class_names, $
cov = cov,$
in_memory=0
END
;-马氏距离 5
3: BEGIN
ENVI_RESTORE_ROIS, roifile
roi_ids = ENVI_GET_ROI_IDS(fid=fid, $
roi_colors=roi_colors, roi_names=class_names)
class_names = ['Unclassified', class_names]
num_classes = N_ELEMENTS(roi_ids)
; Set the unclassified class to black and use roi colors
lookup = BYTARR(3,num_classes+1)
lookup[0,1] = roi_colors
; 计算类ROI的基本统计信息
;
mean = FLTARR(N_ELEMENTS(pos), num_classes)
stdv = FLTARR(N_ELEMENTS(pos), num_classes)
cov = FLTARR(N_ELEMENTS(pos),N_ELEMENTS(pos),num_classes)
FOR j=0, num_classes-1 DO BEGIN
;
roi_dims=[ENVI_GET_ROI_DIMS_PTR(roi_ids[j]),0,0,0,0]
ENVI_DOIT, 'envi_stats_doit', fid=fid, pos=pos, $
dims=roi_dims, comp_flag=4, mean=c_mean, $
stdv=c_stdv, cov=c_cov
MEAN[0,j] = c_mean
stdv[0,j] = c_stdv
cov[0,0,j] = c_cov
ENDFOR
;
thresh=REPLICATE(0.05,num_classes)
out_bname = 'Mahalanobis'
ENVI_GET_ROI_INFORMATION, roi_ids,nPts = nPts
ENVI_DOIT, 'class_doit', fid=fid, pos=pos, dims=dims, $
out_bname=out_bname, out_name=out_name, method=5, $
mean=mean, stdv=stdv, std_mult=st_mult, $
lookup=lookup, class_names=class_names, $
cov = cov,NPTS = nPts, $
in_memory=0
END
;-神经元网络 ENVI_NEURAL_NET_DOIT
4: BEGIN
IF ~KEYWORD_SET(theta) THEN theta = .9
IF ~KEYWORD_SET(eta) THEN eta = .2
IF ~KEYWORD_SET(alpha) THEN alpha = .9
IF ~KEYWORD_SET(act_type) THEN act_type = 0
IF ~KEYWORD_SET(rms_crit) THEN rms_crit = .1
IF ~KEYWORD_SET(num_layers) THEN num_layers = 3
IF ~KEYWORD_SET(num_sweeps) THEN num_sweeps = 10
ENVI_RESTORE_ROIS, roifile
roi_ids = ENVI_GET_ROI_IDS(fid=fid, $
roi_colors=lookup, roi_names=class_names)
; Set the classification variables
;
num_classes = N_ELEMENTS(roi_ids)
class_names = ['Unclassified', class_names]
lookup = REFORM([0,0,0, $
REFORM(lookup,3*num_classes)],3,num_classes+1)
;
; Call the doit
;
ENVI_DOIT, 'envi_neural_net_doit', $
fid=fid, pos=pos, dims=dims, $
out_name=out_name, rule_out_name='', $
theta=theta, eta=eta, alpha=alpha, $
num_classes=num_classes, num_sweeps=num_sweeps, $
num_layers=num_layers, act_type=act_type, $
rms_crit=rms_crit, roi_ids=roi_ids, /train, $
class_names=class_names, lookup=lookup
END
;-向量机 ENVI_SVM_DOIT
5: BEGIN
IF ~KEYWORD_SET(thresh) THEN thresh = .5
IF ~KEYWORD_SET(penalty) THEN penalty=75
IF ~KEYWORD_SET(kernel_type) THEN kernel_type=1
IF ~KEYWORD_SET(kernel_degree) THEN kernel_degree=3
IF ~KEYWORD_SET(kernel_bias) THEN kernel_bias = 2.
ENVI_RESTORE_ROIS, roifile
roi_ids = ENVI_GET_ROI_IDS(fid=fid)
; Call the svm classification doit routine
envi_doit, 'envi_svm_doit', $
fid=fid, pos=pos, dims=dims, $
out_name=out_name, $
roi_ids=roi_ids, thresh=thresh, $
penalty=penalty, kernel_type= kernel_type, $
kernel_degree=kernel_degree, kernel_bias=kernel_bias
END
ELSE:
ENDCASE
END
面向对象特征提取
;+
;ENVI二次开发功能代码
;
;Author: DYQ
;问题讨论:
; http://hi.baidu.com/dyqwrp
; http://bbs.esrichina-bj.cn/ESRI/?fromuid=9806
;描述:
; 面向对象特征提取
;
;调用方法:
; cal_FX,in_file,out_file,scale_level,merge_level,ruleset_filename
; in_file:FX输入文件
; out_file:fx的输出shape结果
; scale_level:fx的分割比例
; merge_level:fx的合并比例
; releset_filename:FX的规则配置文件,需要定制修改!
;-
PRO cal_FX,in_file,out_file,scale_level,merge_level,ruleset_filename
CATCH, Error_status
errorshow = 'Sorry to see the error,'+ $
' please send the error Information to "dongyq@esrichina-bj.cn"'
IF Error_status NE 0 THEN BEGIN
tmp = DIALOG_MESSAGE(errorshow+STRING(13b)+$
!ERROR_STATE.MSG,/error,title = '错误提示!')
return
ENDIF
; 打开文件
ENVI_OPEN_FILE, in_file, r_fid=in_fid
;文件打开出错则退出
IF (in_fid EQ -1) THEN RETURN
;获取文件信息
ENVI_FILE_QUERY, in_fid, dims=dims, nb=nb
IF ~FILE_TEST(ruleset_filename) THEN RETURN
IF ~FILE_TEST(FILE_DIRNAME(out_file),/directory) THEN FILE_MKDIR,FILE_DIRNAME(out_file)
; 执行FX.
ENVI_DOIT, 'envi_fx_doit', $
pos=LINDGEN(nb), $
dims=dims, $
fid=in_fid, $
scale_level=scale_level, $
merge_level=merge_level, $
vector_filename=out_file, $
conf_threshold=0.10, $
ruleset_filename=ruleset_filename, $
r_fid = out_fid
END
结束ENVI
;+
;ENVI二次开发功能代码
;
;Author: DYQ
;问题讨论:
; http://hi.baidu.com/dyqwrp
; http://bbs.esrichina-bj.cn/ESRI/?fromuid=9806
;描述:
; 关闭ENVI
;
;调用方法:
; endENVI
;-
PRO endENVI
;
ENVI_BATCH_EXIT
END