FIT文件格式解析及MATLAB读取程序

FIT文件格式解析

(http://blog.csdn.net/shizhixin,Email: [email protected],2011年12月) 

摘要:本文档主要介绍了用UltraEdit查看FIT文件及简要的说明了FIT文件的数据存储方式,并附上了FIT文件数据读取及保存为TXT的MATLAB程序。此外,通过读取lamda的相关信息,文中还显示了5条FIT文件中读取出来的光谱。
 

用UltraEdit打开一个光谱FIT文件,其十六进制表示如下:



一个 FIT 文件包含一系列逻辑单元,而每个单元的开头都是用一组标题记录描述随后的数据记录。一个 FIT 文件的逻辑记录长度总是 2880 字节(bytes),每字节8 位(bits)。标题和数据组都在一个新的逻辑记录里起始。FIT标题用 ASCII 码编辑成每一个开始用一个 8 字符的关键词(keyword) 定义信息的类型(80字符)。一个 FIT 标题卡片映象的基本语法格式是:

Keyword=Value/Comment

(关键词=参数值/注释说明)

关键词是一个左边对齐的 8 字符 ASCII 码字符串, 放在 1-8 列里, 字母必须大写。“=”号出现在第 9 列, 而第 10 列是空格。逻辑值(F 或 T)和数值在数值区中紧靠右排列,字符串用符号: ' ' 括出,字母大写。符号“/”用来表示数值区结束。注释说明紧接符号“/”,用大小写ASCII码字符书写。因此,为了在普通计算机上简化参数译码,要求对大多数基本参数使用一个固定格式,而且对所有其他参数也建议使用这个固定格式,建议和部分要求的固定格式如下:

1) Logical Variable (逻辑变量): T 或 F, 在 30 列里。

2) Integer Variable (整数变量): 右对齐在 11-30 列里,若有虚部右对齐在31-5 0 列里。

3) Real Variable (实变量): 要求 10 进制小数点,右对齐(如果用指数记数法)在 11-30 列里, 若有虚部,右对齐(如果用指数记数法)在 31-50 列里。

4) Character Variable (字符变量):虽然允许较长的字符串,但正常的长度用 8 个字符表示。在11 列里用符号 ' 随后跟字符串,紧接着用一个符号 '结束,它不能出现在 20 列之前。

按照此方法,可以读取出来FIT文件的头文件记录如下:

SIMPLE  =                    T / NORMAL FIT IMAGE                             
BITPIX  =                  -64 / DATA PRECISION                                
NAXIS   =                    2 / NUMBER OF IMAGEDIMENSIONS                    
NAXIS1  =                 3992 / NUMBER OF COLUMNS                             
NAXIS2  =                  250 / NUMBER OF ROWS                                
EXTEND  =                    T /Extensions may bepresent                      
CRVAL1  =        3.56089999899 / Central wavelength(log10) of first pixel     
.
.
.
WAT0_001= 'system=linear'      /                                               
WAT1_001= 'wtype=linear label=Wavelength units=Angstroms'/                    
CD1_1   =          0.000100000 / Log10 dispersion perpixel                    
CRPIX1  =                    1 / Starting pixel(1-indexed)                    
CTYPE1  ='LINEAR  '           /                                                
DC-FLAG =                   1 / Log-linear flag                               
END  


头文件读取完后,紧接的是数据文件,但是这里注意的是头文件的字节大小必须如开始说的是2880的整数倍,否则在后补空格。全部记录长度均为 23040 bits (2880bytes *8 bit, 3840bytes*6 bit)。这个长度能用市场上出售的所有计算机的位长和字长除尽, (即 6,8,12,16,18,24,32,36,48,60 和 64 bits)。这种通用性适用于在各种各样的计算机上读写记录。如图:

FIT文件格式解析及MATLAB读取程序_第1张图片

END结束的位置在0x27b2(第10162个字节处,可以通过读取这个关键字获取),所以从0x27b3开始补空格,空格的结束位置应该计算如下:

NUMBER_HEAD_UNIT= 10162/2880=3.5284722222222222222222222222222

因而头文件应该包括四个2880的数据单元,即头文件结束的位置:

END_HEADER_POSITION= 2880*4=11520(0x2cff)

空格应该在0x2cff处结束。从文件开头到偏移11520个字节,即0x2d00处开始正式的数据存储,如下图所示:
FIT文件格式解析及MATLAB读取程序_第2张图片

