用envi二次開發的方式,提取TM影像中的水。如圖1所示。
圖1 TM影像(提取前)
提取的影像中水的方法有很多種,包括單波段閾值法和多波段組合法,這里選用多波段組合法。
公式為:(float(b2)+float(b3)) gt (float(b4)+float(b5))。即第二波段加第三波段大於第四波段加第五波段。
先用把公式代入到envi中,實現No problem以后,繼續。
接着需要用IDL中的波段計算的函數,math_doit。
在IDL中的代碼如下所示(修改之前):
1 PRO math_doit 2 3 compile_opt IDL2 4 catch,error_status 5 if error_status NE 0 then begin 6 void=dialog_message(!error_state.msg,title='發生錯誤',/error) 7 catch,/cancel 8 return 9 endif 10 11 ; First restore all the base save files. 12 envi, /restore_base_save_files 13 14 ; Initialize ENVI and send all errors 15 ; and warnings to the file batch.txt 16 envi_batch_init, log_file='batch.txt' 17 inputfilename='D:\Program Files\Exelis\ENVI50\classic\data\can_tmr.img' 18 19 ; Open the input file 20 envi_open_file,inputfilename , r_fid=fid 21 if (fid eq -1) then begin 22 envi_batch_exit 23 return 24 endif 25 26 ; Set the keywords. We will perform the 27 ; band math on all samples in the file. 28 envi_file_query, fid, dims=dims 29 t_fid = [fid,fid] 30 pos = [1,2,3,4] 31 exp='(float(b2)+float(b3)) gt (float(b4)+float(b5))' 32 out_name='d:\Water.img' 34 35 ; Perform the band math processing 36 envi_doit, 'math_doit', $ 37 fid=t_fid, pos=pos, dims=dims, $ 38 exp=exp, out_name=out_name, $ 39 r_fid=r_fid 40 END
結果發現,編譯完成以后沒有錯誤,運行也沒有錯誤,但是就是沒有計算結果,很讓人頭疼。
糾結了半天,后來才發現,原來是fid的惹的禍。
envi幫助中,有關於math_doit函數的解釋:
math_doit,用於影像中的波段計算。
使用語法為,ENVI_DOIT, 'MATH_DOIT', DIMS=array, EXP=string, FID=array, /IN_MEMORY, OUT_BNAME=string array, OUT_NAME=string, POS=array, R_FID=variable
1、DIMS
指dimensions,包含有五個長整型來定義空間子集。
DIMS[0]:只要在有感興趣區的時候才有用,否則,默認為-1。
DIMS[1]:開始像元的行數,第一個x像元為0。
DIMS[2]:最后的像元的行數。
DIMS[3]:開始像元的列數,第一個y像元為0。
DIMS[4]:最后的像元的列數。
如果影像文件沒有空間子集,也要寫DIMS,寫法如下:
envi_file_query,fid,dims=dims
2、EXP
指expression,即波段計算的表達式。如:
EXP='b1+b2'
EXP='byte((float(b1)+float(b2)+float(b3))/3.0)'
3、FID
指定長整型數組所代表的影像的ID,每一個代表着EXP中的一個波段。
4、IN_MEMORY
指定輸出文件是否輸出在內存中,如果不輸出在內存中,則必須指定OUT_NAME。
5、OUT_BANME
指定輸出波段名字。
6、OUT_NAME
指定輸出影像的名字,如果設置為IN_MEMORY,則不需要設置。
7、POS
指定波段位置的數組,表明要進行計算的波段數量。
長整型數組,從0至少到1,0即為波段1,1為波段2,以此類推。
如果在一個影像中使用,則可以這樣寫:
POS=[0,1,2,3]
envi_doit,'envi_stats_doit',dims=dims,fid=fid,pos=pos,$
comp_flag=3,dmin=dmin,dmax=dmax,mean=mean,stdv=stdv,hist=hist
但是,如果計算多個影像中的不用波段,如計算test1影像的波段3,test2影像的波段2,test影像的波段6,test4影像的波段4,則應該這么寫:
fid_array=[fid1,fid2,fid3,fid4]
pos=[2,1,5,3]
envi_doit,'cf_doit',dims=dims,fid=fid_array
out_name='test_composite_file'
8、R_FID
指‘returned FID’,生成的新影像的FID,如果為-1,則生成失敗。
(詳細解釋參見ENVI Classic Help——>math_doit)
所以,原來是代碼中第29行寫錯了,應改為t_fid=[fid,fid,fid,fid],四個波段應該是四個fid,這樣就OK了。
運行結果如圖2所示。
圖2 TM影像(提取后)
另外,如果運行以后沒有得到結果,檢查一下運行后R_FID的值,如果為-1,則檢查輸出文件的名稱是否正確,文件名中不能包括 / \ : * " ? < > | 這九種符號。