完整版IDL入门教程八Word文件下载.docx

上传人:b****1 文档编号:6019495 上传时间:2023-05-05 格式:DOCX 页数:36 大小:36.80KB
下载 相关 举报
完整版IDL入门教程八Word文件下载.docx_第1页
第1页 / 共36页
完整版IDL入门教程八Word文件下载.docx_第2页
第2页 / 共36页
完整版IDL入门教程八Word文件下载.docx_第3页
第3页 / 共36页
完整版IDL入门教程八Word文件下载.docx_第4页
第4页 / 共36页
完整版IDL入门教程八Word文件下载.docx_第5页
第5页 / 共36页
完整版IDL入门教程八Word文件下载.docx_第6页
第6页 / 共36页
完整版IDL入门教程八Word文件下载.docx_第7页
第7页 / 共36页
完整版IDL入门教程八Word文件下载.docx_第8页
第8页 / 共36页
完整版IDL入门教程八Word文件下载.docx_第9页
第9页 / 共36页
完整版IDL入门教程八Word文件下载.docx_第10页
第10页 / 共36页
完整版IDL入门教程八Word文件下载.docx_第11页
第11页 / 共36页
完整版IDL入门教程八Word文件下载.docx_第12页
第12页 / 共36页
完整版IDL入门教程八Word文件下载.docx_第13页
第13页 / 共36页
完整版IDL入门教程八Word文件下载.docx_第14页
第14页 / 共36页
完整版IDL入门教程八Word文件下载.docx_第15页
第15页 / 共36页
完整版IDL入门教程八Word文件下载.docx_第16页
第16页 / 共36页
完整版IDL入门教程八Word文件下载.docx_第17页
第17页 / 共36页
完整版IDL入门教程八Word文件下载.docx_第18页
第18页 / 共36页
完整版IDL入门教程八Word文件下载.docx_第19页
第19页 / 共36页
完整版IDL入门教程八Word文件下载.docx_第20页
第20页 / 共36页
亲,该文档总共36页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

完整版IDL入门教程八Word文件下载.docx

《完整版IDL入门教程八Word文件下载.docx》由会员分享,可在线阅读,更多相关《完整版IDL入门教程八Word文件下载.docx(36页珍藏版)》请在冰点文库上搜索。

完整版IDL入门教程八Word文件下载.docx

(.pro为默认扩展名。

如果加了其它扩展名,那么应该把文件名称写完整)如下所示:

@ImageOut

注意,文件名没有在引号中,这与IDL文件名的一般规则是不一致的。

IDL会严格执行批处理文件中的命令,就像在命令行上键入一样。

这意味着有必要用行续字符($)和其他命令行语言来让IDL确认键入的命令。

如果在文件中的命令输入错误,那么出现的错误结果和在命令行键入命令出现的错误结果是一样的。

假设要打开8到10个图像文件,因而不得不分别打开每个图像文件,读取数据,然后运行批处理命令将每一个图像显示在窗口中。

具体地说,可以这样自动进行读取数据和显示图像过程:

theseFiles=FindFile(‘*.img’,count=numFiles)

Print,‘numberoffilesfound:

‘,numfiles

Forj=0,numFiles-1DoBegin

Openr,lun,theseFiles[j],/get_lun

Image=BytArr(512,512)

Readu,lun,image

Free_lun,lun

thisImage=BytScl(image,top=199)

LoadCT,5,Ncolors=200

S=size(image)

Window,/Free,XSize=s[1],YSize=s[2]

TV,thisImage

Endfor

但是这个文件不适合于作批处理文件,因为FOR循环里面有多行语句。

如果没有续行符($)和命令连接符(&

)的话,这种程序是很难写在命令行中的。

为了自动执行由多行控制语句组成的命令,最好使用IDL主程序。

编写IDL主程序

IDL主程序和批处理文件在很多方面很相似,但也存在着很大的区别。

像批处理文件一样,一个主程序也包含一系列命令。

但与之不同的是,这些命令必须以END语句结束。

例如,上面自动读取数据和显示图像的程序可以写成一个IDL主程序:

End

批处理文件和IDL主程序最大的区别就是主程序的命令语句先由IDL编译器编译成程序模块,然后才执行代码。

这就是为什么在主程序中可以有多行控制语句的原因。

如果将上面的代码保存在文件ImageOut.pro中,键入如下命令就可以编译并运行这个程序模块:

.RUNImageOut

现在,主程序就已经驻留在IDL内存中了。

同一时间只能有一个主程序驻留在IDL内存中。

如果没有重新编译该代码而要重新运行这个程序,可以使用可执行命令.GO来实现,如下:

.Go