这里注意的是上图中0x2d00处的00表示起始数据就是0,不是其他标志。数据的实际长度为:

NAXIS1* NAXIS2 * BITPIX /8 = 8276000

其中:

NAXIS1:数据列数;

NAXIS2数据行数,这里数据250应该为250条光谱数据(通过焦面上4000根光纤和16台光谱仪);

BITPIX:数据表示的位数,64位,8个字节;

但是,8276000/2880 = 2873.6111111111111111111111111111,不是2880的整数倍,所以文件存储的长度应该为:

DATA_LENGTH= 2874*2880 = 8277120

所以,结束地址应该是:

END_DATA_POSTION= END_HEADER_POSITION + DATA_LENGTH

= 11520+8277120=8288640(0x7e7980)

如图所示:
FIT文件格式解析及MATLAB读取程序_第3张图片

 从上图也可以看出,数据结束后又开始了新的文件头,新的数据块,这里的数据存储及读取方式如开始所述类似,此处不再赘述。

    下面附上MATLAB程序,其中包含了对数据的读取和写入TXT文件:

clc,clear,close all;
filename = '20100121\9b_1_sp01.FIT';
fr_id = fopen(filename,'r','s'); %FITfile
info=FITinfo(filename); 
%FIT file head info, which includeprimarydata and image
oset=info.PrimaryData.Offset;
%thesize of primarydata head and it is also the start of primarydata
cols =info.PrimaryData.Size(1);%the columns of primary data
rows =info.PrimaryData.Size(2);%the rows of primary data
SIZE_UNIT = 2880;   %The size of a FIT logical record
SIZE_TYPE_NAME= 8; % size of keyword, Keyword= Value/Comment
SIZE_TYPE = 80;     % size of (Keyword= Value/Comment)
num_type_prim = oset / SIZE_TYPE;%the numbers of primarydata head type
 
%-------get the start position oflamda and its step(log10)
for i=1:num_type_prim
   fseek(fr_id, (i-1)*SIZE_TYPE,-1);
   type_name = fread(fr_id, SIZE_TYPE_NAME,'*char');
   switch type_name'
        case 'BITPIX  ' %data dispersion
            fseek(fr_id,2,0); %skip two bytes,cause there are '= ' after type_name
            str_tmp = fread(fr_id, SIZE_TYPE -SIZE_TYPE_NAME - 2,'*char');
            data_percision =str2num(str_tmp(1:20)');
            data_percision = abs(data_percision);
        case 'CRVAL1  '  %thestart position of lamda
            fseek(fr_id,2,0);
            str_tmp = fread(fr_id, SIZE_TYPE -SIZE_TYPE_NAME - 2,'*char');
            lamda_start =str2num(str_tmp(1:20)');
        case 'CD1_1   ' %the step of lamda
            fseek(fr_id,2,0);
            str_tmp = fread(fr_id, SIZE_TYPE -SIZE_TYPE_NAME - 2,'*char');
            lamda_deta =str2num(str_tmp(1:20)');
   end
end
 
% calc the array of lamda(not logformat)
lamda = lamda_start:lamda_deta:lamda_start+lamda_deta*(cols-1);
for i=1:length(lamda)
   lamda(i) = 10^lamda(i);
end
 
%--------------------write primaryhead----------------------
fph_id =fopen('primary_head_info.txt','w','b');
fseek(fr_id,0,-1);
for i=1:num_type_prim
   head_info = fread(fr_id,SIZE_TYPE);
   fwrite(fph_id,head_info);
   fprintf(fph_id,'\r\n');
end
fclose(fph_id);
 
%--------------------write primarydata----------------------
fpd_id =fopen('prim_data.txt','w','s');
fseek(fr_id,oset,-1);
for i=1:5 %because of the openspeed in txt, this only write five rows data into txt file.If you want all, youcan replace 5 with rows
   data_prim = fread(fr_id, cols, 'double');
   figure
   plot(lamda, data_prim);
   fprintf(fpd_id,'%f ',data_prim);
end
fclose(fpd_id);


程序运行结果:
 FIT文件格式解析及MATLAB读取程序_第4张图片

FIT文件格式解析及MATLAB读取程序_第5张图片


 

参考文献

[1]柯大荣 赵永恒.FIT 基本格式及其扩展.中国科学院北京天文台,1993年7月,

http://www.lamost.org/~yzhao/doc/FIT.html

[2] FIT Standard, Definition of theFlexible Image Transport System 

你可能感兴趣的:(image,header,Integer,matlab,存储,character)