利用ENVI IDL去除小斑块功能扩展附源码Word文档下载推荐.docx
《利用ENVI IDL去除小斑块功能扩展附源码Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《利用ENVI IDL去除小斑块功能扩展附源码Word文档下载推荐.docx(13页珍藏版)》请在冰豆网上搜索。
6、处理效果:
分别对原始的分类图,进行MajorityAnalysis3X3窗口处理和“去除小斑块”参数(3,3,3)处理,得到如下的对比结果。
7、总结
ENVI+IDL功能强大,能够很方便快速的进行遥感图像处理的功能扩展。
ENVI提供了文件的输入输出以及众多的图像处理功能的函数。
即使有些功能没有提供函数,只要知道了原理和算法,也能非常方便和快捷的利用IDL来实现,同时结合ENVI的文件输入输出函数就能够很好的进行遥感功能的扩展。
8、源码
简介:
程序中包括的功能
(1)自定义菜单
(2)核心运算程序
(3)利用ENVI的分块函数效率高
;
####自定义菜单
PRORemoveLittleBlock_define_buttons,buttonInfo
ENVI_DEFINE_MENU_BUTTON,buttonInfo,VALUE='
去除小斑块'
$
uValue='
'
event_pro='
RemoveLittleBlock'
REF_VALUE='
Classification'
position=7
想实现在已知菜单下添加按钮,这个/SIBLING一定不能要
并且position指定了按钮的位置
end
####运算函数
FUNCTIONsimilarsmooth,inputdata,threshold
compile_optidl2
;
设置阈值的默认值
IF(N_ELEMENTS(threshold)EQ0)THENthreshold=2
a=inputdata
b1=a[sort(a)];
排序,
b2=uniq(b1);
找唯一值下标
b3=b1[b2];
找唯一值
n=n_elements(b3);
我唯一值的个数
countx=intarr(n);
初始化用于记录每个唯一值的个数
fori=0,n-1dobegin
aa=where(aeqb3[i],count);
窗口中的数据和每一个唯一值进行比较,并记录其个数
countx[i]=count;
记录每个唯一值的个数
endfor
t=max(countx);
计算某个个数最多
indmax=where(countxeqt)
indmin=where(countxlethreshold,count)
print,'
indmin:
n_elements(indmin),count
ifcountle0thenbegin
return,a
endifelsebegin
muldata=b3[indmax];
个数最多的唯一值(不止一个)
muldata:
muldata;
个数最多的值可能不止一个,所以后面赋值的时候,取第一个值muldata[0]。
minldata=b3[indmin];
符合条件(个数少得)的其他唯一值(不止一个)
fori=0,count-1dobegin
a[where(aeqminldata[i])]=muldata[0];
替换成个数最多的唯一值可能不止一个,取第一个值muldata[0]。
endelse
InputFile:
输入文件
OutFile:
输出路径
MoveWindow:
移动窗口大小,默认3x3
Threshold:
移动窗口中值的阈值。
默认2
step:
step=1表示步长按照窗口大小走,step=0表示步长按照半窗口大小走。
####利用ENVI的分块函数方便!
proEliminateSpeckle,Fid,OutFile,MoveWindow,Threshold,step
IF(N_ELEMENTS(MoveWindow)EQ0)THENMoveWindow=3
IF(N_ELEMENTS(step)EQ0)THENstep=MoveWindow
参数确认
求outfile路径的最后一个字符,用于判定是否指定了文件名
未指定文件名的路径后面有一个字符‘\’.
p=strmid(strtrim(outFile,2),0,1,REVERSE_OFFSET=1)
print,p
pp=strcmp(p,'
\'
);
比较字符
print,pp
IF(pp)THENbegin
print,outfile
void=DIALOG_MESSAGE('
请指定输出路径和文件名'
/info,title='
提示'
)
return
outname=outfile
print,outname
ENDELSE
ENVI,/RESTORE_BASE_SAVE_FILES
ENVI_BATCH_INIT
envi_open_file,InputFile[0],r_fid=fid
iffideq-1thenbegin
输入文件无效,请重新选择'
endif
envi_file_query,fid,dims=dims,nb=nb,nl=nl,ns=ns,DATA_TYPE=DATA_TYPE,$
interleave=interleave,xstart=xstart,ystart=ystart
只处理单波段文件
ifnbne1thenbegin
请指定单波段文件'
inherit=envi_set_inheritance(fid,dims,0,/full)
ostr='
输出路径:
'
+outname
envi_report_init,ostr,title="
正在运行"
base=base;
++++
分块处理-----------
ndvi_tile_id=ENVI_INIT_TILE(fid,0,num_tiles=num_tiles);
OVERLAP=MoveWindow)
openw,lun,outname,/get_lun
envi_report_inc,base,num_tiles;
num_tiles:
num_tiles
fori=0L,num_tiles-1dobegin
t1=SYSTIME
(1)
envi_report_stat,base,i,num_tiles-1;
data=envi_get_tile(ndvi_tile_id,i)
help,data
data=ENVI_GET_DATA(fid=fid,dims=dims,pos=0)
data1=data
指定窗口大小和移动步长
q=(step-1)/2
q=(MoveWindow-1)/2
step=MoveWindow
a=size(data)
print,a[1]
print,a[2]
return
forn=q,a[2]-q-1,stepdobegin
form=q,a[1]-q-1,stepdobegin
cdata=data1[(m-q):
(m+q),(n-q):
(n+q)]
data[(m-q):
(n+q)]=SIMILARSMOOTH(CDATA,threshold)
endfor
print,SYSTIME
(1)-t1
writeu,lun,data
free_lun,lun
ENVI_SETUP_HEAD,fname=outname,data_type=DATA_TYPE,$
ns=ns,nl=nl,nb=1,xstart=xstart,ystart=ystart,$
INTERLEAVE=interleave,INHERIT=inherit,$
map_info=map_info,/write,/OPEN,OFFSET=0
envi_tile_done,ndvi_tile_id
envi_file_mng,id=fid,/remove
envi_report_init,base=base,/finish;
####帮助文档
proHelpButton,event
WIDGET_CONTROL,event.top,GET_UVALUE=pstate
hlptlb=WIDGET_BASE(GROUP_LEADER=event.top,title='
帮助文档'
value=['
说明:
设置一个窗口,如3x3,一共9个值;
$
阈值为2表示在这9个值中,某一个值的个数如果小于2,'
将被这9个值中,个数最多的值替代;
“步长”表示窗口移动的像素距离;
该方法能够有效的去除孤立的小斑点。
“移动窗口”尽量设为奇数值,不能过大,影响结果。
“阈值”值越大,结果越平滑,小斑块消除越厉害。
$
“步长”值越大,运行越快,不超过“移动窗口”值;
“步长”值越小,运算量越大,可以按照默认的值;
“步长”值一般默认的与设置的“移动窗口”值一样;
如有问题请联系邮箱:
,putiming'
2011-10-18'
]
hlptxt=WIDGET_TEXT(hlptlb,value=value,ysize=(*pstate).yoff*0.08,xsize=(*pstate).xoff*0.11)
WIDGET_CONTROL,hlptlb,/REALIZE
####析构函数
proclean_up,tlb
compile_optidl2
WIDGET_CONTROL,tlb,get_uvalue=pstate
ptr_free,pstate
####界面事件响应
proRemoveLittleBlock_event,event
uName=WIDGET_INFO(event.id,/uname)
窗口关闭
ifTAG_NAMES(event,/STRUCTURE_NAME)eq'
WIDGET_KILL_REQUEST'
thenbegin
WIDGET_CONTROL,event.top,/destroy
RETURN
caseunameof
yidong'
:
begin
WIDGET_CONTROL,event.id,GET_VALUE=x
ifxmod2eq0thenbegin
void=DIALOG_MESSAGE('
“移动窗口”值需为奇数'
title='
WIDGET_CONTROL,event.id,sET_VALUE=3
(*pstate).MoveWindow=3
t=strtrim(sindgen(3)+1,2)
WIDGET_CONTROL,(*pstate).list1,SET_VALUE=t
endif
envi_file_query,(*pstate).fid,nl=nl,ns=ns
if(xlenl)or(xlens)thenbegin
ifxne'
thenbegin
t=strtrim(sindgen(x)+1,2)
t=indgen(x)
t=x-t
t=strtrim(string(t),2)
print,t
(*pstate).MoveWindow=x
“移动窗口”值超过数据的行列数,请重设'
)
WIDGET_CONTROL,(*pstate).field3,SET_VALUE=2
(*pstate).Threshold=2
end
yuzhi'
:
WIDGET_CONTROL,event.id,GET_VALUE=y
ifyge(*pstate).MoveWindow*(*pstate).MoveWindowthenbegin
“阈值”必须小于“移动窗口”值平方'
WIDGET_CONTROL,event.id,sET_VALUE=2
(*pstate).Threshold=y
end
buchang'
WIDGET_CONTROL,event.id,GET_VALUE=z
(*pstate).step=z[event.index]
xuanze'
Begin
out_name=Dialog_Pickfile(Path=current,/NoConfirm,$
Get_Path=path,Filter=['
*.*'
],title='
选择输出文件名'
ifout_nameeq'
thenreturn
widget_control,(*pstate).txt,set_value=out_name
(*pstate).out_name=out_name
lujing'
WIDGET_CONTROL,event.id,get_value=outname
(*pstate).out_name=outname
queding'
if(*pstate).out_nameeq'
请指定输出路径'
警告'
EliminateSpeckle,(*pstate).Fid,(*pstate).out_name,(*pstate).MoveWindow,(*pstate).Threshold,(*pstate).step
quxiao'
help'
HelpButton,event;
启动帮助文档
else:
endcase
####主程序界面
PRORemoveLittleBlock,event
dim=GET_SCREEN_SIZE()
print,dim
xoff=dim[0]*0.2
yoff=dim[1]*0.1
envi_center,xoff,yoff
ENVI_SELECT,fid=fid,pos=pos,/band_only,$
/no_dims,title='
选择单波段文件'
if(fid[0]eq-1)thenreturn
tlb=WIDGET_BASE(title='
/COLUMN,/TLB_KILL_REQUEST_EVENTS,$
TLB_FRAME_ATTR=1,xoff=xoff,yoff=yoff)
cstlb=WIDGET_BASE(tlb,/COLUMN,/FRAME)
field1=CW_FIELD(cstlb,TITLE='
移动窗口(奇数):
/FRAME,value='
3'
/INTEGER,/all_EVENTS,uname='
field3=CW_FIELD(cstlb,TITLE='
阈值:
2'
/INTEGER,/ALL_EVENTS,uname='
list1=WIDGET_dropLIST(cstlb,value=['
'
1'
],xsize=200,title='
步长:
uname='
kgtlb=WIDGET_BASE(tlb,/COLUMN)
label=WIDGET_LABEL(kgtlb,value='
ljtlb=WIDGET_BASE(tlb,/COLUMN,/FRAME)
ljtlb1=WIDGET_BASE(ljtlb,/row)
lable=WIDGET_LABEL(ljtlb1,value='
输出路径和文件名:
xz=WIDGET_BUTTON(ljtlb1,value='
选择'
Uname='
ljtlb2=WIDGET_BASE(ljtlb)
txt=WIDGET_TEXT(ljtlb2,uname='
/EDITABLE,/ALL_EVENTS,xsize=32)
kgtlb1=WIDGET_BASE(tlb,/COLUMN)
label=WIDGET_LABEL(kgtlb1,value='
qdtlb=WIDGET_BASE(tlb,/FRAME,/row)
qd=WIDGET_BUTTON(qdtlb,value='
确定'
lable=widget_label(qdtlb,value='
qx=WIDGET_BUTTON(qdtlb,value='
取消'
帮助'
pstate=PTR_NEW({list1:
list1,$
field3:
field3,$
txt:
txt,$
out_name:
$
Fid:
fid,$
MoveWindow:
3,$
Threshold:
2,$
step:
3,$
xoff:
xoff,$
yoff:
yoff$
},/no_copy)
WIDGET_CONTROL,tlb,SET_UVALUE=pstate
WIDGET_CONTROL,tlb,/REALIZE
XMANAGER,'
tlb,/NO_BLOCK,cleanup='
clean_up'