可执行命令(.Go,Compile,Run,等等)只能应用在IDL开发环境中,而不能用在IDL过程和函数中(尽管有很多方法可以在过程和函数中编译程序。

详细情况请参阅P230“特殊编译命令”)

编写主程序的最大优点是在程序中定义的变量可以在IDL开发环境中使用,IDL的命令都是在那里键入并被解释的。

换句话说,在主程序中定义的变量的作用范围是IDL整个开发环境,因而它可以被IDL其它命令使用。

更为通常的是,往往希望限定变量的作用范围,以使它们不致于占用大量的内存。

在编程过程中,使用大量的全局变量会使内存的使用效率大大降低。

为此,大部分应用程序都用过程和函数来编写。

编写IDL过程

IDL过程和IDL主程序很相似,同时也存在很大的区别。

首先,在编写一个过程时,实际上所做的是创造另外一个IDL命令,一个构造在IDL系统语言之上的新命令。

在IDL命令行和程序中,可以使用所创造的命令,就像使用IDL系统内置的命令一样。

过程看起来和主程序非常相似,不过过程是以过程定义语句开始的。

定义语句的目的就是为过程命名(如果喜欢,也可以称之为命令名称)和定义过程参数。

过程的参数既可以是定位参数也可以是关键字。

待一会儿将学到更多有关过程参数如何定义方面的知识。

例如,想将上面的主程序写成一个名为ImageOut的IDL命令,可以这样编写这个过程:

PROImageout

如果这些代码被保存在一个名为ImageOut.pro文本文件中,在命令行上键入此程序的名字,它就会自动编译和执行。

如下所示:

Imageout

有时候想在运行之前清楚显式地编译一个过程或函数。

(例如,在代码中有一个错误,在修改完毕之后,运行之前希望将程序重新编译。

)如果想要显式地编译和运行上面的代码,可以这样键入:

.CompileImageOut

注意,在上述编译语句中的ImageOut是想要编译的文件的文件名(IDL默认.pro为文件扩展名)。

文件名并没有加引号,但是它可能会区分大小写,这取决于当前的操作系统。

.Compile命令将编译该文件中所有的程序模块,但不会运行其中的任何一个。

(在这个例子中只有一个程序模块。

编译方面的详细信息请参阅P228“编译和运行IDL程序模块”。

)文件名不一定必须和过程名称相同,但通常情况是这样的。

上面的第二行语句是想要运行的程序或程序模块的名称。

过程和与函数中变量的作用范围

关于过程和函数很重要的一点是在过程和函数中创建的变量是局部变量。

也就是说,只有过程和函数内部的命令才能调用在他们内部创建的变量。

例如,在上面的过程中,在IDL命令行中是不可能识别变量theseFiles,thisimage或者s的,因为这些变量的作用范围只限于过程。

而且,当IDL退出该过程时(在这种情况即为执行到end语句),这些变量被清除,它们所占用的内存也被释放。

如果所有的变量的作用范围都只是局部的,这就变得极其不方便了。

因为那样就不可能在过程、函数之间,或命令行与过程及函数之间进行信息交流和数据传递了。

因此,可以采用多种办法来扩展变量的作用范围,或在过程、函数之间传入或传出信息通常情况下,信息(例如变量等),是以过程和函数的参数形式来传递的。

创建定位参数

定位参数是在过程的定义语句中被定义的。

一般来说,定位参数的数量没有限制的,但对它们的顺序有严格的要求。

第一个定义的定位参数(“定义”的意思是把它放在过程名称的右边)是参数1,紧接着定义的是参数2,以此类推。

例如,希望指定ImageOut过程通常在哪一个子目录下查找图像文件。

可以通过字符串参数lookHere把信息传入到ImageOut过程中去,修改后的ImageOut过程如下所示,增加部分已用黑体字标出。

PROImageOut,lookHere

Cd,lookhere

若要调用修改以后的过程,应该重新编译它。

之后,就可以这样来调用它:

(假设在Windows操作系统中。

下面的代码仅起示范使用)

.CompileImageOut

ImageOut,’c:

\rsi\mydatafiledir’

字符串c:

\rsi\mydatafiledir被拷到参数(有时也叫形参或局部变量)lookhere后,命令CD根据这个将工作路径改变到与之同名的指定路径中。

这个字符串也可以作为变量传递到过程ImageOut中。

如下面所示:

myimagedirectory=‘c:

ImageOut,myimagedirectory

在这里,变量myimagedirectory通过引用方式来传递的。

它的意思以后将会更详细讨论到。

但其中一点就是,这个变量现在可以在主程序和过程ImageOut中被使用。

这意味着如果在过程内部改变它的值,这个变化将会反应在IDL命令行上来。

