Friday, November 20, 2015

ENVI+IDL: 批量提取多幅影像共同区域的方法

问题:已知多幅裁剪之后的影像,他们存在着多一行(或列)的问题,将其中行(列)最小的影像作为多幅影像的共同区域,达到批量提取其他影像的目的?
方法:ENVI+IDL。
练习数据中,mask.tif是行(列)最小的影像,即为多幅影像的共同区域。1比mask.tif多一行(列),代码运行的结果是result,行(列)与mask.tif一致,其第一波段即是mask.tif,其他波段为1影像。
文件test.pro是代码的入口。代码运行结果与ENVI操作结果一致。
注意不同文件之间数据类型差别,可能在批处理过程中要适当修改代码中选择数据类型的规则(out_dt=max(in_dt))。Referencing: IDL Data Types.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
;;Created by LI Xu
;;Version 1.0
;;18 October, 2014

pro CommonRange_Batch

  print, 'Time Begin:'+' '+systime()
  begintime=SYSTIME(1)

  ;;Source Directory
  SouDir='E:\Tools\rad\Rad'
  ;;Destination Directory
  DesDir='E:\Tools\rad\NEW'
  ;;One Image
  imgpath='E:\Tools\rad\pro\mask.tif'
  
  
  ;;Retrieve all files
  filespath=file_search(SouDir, '*.tif', count=num_files, /test_regular)
  for ii=0, num_files-1 do begin
    file=filespath(ii)
    ;;file=strsplit(file, '.', /extract)
    ;;file=file(0)
    
    filename=strsplit(file, '\', /extract, count=strcount)
    filename=filename(strcount-1)
    otImage=DesDir+'\'+filename
    inImage=strarr(2)
    inImage[0]=imgpath
    inImage[1]=file
    
    CommonRange, inImage, otImage
    
    
  endfor
  

  print, 'End!'
  print, 'Time End:'+' '+systime()
  endtime=systime(1)
  timespan=endtime-begintime
  print, 'Time Span:'+' '+string(timespan)+' s'




end

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
;+
; :Author: LiXu
;-

;;Created by LI Xu
;;Version 1.0
;;18 October, 2014

;;Description:
;;Make files in same Column and Row,
;;and upper left coodinate.
;;Reference:
;;http://www.exelisvis.com/Support/HelpArticlesDetail/TabId/219/ArtMID/900/ArticleID/4572/4572.aspx

pro CommonRange, imgpath, otimg

  ;;Debug Bolck
;  imgpath=strarr(2)
;  imgpath[0]='C:\AAAAA\practice\mask.tif'
;  imgpath[1]='C:\AAAAA\practice\1'
;  otimg='C:\AAAAA\practice\result'
  
  
  
  compile_opt idl2
  envi, /restore_base_save_files
  
  ;;Number of files
  num_files=N_Elements(imgpath)
  ;;open and gather file information in arrays
  in_fid=lonarr(num_files)
  in_nb=lonarr(num_files)
  in_dims=lonarr(5, num_files)
  in_dt=lonarr(num_files)
  
  for i=0L, num_files-1 do begin
    envi_open_file, imgpath[i], r_fid=r_fid
    if (r_fid eq -1) then begin
      print, imgpath[i]+' Open failed!'
      return
    endif

    envi_file_query, r_fid, ns=ns, nl=nl, nb=nb, dims=dims, data_type=dt
    in_fid[i]=r_fid
    in_nb[i]=nb
    in_dims[*,i]=dims
    in_dt[i]=dt
  endfor
  
  
  ;set up output fid, pos, and dims arrays
  out_fid = replicate(in_fid[0], in_nb[0])
  for i=1, num_files-1 do out_fid = [out_fid, replicate(in_fid[i], in_nb[i])]

  out_pos = lindgen(in_nb[0])
  for i = 1, num_files-1 do out_pos = [out_pos, lindgen(in_nb[i])]

  rep_dims = (intarr(in_nb[0])+1) # in_dims[*, 0]
  for i = 1, num_files-1 do $
    rep_dims = [rep_dims, (intarr(in_nb[i]) + 1) # in_dims[*, i]]
  out_dims = transpose(rep_dims)
  
  ;set the output projection and pixel size from the first file.
  ;save the result to disk and use max data type
  out_proj = envi_get_projection(fid=in_fid[0], pixel_size=out_ps)
  out_dt = min(in_dt)
  out_name=otimg
  
  ;call the layer stacking routine.
  ;Use nearest neighbor for the interpolation method.
  envi_doit, 'envi_layer_stacking_doit', fid=out_fid, pos=out_pos, dims=out_dims, $
    out_dt=out_dt, out_name=out_name, interp=0, out_ps=out_ps, $
    out_proj=out_proj, r_fid=r_fid,  /EXCLUSIVE

 

  
  
  
  
end

No comments:

Post a Comment