ENVI二次开发综述与代码分享

ENVI二次开发综述与代码分享

 

ENVI具备了丰富的二次开发功能函数接口,基本涵盖了ENVI下所有的功能,且通过IDL语言有输出助手(导出为COMJAVA类)、CallableIDLDrawWidgetCOM_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

posted @ 2022-09-05 11:03  ENVI-IDL技术殿堂  阅读(1336)  评论(0编辑  收藏  举报