利用ENVI IDL去除小斑块功能扩展附源码.docx

上传人:b****6 文档编号:6680751 上传时间:2023-01-08 格式:DOCX 页数:13 大小:19.46KB
下载 相关 举报
利用ENVI IDL去除小斑块功能扩展附源码.docx_第1页
第1页 / 共13页
利用ENVI IDL去除小斑块功能扩展附源码.docx_第2页
第2页 / 共13页
利用ENVI IDL去除小斑块功能扩展附源码.docx_第3页
第3页 / 共13页
利用ENVI IDL去除小斑块功能扩展附源码.docx_第4页
第4页 / 共13页
利用ENVI IDL去除小斑块功能扩展附源码.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

利用ENVI IDL去除小斑块功能扩展附源码.docx

《利用ENVI IDL去除小斑块功能扩展附源码.docx》由会员分享,可在线阅读,更多相关《利用ENVI IDL去除小斑块功能扩展附源码.docx(13页珍藏版)》请在冰豆网上搜索。

利用ENVI IDL去除小斑块功能扩展附源码.docx

利用ENVIIDL去除小斑块功能扩展附源码

利用ENVIIDL去除小斑块功能扩展(附源码)

利用ENVI+IDL去除小斑块功能扩展(附源码)

2011-10-2109:

36去除小斑块功能扩展

1、背景介绍:

在做分类后,结果图中有很多小斑点,为了消除小斑点,ENVI下提供了一些去除小斑块的工具,包括Majority/MinorityAnalysis工具、ClumpClasses工具、SieveClasses工具。

本工具主要是对其进行扩展,综合了MajorityAnalysis和SieveClasses的功能,使得我们进行小斑去除时能够更加灵活的进行设置,来达到结果要求。

2、原理:

通过处理窗口内的值,使得小于阈值个数的像元值被窗口中像元个数最多的值替换。

例如,设置一个窗口3x3,一共9个值;阈值为2表示在这9个值中,某一个或几个像素值的个数如果小于等于2,将被这9个值中个数最多的值替代。

该方法综合了MajorityAnalysis和SieveClasses的功能,能够有效的去除孤立的小斑点。

你可以根据需求,自定义参数,得到多样的结果。

3、功能介绍:

界面上主要设置的参数有:

移动窗口、阈值、步长(默认)。

“移动窗口”尽量设为奇数值,不能过大,影响结果。

“阈值”值越大,结果越平滑,小斑块消除越厉害。

“步长”表示窗口移动的像素距离;

“步长”值越大,运行越快,不超过“移动窗口”值;

“步长”值越小,运算量越大,可以按照默认的值;

“步长”值一般默认的与设置的“移动窗口”值一样(推荐使用默认值)。

4、安装:

下载链接:

将removelittleblock.sav文件拷贝到X:

\ProgramFiles\ITT\IDL\IDLx.x\products\envix.x\save_add目录下。

5、使用:

(1)启动ENVI->classification->“去除小斑块”。

(2)选择单波段文件(分类结果),点击OK。

如果没有文件供选择,可以用Open按钮来打开一单波段文件。

(如下图)

(3)弹出“去除小斑块”对话框,设置参数相应的参数后,点击“确定”执行。

参数设置可以查看“帮助”。

(如下图)

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];个数最多的唯一值(不止一个)

;print,'muldata:

',muldata;个数最多的值可能不止一个,所以后面赋值的时候,取第一个值muldata[0]。

minldata=b3[indmin];符合条件(个数少得)的其他唯一值(不止一个)

fori=0,count-1dobegin

a[where(aeqminldata[i])]=muldata[0];替换成个数最多的唯一值可能不止一个,取第一个值muldata[0]。

endfor

return,a

endelse

end

;;;InputFile:

输入文件

;;;OutFile:

输出路径

;;;MoveWindow:

移动窗口大小,默认3x3

;;;Threshold:

移动窗口中值的阈值。

默认2

;;;step:

step=1表示步长按照窗口大小走,step=0表示步长按照半窗口大小走。

;####利用ENVI的分块函数方便!

proEliminateSpeckle,Fid,OutFile,MoveWindow,Threshold,step

compile_optidl2

IF(N_ELEMENTS(MoveWindow)EQ0)THENMoveWindow=3

