IDL中關於波段計算的問題


用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,則檢查輸出文件的名稱是否正確,文件名中不能包括 / \ : * " ? < > | 這九種符號。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM