1.11k likes | 1.39k Views
IDL 高级培训 基础篇. 基础篇 - 语法基础. 1. 变量及其属性. 整型为短整型,注意使用 L 变量的属性是动态改变的 var=5 为整型 var=var*2.0 变为浮点 NaN : ! VALUES.F_NAN、 ! VALUES.D_NAN var= ! VALUES.F_NAN, 则 f inite(var)=1. 基础篇 - 语法基础. 2. 数组 IDL 是面向矩阵的语言,几乎所有运算都可以在数组上使用。 数组表达 : array[n,m] 表示 n 列 m 行(与其他语言有别),按行排列, 0 为下标起点
E N D
IDL 高级培训 基础篇
基础篇 -语法基础 1.变量及其属性 • 整型为短整型,注意使用L • 变量的属性是动态改变的 • var=5为整型 • var=var*2.0变为浮点 • NaN:!VALUES.F_NAN、!VALUES.D_NAN • var=!VALUES.F_NAN,则finite(var)=1
基础篇 -语法基础 2.数组 IDL是面向矩阵的语言,几乎所有运算都可以在数组上使用。 数组表达:array[n,m] 表示n列m行(与其他语言有别),按行排列, 0为下标起点 数组引用:array[subscript],或(array)[subscript] 下标语法:e、e0:e1、e:*、*、array。 array=make_array(10,10,/integer),sub=indgen(12) 合法的下标表示:array[5,5]、array[2:3,5]、array[*,4]、array[*,5:8]、array[4,4:*]、 array[sub]、A[[1,3,5],7:9] reform():array[4,4:*]为1列4行(列向量),reform(array[4,4:*])则为4列1行(行向量) 常数的数组表示:var=5,则var[0]=5(合法!) 赋值:array[[2, 4, 6],5]=[4, 16, 36] where():array[where(array lt 0)]=-999 数学运算:与普通变量基本相同。 * 和 / :表示两个同维数数组对应元素运算 arr1=indgen(5)+1,arr2=arr1。则:arr1*arr2=[1,4,9,16,25],arr1/arr2=[1,1,1,1] # 和 ##:矩阵运算 arr1(n1,m)#arr2(m,n2)=arr(n1,n2),arr1(n,m1)##arr2(m2,n)=arr(m2,m1) 数组串连:arr1(5,6),arr2(5,2)。则:arr3=[[arr1],[arr2]]为(5,8) 注意: arr3=[arr1,arr2]不合法!(一维除外)
基础篇 -语法基础 数组常用函数: 其他常用函数:array_equal、rebin()、congrid()、expand()、reverse()
基础篇 -语法基础 3.结构 一种复合变量,它可以将多种类型的数据存储在一个变量中,对于表示意义相关的数据、程序间交换数据均非常有意义。 类型及定义 命名结构:dot={PIXEL ,x:128 ,y:236 ,color:bytarr(3)},定义后可使用FIXEL定义其他结构 dot1={PIXEL ,x:58 ,y:46 ,color:[255,0,255]}、 dot2={PIXEL ,58 ,46 ,[255,0,255]}、dot3= {PIXEL} 匿名结构:person={name:’jack’ ,id:123456L},定义后无固定结构,可任意改变 person={name:’jack’ ,id:123456L ,phone:’123-4567’} 引用 变量引用:使用变量名或变量在结构中的位置索引。如:dot.x或dot.(0) 数组变量:s={arr:indgen(10)},则s.arr=10将数组所有元素赋值为10。 结构数组 定义:dotarr=replicate({PIXEL} ,10),或dotarr=replicate(dot ,10) 引用:dotarr[1].x=10、dotarr.x=10将所有结构的x赋值为10、dotarr.y=indgen(10) 结构中的变量的类型和(数组)大小 结构定义后,各变量的数据类型以及数组变量的维数均不可改变。当使用中出现不一致时向原类型转换,不能转换时报错。 var=dot.x*1.0=128.0,为浮点,而dot.x=dot仍为整型。 s.arr=-indgen(8)会改变s.arr中前8个元素的值,而s.arr=-indgen(11)会出错。 结构继承 dot3d={POINT ,INHERITS PIXEL ,z:0} 常用函数 creat_struct()、n_tags()、tag_names()、struct_assign()
基础篇 -语法基础 4.指针 建立动态数据结构的有效工具,是实现IDL面向对象编程和Widget编程的基本要素之一。 IDL 的指针与其他语言的指针有很大的不同,它不是指向存储的地址而仅仅是一个轻型的指向一个堆变量的引用(指针变量)。堆变量可以动态分配(数据类型和数组维数),这意味着传递指针变量就相当于传递动态数据。 Pointer Reference Pointer in Heap Variables Pointer Data • 标量 • 数组 • 结构 指针基本操作 创建:ptr=ptr_new( [initexpr] [, /allocate_heap] [, /no_copy] ) 释放:ptr_free ,ptr
基础篇 -语法基础 标量指针 创建:v=5.5,p=ptr_new(v) 引用:print , p ,*p;p1=p,*p1=20,print ,*p 数组指针 创建:arr=findgen(10),p=ptr_new(arr) 引用:print ,(*p)[5] 结构指针 创建:s={name:’joe’ ,age:40 ,height:180} ,p=ptr_new(s) 引用:print , (*p).name 结构内指针 创建:rec={lon:120 ,lat:20 ,data:ptr_new(findgen(2,10))} ,p=ptr_new(rec) 引用:* (*p).data=findgen(2,20) 特殊指针 Null指针:nptr=ptr_new(),仅定义一个指针,并不指向一个堆变量。引用时需重新定义指针。 Empty指针:eptr=ptr_new(/allocate_heap),定义一个指向一个堆变量的指针,但并未定义变量,引用时可以直接定义变量 指针释放 ptr_free ,ptr 相关函数 ptr_valid():ptr_valid(nptr)=0, ptr_valid(eptr)=1 heap_gc:释放没有引用的堆变量 指针数组 ptrarr( d1, ... , d8 [, /allocate_heap] )
基础篇 -编程基础 IDLDE是IDL的集成开发环境,可以使用IDL命令进行交互式命令运行,编写、调试、运行IDL程序,使用GUI Builer开发用户界面,使用项目管理器管理工程项目等。 1.IDL程序 批处理:由一系列IDL命令组成,以IDL->@batchfile方式运行。批处理文件运行时并不编译,因此使用控制结构时必须大量使用续行符($),给书写、理解造成困难。 主程序:与批处理相似,但以end结束,以IDL->.run profile方式运行。主程序运行时先编译,因此可以正常使用控制结构。 过程:与主程序相似,但以pro proname开始,以end结束。以IDL->proname方式运行(也可以先运行IDL->.compile proname,编译但不运行)。 函数:与过程相似,但以function fnname开始,以end结束,并以return语句返回一个IDL变量。以IDL->ret=fnname(para_list)方式运行。 在IDL系统中,一个过程或函数即为一个新的IDL命令。 变量作用范围:批处理和主程序方式的变量为全局变量,可以在IDL开发环境中使用。过程和函数的变量为局部变量,只在过程和函数运行过程中有效。
基础篇 -编程基础 2.参数传递 位置参数:在参数列表中按位置列出参数名,严格的顺序限制。通常用于必选参数。 定义:pro batch ,para1 ,para2 ,... 调用:IDL->batch ,para1 ,para2 ,… 关键字参数:关键字参数与位置无关,且可以与位置参数混合位置。通常放在位置参数之后,用于可选参数。 定义:pro batch ,keywordname=keywordsymbol ,... 调用:IDL->batch ,keywordname=keywordsymbol ,… IDL->batch ,/keywordname 注意:keywordname用于定义,keywordsymbol用于调用。 引用传递和值传递:所有变量为引用传递,其值会被修改。系统变量、下标变量、表达式和常量均为值传递,原变量的值不被修改。 参数传递了吗?传递了什么? n_params():返回位置参数的个数 keyword_set():关键字参数为不为0常量或已定义的引用传递时返回1,否则返回0 arg_present():关键字参数为引用传递时返回1(无论是否定义),否则返回0 n_elements():关键字参数未传递或未定义返回0,否则返回非0数
基础篇 -编程基础 3.错误处理 on_ioerror:当出现I/O错误时,跳转指定的语句。两种用途:跳过错误返回或跳过错误继续。 注意:使用on_ioerror ,null on_error:当程序运行出错时,并不执行一个新的语句,而是指明IDL应该怎样做。 可以设置on_error ,1,或在命令行使用retall catch:格式:catch ,error_var。当程序执行到catch语句时,IDL为改模块记录一个错误处理语句,并将error_var赋值为0。若程序执行出错,则给error_var赋值相应的错误码,然后跳转到catch后第一条语句。注意:使用catch ,/cancel
基础篇 -编程基础 IDL出错处理示意 Error or Exception is Generated Is it an I/O error? Yes Is ON_IOERROR routine in use? No No Is there an error handler defined by the CATCH routine? Yes Handle error with CATCH-defined error handler and continue program execution. Yes No Handle error as indicated by setting of ON_ERROR routine or use default error handling. Handle error as indicated by ON_IOERROR setting.
基础篇 -编程基础 4. 编译与运行 批处理:@bacthfile,运行 主程序:.run,编译、运行 过程和函数:.compile,编译;->proname,编译、运行。 编译规则:(1)编译到主程序后,编译停止 (2)编译到与文件同名的程序模块时,停止编译 (3)编译到文件末尾或适合其他规则时,停止编译 自动编译规则:当过程或函数出现在命令或代码中时,会自动被编译执行。 (1)过程或函数所在的文件应在当前工作路径和 !Path指定的路径中 (2)过程或函数名与文件名相同 编译函数:resolve_routine、resove_all。可用于程序模块中。 .sav:IDL->save,编译后存储为.sav文件,便于发布。但版本间不兼容。
基础篇 -输入输出 1.常用概念 文件操作:openr,openw,openu,close 逻辑设备号:1~99,直接使用 100~128,使用get_lun获取,free_lun释放 常用函数:dilog_pickfile,findfile,filepath 2.文本文件的格式处理 自由格式:readf,printf,strsplit readf中只接收变量引用,不接收值引用 format语法:format=‘()’,括号内为格式符及其组合 A:[n]a[w],n为重复次数,w为输出宽度 I:[n]i[w]或[n]I[w.m],缺省w=7,特殊用法:i0 F:[n]f[w.d],缺省w=15 X:[n]X,空格 /:换行符 ::其后的格式不用于最后一项。如每个输出项后加一个‘,’时,最后一项不加。 C:c(),表示日期,接受julian日期。有丰富的子集
基础篇 -输入输出 3.二进制文件的关连变量处理 基本命令:readu,writeu 关联变量:大型重复单元二进制文件的有效读取手段,可以随机读取。 一个文件可建立多个关联,解决重复单元不一致的情况。 assoc():result=assoc(unit,array_structure [,offset] [,/packed]) 4.使用与机器无关的数据格式
IDL 高级培训 直接图形篇
直接图形篇 -色彩控制 1. 基本概念 颜色构成:(r,g,b),每个颜色值在0~255之间,所以IDL可以表现256*256*256种颜色 颜色表:一个颜色表由一个3列的数组构成,各列分别表示r、g、b值,通常256行。 索引号:颜色表中的索引位置。可以用来获得颜色的r、g、b值 8位显示器和24位显示器:8位显示器只能显示256色,24位则可以显示256*256*256色 2. 索引颜色模式和RGB颜色模式 索引颜色模式:通过颜色表的索引号获得颜色的r、g、b值,用于8位显示器。 RGB颜色模式:直接指定颜色的r、g、b值,用于24位显示器。IDL使用一个长整数表示所有颜色的索引号,c=r+g*256L+b*256L*256L。 3. 动态显示和静态显示 动态显示:索引模式将索引号与颜色表中的特定位置连接,称为动态颜色显示。改变颜色表会影响当前索引号所对应的颜色。通常,8位显示是动态显示 静态显示:RGB模式直接指定颜色本身,称为静态颜色显示。通常24位显示是静态显示。
直接图形篇 -色彩控制 4. device ,decomposed=0|1 decomposed=0:关闭颜色分解,使用索引颜色模式。适用于8位显示和24位显示,但24位时仍是静态显示。此时,可以使用IDL预设的41个颜色表。 decomposed=1:IDL缺省模式,打开颜色分解,使用RGB颜色模式。只适用于24位显示。此时,只能使用长整数的全索引。 5. tvlct ,r ,g ,b [,start] [,/get] :(RGB模式) tvlct ,r ,g ,b ,/get可以获取当前的颜色表。 tvlct ,r ,g ,b ,start可以加载一个颜色表到start指定的入口处。 6. loadct ,table 加载IDL预设的41各颜色表之一 7. 创建自己的颜色表 根据颜色表的原理,可以很容易地创建一个3*n数组作为自己的颜色表,用tvlct加载使用。
直接图形篇 -坐标系 data:数据单位(缺省) dvice:像素单位 normal:归一化坐标,x:0~1,y:0~1 一般来说,在输出图形时,3个坐标系同时存在并都可以使用。 例:对于一个一维数组,在未指定坐标系时,IDL会把数组的下标值作为data坐标系下x轴的值,数组的值作为y值画出曲线。
直接图形篇 -2D图形 创建自己的标注
直接图形篇 -2D图形 多坐标系数据集显示
直接图形篇 -2D图形 画真正的圆
直接图形篇 - 2D图形 在背景上叠加等值线
直接图形篇 - 2D图形 等值线图填充中的“黑洞”
直接图形篇 - 添加文本 • 给图形加文本标注 • xyouts ,x ,y ,string ,font= • TrueType字体设置: • (1)DEVICE ,SET_FONT=font_str ,/TT_FONT ,输出时,使用font=-1|0|1 • (2)font=fnont_str • Windows环境下TrueType字体设置: • font_str='font*modifier1*modifier2*...modifiern’ • For font weight: THIN, LIGHT, BOLD, HEAVY • For font quality: DRAFT, PROOF • For font pitch: FIXED, VARIABLE • For font angle: ITALIC • For strikeout text: STRIKEOUT • For underlined text: UNDERLINE • 注意:并非所有选项在两种方式下均合法!
直接图形篇 -添加文本 使用汉字:font_str=“中文TrueType字体名称” device ,set_font=‘隶书’ ,/tt_font xyouts ,x ,y ,‘ ’ ,font=1 使自己的字体成为IDL的系统字体:编辑 \RSI\IDL54\resource\fonts\tt\ttfont.map
直接图形篇 - 3D图形 建立三维坐标系 IDL使用变换矩阵与三维空间的点相乘,实现在二维显示上模拟三维坐标系。该变换矩阵装入!P.T。实现时,先装入正确的变换矩阵,然后在图形显示前,保证图形命令已经被变换矩阵乘过。 常用方法:(1)带save关键字的surface命令 surface ,data ,/nodata ,/save (2)在surface后,使用surfr命令 surface ,data surfr (3)scale3命令(scale3d:单位立方体) scale3 [,xrange=vector] [,yrange=vector] [,zrange=vector] [,ax=degrees] [,az=degrees] (4)t3d命令 严格、完整、复杂的方法
直接图形篇 - 3D图形 三维散点图
直接图形篇 - 3D图形 曲面图 阴影曲面图 图中色彩变化表示光源的方向
直接图形篇 - 3D图形 用颜色表现另一个数据集的信息 上图为属性数据集 右上、下图为用颜色表示的属性分布信息
直接图形篇 - 3D图形 用彩色图形叠加表现另一个数据集的信息 左图为属性数据集 右图为用叠加在阴影曲面上的彩色曲面表示属性分布信息
直接图形篇 - 3D图形 等值线叠加
直接图形篇 - 3D图形 三维实体创建: shade_volume, volume, value, vertex, polygons scale3 image=polyshade( vertex, polygons) tv, image
直接图形篇 - 图形定位 图形定位: !p.region=[x0,x1,y0,y1](归一化坐标) !p.position=[x0,x1,y0,y1](归一化坐标) !x|y|z.margin=[p1,p2](字符个数,会随charsize改变) 多数图形命令中都带有margin和position关键字,优先级较!变量高 图形位置: 指被坐标轴包围的区域 可以使用!X|Y|Z.margin、 !p.position设置 图形区域 包括图形标题其它注释的区域 可以使用!P.region设置 图形边缘
直接图形篇 - 图形组合显示 如何在一个窗口里显示多个具有不同坐标系的图形? (1)position=[x0,y0,x1,y1] (2)!Multi=[p1,p2,p3,p4,p5] p1:页面上剩余的部分的数目。通常为0,表示擦除窗口开始输出 p2:页面上图形的列数 p3:页面上图形的行数 p4:页面上Z方向上叠加的数目 p5:0,按行显示;1,按列显示
直接图形篇 - 图形组合显示 !Y.omargin=[0,4] !p.multi=[0,2,2,0,0]
直接图形篇 - 图形组合显示 !Y.omargin=[0,4] !p.multi=[0,2,2,0,0] . . . !p.multi=[1,1,2,0,0]
直接图形篇 - 图形文件读写 作为一个数据分析和可视化的工具,IDL支持大量的图形格式。包括:bmp,geo tiff,interfile, jpeg,pict,png,ppm,srf,tiff,x11 bitmap,xwd。但从v5.4起,不再支持gif。 PNG格式:支持最多4个通道的8位或16位数据 单通道数据时,支持调色板 wirte_png ,filename ,image ,[r,g,b]:将图形数据写入PNG文件 其中:(1)如果image为2维数组,并且提供r、g、b值,则转换为byte以8位数据写入,否则转换为16位无符号整数。 (2)对单通道数据, r、g、b值必须提供,对多通道数据, r、g、b值被忽略 ok=query_png(filename ,s):获取PNG文件的属性。 其中:ok=0,不是合法的PNG文件。 s为一个结构,包含PNG文件的属性。若s.has_palette=1,为单通道数据,否则为多通道数据。 image=read_png(filename [,r,g,b]):读出PNG文件的数据 其中:r,g,b对单通道数据,读出调色板,否则忽略。 常见用法:write_png ,filename ,tvrd(true=1) (作为3通道数据写入) ok=query_png(filename ,s) . . image=read_png(filename) tv image ,/true
直接图形篇 - 图像处理 图像:任何一个二维数组都可以视为一幅图像。 8位图像:总表示为一个二维数组。 24位(真彩色)图像:总表示为一个3维数组,其中一维为3。 m*n*3:隔波段扫描(band-interleaved ,true=3) m*3*n:隔行扫描( row-interleaved ,true=2) 3*m*n:隔象素扫描( pixel-interleaved,true=1) 在8位显示设备上,所有数据要转换位字节类型;在24位显示设备上,24位图像的r、g、b值必须转换位字节类型。
直接图形篇 - 图像处理 1. 基本操作 显示:tv和tvscl。两个命令几乎一样,包括可以使用的关键字。都不删除当前窗口的内容。 tvscl:将图像数据调整为与运行时刻所有可用颜色数目相同的字节数据。通常用于8位图像 tv:取图像数据本身,作为字节数据显示。如果图像数据以整形和更多位数表示,则被截断以适合字节类型。因此,图形可能会显示不正确。 在24位设备上显示图像一般方法: device ,decomposed=0 [loadct ,ct] tv/tvscl ,image(8位图像) tv ,image ,true=1|2|3(24位图像))
直接图形篇 - 图像处理 2. 调整数据为字节类型并可以使用统一的颜色集 bytscl(image ,min= ,max= ,top=) 如:scaleImage=bytscl(image ,min=5 ,max=30) 3. 改变图像尺寸 IDL提供了两个改变图像大小的命令:rebin和congrid rebin:新建的图象的大小必须是原始尺寸的整数比例。缺省放大时采用双线性插值,缩小时采用邻近平均法。sample关键字指定最近邻近采样法。 congrid:新建的图象的大小可以是原始尺寸的任意比例。缺省对三维以下数据采用最近邻近采样法,三维采用线性插值法。interp关键字指定线性插值法 4. 在窗口中定位图像 (1) tv ,image ,index:根据图像尺寸,从窗口左上角开始计算位置,逐行至右下角。 (2) tv ,image ,x ,y:指定左下角开始计算的坐标(devic|data|normal)。 利用!d.x_vsize和!d.y_vsize(象素值)计算归一化坐标以确定图像位置和大小。 5. 从窗口中读取图像 8位显示:image=tvrd() 24位显示:image=tvrd(true=1) tvrd命令支持读取指定区域的图像
直接图形篇 - 图像处理 6. 基本图像处理 上图:原始图 中图:hist_equal函数 下图:adapt_hist_equal函数 直方图均衡化:观察图像中的象素值分布,往往会发现象素值分布趋于一个较狭窄的数值范围内。如果将象素值分散开,使象素值得每个子范围都有与这些象素值大约相同的象素,则该图像的信息内容有可能增加。将象素分布道整个颜色范围的过程称为直方图均衡化。
直接图形篇 - 图像处理 负片:将原始图像的显示色板翻转,象素的字节值不变所得到的图像。
直接图形篇 - 图像处理 消除噪声:噪声来自多方面,影响对图像质量。噪声的一般表现形式是随机的具有极端值的象素(黑白噪声)。 median:计算相邻象素的中间值。这样既可以消除极端值,又不会使大于邻域的部分图像边缘或特征模糊。
直接图形篇 - 图像处理 平滑:通过将每个象素值与它周围相邻象素值进行平均来平滑图像。称为均值或核状平滑。 smooth:在给定的奇数宽度的范围内通过等加权值实现平滑。 convol:使用给定的方形滤波核通过卷积实现平滑。 晕光蒙片:将原始图像减去平滑后的图像。可以定位图像上的边缘或象素值突然变化的地方 上图:smooth,w=5 中图:smooth,w=3 下图:convol,k=1,2,1 2,8,2 1,2,1
直接图形篇 - 图像处理 边缘增强:通过锐化或微分以增强边缘。 roberts: sobel: convol:使用给定的方形滤波核通过卷积实现。 右图:原始图像 下图:自左至右依次为roberts、sobel、convol
直接图形篇 - 图像处理 7. 频域滤波 频域滤波是图像 和信号处理的常规手段。可以用于平滑图像、锐化图像、降低图像的模糊程度和恢复图像。 基本步骤:(1)用快速傅立叶变换(FFT)将图像从空间域转换为频率域 (2)将转换后的图像与一个频率滤波器相乘 (3)将滤波后的图像逆变换转换为空间域 方法:filtered_img=fft( fft(img,-1)*filter ,1) img可以是一维矢量,也可以是二维图像 filter为滤波器,用于滤波图像中某些特定频率的一维矢量和二维数组。 创建滤波器: 欧氏距离图(频率图像):r=dist(n [,m]),n和m与实际图像相同 Butterworth频率滤波器: 低通滤波:filter=1/[1+c*(r/r0)2n] 高通滤波:filter=1/[1+c*(r0/r)2n] 其中:c=1.0或0.414(即当r=r0时,滤波幅度为0.5或1/sqrt(2)) r0为滤波器截止频率(实际中使用象素宽度) n为滤波器阶数,通常n=1 通常,低频项代表图像的一般形状,高频项对应图像的细节
直接图形篇 - 图像处理 东海海表面温度图 NOAA12 2000.9.23 20:40 左图:原始图 中图:低通(w=10) 右图:高通(w=10)
直接图形篇 - 图形窗口输出 IDL支持多种设备输出,并可以简单地在设备之间切换。 set_plot ,’option’:option=win|ps|printer,大小写不敏感。 !d.name:当前设备名。 一般用法: cDevName=!d.name set_plot ,‘printer’ help ,/device set_plot ,cDevName 常用关键字: close_document:刷新输出缓冲区后关闭图形文档,用于从打印机排出打印页。 close_file:刷新输出缓冲区后关闭图形输出文件。 Filename:当输出为文件时地文件名,默认‘idl.option’ landscape:横向输出 portrait:纵向输出,缺省值 xoffset:确定纵向模式下输出窗口左下角(横向模式下ps和printer算法不同) yoffset:确定纵向模式下输出窗口左下角(横向模式下ps和printer算法不同) xsize:确定输出窗口宽度 ysize :确定输出窗口长度 inches:以英寸为单位,缺省为厘米
直接图形篇 - 图形窗口输出 ps 输出的一般方法: img=tvrd(true=1) set_plot ,‘ps’ device, filename=‘ .ps’ ,color=1 device ,xsize= ,ysize= ,xoffset= ,yoffset= tvscl, img ,/true device, /close_file set_plot ,‘win’ printer输出的一般方法: ok=dialog_printersetup() img=tvrd(true=1) ratio=float(!d.y_vsize)/!d.x_vsize (printer设备不能自动保持纵横比) set_plot,'printer' device,get_page_size=spagesize spagesize=spagesize/[!d.x_px_cm,!d.x_px_cm] device ,xoffset= ,yoffset= tvscl ,img ,/true ,/centimeters ,xsize= ,ysize= *ratio device ,/close_document set_plot ,’win’
IDL 高级培训 应用程序构造篇