IF(N_ELEMENTS(threshold)EQ0)THENthreshold=2

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

endifelsebegin

outname=outfile

;print,outname

ENDELSE

;ENVI,/RESTORE_BASE_SAVE_FILES

;ENVI_BATCH_INIT

;envi_open_file,InputFile[0],r_fid=fid

iffideq-1thenbegin

void=DIALOG_MESSAGE('输入文件无效,请重新选择',/info,title='提示')

return

endif

envi_file_query,fid,dims=dims,nb=nb,nl=nl,ns=ns,DATA_TYPE=DATA_TYPE,$

interleave=interleave,xstart=xstart,ystart=ystart

;只处理单波段文件

ifnbne1thenbegin

void=DIALOG_MESSAGE('请指定单波段文件',/info,title='提示')

return

endif

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;++++

print,'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):

(m+q),(n-q):

(n+q)]=SIMILARSMOOTH(CDATA,threshold)

endfor

endfor

;print,SYSTIME

(1)-t1

writeu,lun,data

endfor

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;++++

end

;####帮助文档

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

end

;####析构函数

proclean_up,tlb

;compile_optidl2

WIDGET_CONTROL,tlb,get_uvalue=pstate

ptr_free,pstate

end

;####界面事件响应

proRemoveLittleBlock_event,event

WIDGET_CONTROL,event.top,GET_UVALUE=pstate

uName=WIDGET_INFO(event.id,/uname)

;窗口关闭

ifTAG_NAMES(event,/STRUCTURE_NAME)eq'WIDGET_KILL_REQUEST'thenbegin

WIDGET_CONTROL,event.top,/destroy

ptr_free,pstate

RETURN

endif

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

;return

;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

WIDGET_CONTROL,(*pstate).list1,SET_VALUE=t

(*pstate).MoveWindow=x

endif

endifelsebegin

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

WIDGET_CONTROL,(*pstate).field3,SET_VALUE=2

(*pstate).Threshold=2

return

endelse

end

'yuzhi':

begin

WIDGET_CONTROL,event.id,GET_VALUE=y

ifyge(*pstate).MoveWindow*(*pstate).MoveWindowthenbegin

void=DIALOG_MESSAGE('“阈值”必须小于“移动窗口”值平方',title='提示')

WIDGET_CONTROL,event.id,sET_VALUE=2

return

endifelsebegin

(*pstate).Threshold=y

endelse

end

'buchang':

begin

WIDGET_CONTROL,event.id,GET_VALUE=z

(*pstate).step=z[event.index]

end

'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

end

'lujing':

begin

WIDGET_CONTROL,event.id,get_value=outname

(*pstate).out_name=outname

end

'queding':

begin

if(*pstate).out_nameeq''thenbegin

void=DIALOG_MESSAGE('请指定输出路径',title='警告')

return

endif

EliminateSpeckle,(*pstate).Fid,(*pstate).out_name,(*pstate).MoveWindow,(*pstate).Threshold,(*pstate).step

end

'quxiao':

begin

WIDGET_CONTROL,event.top,/destroy

end

'help':

begin

HelpButton,event;启动帮助文档

end

else:

begin

end

endcase

end

;####主程序界面

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='yidong')

field3=CW_FIELD(cstlb,TITLE='阈值:

',/FRAME,value='2',$

/INTEGER,/ALL_EVENTS,uname='yuzhi')

list1=WIDGET_dropLIST(cstlb,value=['3','2','1'],xsize=200,title='步长:

',uname='buchang')

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='输出路径和文件名:

')

lable=WIDGET_LABEL(ljtlb1,value='')

xz=WIDGET_BUTTON(ljtlb1,value='选择',Uname='xuanze')

ljtlb2=WIDGET_BASE(ljtlb)

txt=WIDGET_TEXT(ljtlb2,uname='lujing',/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='确定',uname='queding')

lable=widget_label(qdtlb,value='')

qx=WIDGET_BUTTON(qdtlb,value='取消',Uname='quxiao')

lable=widget_label(qdtlb,value='')

qx=WIDGET_BUTTON(qdtlb,value='帮助',Uname='help')

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,'RemoveLittleBlock',tlb,/NO_BLOCK,cleanup='clean_up'

end

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1