换句话说,IDL命令行上的myimagedirectory变量和ImageOut程序中的变量lookhere是相同的。

换句话说,这个变量有两个名字,这两个名字都指向同一个数据或IDL中的物理地址。

(就好比说,一个人在美国时人们叫他为乔,而当他回到家乡智利时是人们叫他乔丝。

两个名字所指的是同一个人,但是一个地方的人只知道他的一个名字。

但是如果在调用ImageOut时忘记了传递参数会怎样呢?

如果键入如下所示会发生什么事?

ImageOut

在这种情况下,什么也不会传递到变量lookhere中去,所以在过程中变量就没有定义(但是,没有定义也是变量的一个有效类型)。

遗憾的是,这会带来很大的麻烦,因为在过程中,CD命令语句把lookhere变量作为它的参数。

而在cd命令中使用一个没有定义的变量会导致错误的。

因此,清楚地知道过程如何被调用是非常有必要的。

定义可选的或必须的定位参数

IDL提供的N_Params命令可以返回过程在被调用时定位参数的调用个数(不包括关键字)。

这个命令如下所示:

Numparams=N_Params()

知道了过程在调用时输入了多少个定位参数,就有机会对所传入的参数是可选择的还是必须的进行判断。

例如,想把参数lookHere作为一个必须的参数,在过程的前几行应增加如下几行:

ProImageOut,lookHere

IfnumparamsEQ0Then$

Message,‘mustsupplyoneparametertothisprocedure.’

Cd,lookHere

这里,message命令会产生一个错误,导致IDL停止执行过程中的命令,同时错误信息被送到命令记录窗口或输出窗口。

这个结果和在没有数据参数的情况下调用plot命令是一样的。

也许在ImageOut过程中把参数lookHere作为一项可选参数更合情合理。

如果没有提供参数,那么lookHere变量的值就会设置为当前子目录。

实现这部分功能的代码如下所示:

ProImageOut,lookhere

IfnumparamsEQ0ThenCD,current=lookhere

在这里,如果在调用ImageOut时没有提供lookhere参数,那么cd命令就和关键字Current一起使用,并将当前工作目录放在lookhere变量中(关键字current在这里是一个输出性质的关键字,关于这个,读者等下将会了解更多。

在IDL过程和函数中,定义参数的习惯性规则是,参数是指必须的参数,关键字是指可选参数。

这种规则常常因为参数而破例,而几乎不会因为关键字而破例。

也就是说,经常可能会出现参数是可选的,却很少有关键字是必选的情况。

定义关键字

和定位参数一样,关键字也是在过程的定义语句中加以定义的。

只要愿意,关键字可以和混杂在参数中定义,(这对参数的相对位置没有任何影响),但一般地,关键字在参数定义之后再定义。

如果读者看了过程ImageOut的代码,就会发现程序中硬性地载入了颜色表5。

但是,如果允许用户指定颜色表,并且只有在用户没有指定的情况下才将颜色表5作为默认的颜色表,那样就更符合情理了。

这便是关键字所起的作用。

关键字定义语法如下:

Keywordname=keywordsymbol

等号左边的是关键字名字,这是关键字使用时的名字;

等号右边是在过程和函数中关键字所赋的值。

例如,下面是为Imageout过程定义关键字colortable的例子:

ProImageOut,lookHere,colortable=thiscolortable

关键字colortable是连同颜色表值一起调用ImageOut过程时即将使用到的名称。

例如,想用Red-Temperature色表,即色表3,来浏览这些图片,可以这样调用过程:

ImageOut,‘c:

\data’,colortable=3

使用缩写关键字

关键字名称,colortable,在使用过程中不必全部拼写,只要有足够多的字母将它和其它关键字区别开来就可以了。

因为colortable是ImageOut中唯一的关键字,所以用c已足够来定义这个关键字。

过程ImageOut也可以这样调用。

ImageOut,’c:

\data’,c=3

或者这样:

\data’,color=3

上述三种调用方法的作用是相同的。

关键字右边的变量,thiscolortable,是用来给程序中关键字赋值的。

在这里值赋为3。

现在可以重新编写ImageOut的代码了(修改部分已用粗体字标出):

ProImageOut,lookHere,colortable=thiscolortale

IfnumparamsEQ0ThenCD,current=lookHere

CD,lookHere

’numfiles

Forj=0,numFiles-1dobegin

Thisimage=BytScl(image,top=199)

LoadCT,thiscolortablel,ncolors=200

Window,/Free,XSize=s

(1),YSize=s

(2)

TV,thisimage

但是如果变量thiscolortable没有定义呢?

换句话说,如果用户这样调用ImageOut过程会怎么样呢?

由于关键字colortable没有被使用,所以在变量thiscolrotable里面什么也没有。

这话也可以这样理解:

变量thiscolortable在过程中没有定义。

如果这样,那么在上述代码中LoadCT命令以下的三分之二的编码都会无效,因为它不能接受一个没有定义的变量作为参数。

这使读者想起上次曾经遇到的情况,即在调用ImageOut时应该知道参数是否被使用。

在这里读者应该知道,在调用ImageOut时关键字是否被使用的情况。

定义可选择的关键字

关键字是可选择的参数。

这意味着,在调用含有关键字的过程和函数时,关键字很可能不会被使用。

但是赋有关键字的值的变量还是会在程序中被使用的。

这意味着要对每一个已经定义的关键字赋予默认值。

实际上如果不这样做的话,IDL应用程序迟早会失败。

但是怎样才知道需要定义默认值呢?

当然,如果用户已经赋值那就没有必要来定义默认值。

但是怎样知道用户是否已赋值了呢?

如果是参数,可以用N_Params命令来提供这方面的信息。

遗憾的是,N_Params只对参数才起作用,而不能提供关于关键字的任何信息。

很多人把这个问题想象为“我想知道关键字使用了还是没有?

”。

如果是这样的话,要查明关键字是否使用比其最初出现的时候要难多了。

我们经常期待好事出现,但是现实却未必如此。

我们问,“这个变量已经赋予了关键字的值还是没有?

关键字定义了吗?

对一个关键字,比如colortable,很可能被赋予很多可能的值,用N_elements这个IDL命令可以知道在过程和功能程序中,变量thiscolortable是否已经定义。

尽管N_emements在IDL中还有其他作用,但是在这个情况下,使用这个函数的功能是:

如果N_emements的参数没有定义,则函数返回值为零。

否则将返回参数的元素个数。

该参数可以是任意数据类型。

在这种情况下,过程ImageOut在用户没有提供色表的情况下,将会定义默认的色表值,它的前几行如下所示:

ProImageOut,lookhere,colortable=thiscolortable

Ifnumparamseq0hencd,current=lookhere

IfN_Elements(thiscolortable)EQ0Thenthiscolortable=5

注意,一定要把关键字的名字(比如,它在IDL命令行中是如何使用的)和赋有关键字的值的变量区分开来。

关键字的名字在关键字定义的左边,赋值的变量在右边。

N_elements的参数必须是关键字的变量,而不是关键字的名字。

这点经常被错误理解,因为一些IDL程序员(包括作者在内)喜欢把关键字名字和变量拼写成一样。

换句话说,如果作者正在为自己编写以下程序,作者会这样写:

ProImageOut,lookHere,colortable=colortable

IfN_Elements(colortable)EQ0Thencolortable=5

这里不存在正确与否,但还是存在区别。

IDL会清楚地区别这些。

建议读者也这样做。

记住,检查的应是关键字变量,不是关键字名字。

作者喜欢把关键字变量和名字拼成一样,因为这样可以减少拼写错误。

我可以认为我是在检查关键字名字,事实上我在检查关键字变量。

处理具有双重属性的关键字

如果仔细检查ImageOut的代码,将会发现图像数据在显示之前已经被拉伸了。

这个特殊代码行是:

图像数据文件很可能已被拉伸过,因此这个步骤并不是必须的。

如果这样的话,就可以定义一个名为scale的关键字,当过程带该关键字调用时,则拉伸图像,如果不带该关键字调用,则忽略图像的拉伸。

这样的关键字具有双重属性,它可以设置也可以不设置。

其它关键字同样具有双重属性,也就是说它们可以是真或假,是或者否,1或者0。

IDL提供了一个特殊的命令来处理类似的关键字,即Keyword_Set命令。

和N_elements一样,Keyword_Set的参数是关键字变量而不是关键字名字。

但Keyword_Set有一点不一样就是,如果Keyword_Set的参数没有定义或者值为0,那么它将会返回0。

否则返回1。

所以,Keyword_Set的返回值只有两种:

0或者1。

许多程序员错误运用了Keyword_Set,用它来检测关键字是否使用。

其实不是这样的,用它来验证一个关键字是否已经使用最终会导致IDL应用程序的错误。

只能在关键字具有双重属性时才能使用它。

在确定只有设置了关键字scale情况下才调用图像拉伸步骤,这时的ImageOut代码可以这样来写:

ProImageOut,lookhere,colortable=thiscolortable,Scale=scaleIt

Ifnumparamseq0thencd,current=lookhere

Thesefiles=findfile(‘*.img’,count=numfiles)

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

当前位置:首页 > IT计算机 > 电脑基础知识

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2