IDL考试前复习笔记(四) 读取光谱文件并绘图

前言
  突然想起来电脑最近网卡不大好,怕回去写不出来,就把第四篇也一带写了,最后辐射定标的回学校再写吧,这个程序属于稍微困难点的程序,需要好好构思构思,而且我对读文件的操作也不大熟,尽量讲清楚!

需求分析

Created with Raphaël 2.2.0 开始 读取*.hdr文件 line.indexof=’...‘ wavelenth 读取*.sli文件 绘制波谱曲线 结束 yes no

这个程序稍微复杂一些,先看看绘制出的效果图吧!在这里插入图片描述

二话不说开始干活!

1.读取hdr文件,读出波长等各种信息
  

    fn = 'D:\envi531\ENVI53\resource\speclib\veg_lib\veg_1dry.hdr'
    openr,lun,fn,/get_lun
    lines = ''		;预定义一个空的字符变量
    waveflag = 0        ;定义一个判断的flag
    waves = ''          ;预定义waves
    ncols = 0           ;预定义一个列
    
    while (~eof(lun)) do begin
    readf,lun,lines
        ;find the samples
        if (lines.indexof('samples') gt -1 ) then begin
            samples = lines.split('=')
            ncols = fix(samples[1])
        endif
        ;find the wavelength       
        if ((lines.indexof ('wavelength = {')gt -1) and waveflag eq 0) then begin
            waveflag = 1
            continue 
        endif
                
        if ( waveflag eq 1 ) then begin
            waves =  waves + lines
        endif 
    endwhile

前面是预定义变量,因为用read的方法读出来的都是字符变量,有些后续需要转成一个float型变量需要提起定义好float变量。

整个程序块在while循环中,其中(~eof)是循环的条件,这个条件就是文件还没有读到最后一行,也就是指针还没到最后。英语就是非end of file吗!
IDL在读取文件的时候有一个指针,它会一行一行的读取文件,当读到最后的时候那个,会有一个返回值,告诉程序文件已经读完了。

   readf,lun,lines
这个就是读取这个驱动(文件或者行咋理解都行),并且赋值给lines这个变量,之前定义的lines是一个空字符,就是用来接收这些数据的。

   if (lines.indexof(‘samples’) gt -1 ) then begin
      samples = lines.split(’=’)
      ncols = fix(samples[1])
   end if

IndexOf方法返回字符串中字符或子字符串的索引,这句话是IDL帮助里的文字,即抽取子字符串的意思,如果这个子字符串里用’samples’这个字符串,那么就会返回一个大于-1的值,如果没有就略过,fix是取整数的意思。突然想起来这个程序好像是某节实验课自己做的,所以有些根本没用的读取,但是这种方法老师又要求掌握。只好写上去了。

   if ((lines.indexof (‘wavelength = {’)gt -1) and waveflag eq 0) then begin
      waveflag = 1
      continue
   end if
这里就是找到’wavelength={'这个字符串,必须要有{'否则会找失败,这句话就是说,如果找到了’wavelength={'并且这个判断的waveflag还为0的话,那么这个循环会一直继续下去,直到找到waveflag这个子字符串,flag会变成1跳出循环。

   if ( waveflag eq 1 ) then begin
      waves = waves + lines
   end if
由于之前wave是一个空变量,当找到’wavelength={'这一字符的时候flag结束了,然后开始循环,他会一行一行的把waves读出来,然后一行一行的加进去,最后形成一个总的waves,但是这个waves仍然是一个字符变量,后续是需要转成浮点型的。
在这里插入图片描述

读完之后waves应该是这样的,在这里插入图片描述

之后我们需要去掉括号和并去除分割的逗号然后提取中间的数字以便为后续的图提供数据,

   waves = strmid(waves,0,strlen(waves)-1)
   wavedata = waves.split(’,’)
   wavedata = float(wavedata)

在这里插入图片描述

首先去掉逗号,利用split,split就是切割去除的意思,看下面这个例子
在这里插入图片描述

分割开,分割开之后大括号也一起没了(我也不是特别懂,但是断点运行之后确实是酱),直接利用float转换类型,ok再free_lun释放文件指针

   free_lun,lun
前半部分完成,有用的其实只有找到wavedata即波长,因为后面的画图需要它当x。

   data = make_array(826,74,type=4)
   fn1 = ‘D:\envi531\ENVI53\resource\speclib\veg_lib\veg_1dry.sli’
   openr,lun,fn1,/get_lun
   readu,lun,data
   free_lun,lun

这个看过前面文章
应该都明白了,可以看看用vscode打开二进制文件是啥样的
在这里插入图片描述

毕竟为了保护呗。读取部分毕,开始绘图。

2.精细化绘图
为啥说是精细化绘图呢,因为绘图的时候我当时延续了MATLAB绘图的习惯,喜欢把细节做到位,所以有些不是老师需要的部分,至于看不看就随便
~~^ ^- ~~

    p1 = plot(wavedata,data[*,1],name = 'Spruce Cellulose',linestyle = 1,THICK=2.5)
    p2 = plot(wavedata,data[*,2],/overplot,linestyle = 2.5,THICK=2,color = 'red',name = 'Cotton Cellulose')
    leg = legend(target = [p1,p2],position = [0.95,0.95])
    
    p1.FONT_SIZE = 15
    p1.title = 'Spectral plot'
    p1.title.FONT_SIZE=30
    
    ax = p2.axes           
    ax[0].TITLE = 'Spectral (Micrometers)'
    ax[1].TITLE = 'reflectance '   
    ax[2].hide = 1
    ax[3].hide = 1
    ax[0].ticklen=0.01
    ax[1].ticklen=0.01  

首先plot是绘图的意思,x是wavedata即它的波长,data[*,1]就是要刚才读取出data的第一行,*是全访问的意思,然后name,linestyle等等都是附加选项,
记得p2的时候加上/overplot,否则覆盖原有的图像,和 MATLAB hold on是一个道理
p其实现在是一个对象,你可以加入很多属性,比如我下面的p1.fontsize就是控制它的字体的大小,原来坐标轴有4个,从0-3,我们先取出p2的坐标轴,即
ax=p2.axes,我希望只要2个坐标轴,所以我就把23的坐标轴隐藏了,就是ax[2].hide,ax3.[hide],然后坐标轴凸出来的尖锐太长了,就控制下,即ticklen,

咋回事儿又写了5000字。markdown给的统计字数给了5024字。

  • 8
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值