讀*.spa檔案,比較靠譜的方法似乎還是,直接用UltraEditor開啟二進位制檔案,找相關的位置並猜測...
首先 , filename = 'c:/Documents and Settings/User Name/My Documents/Spectral Sample.SPA' %包括路徑名的檔名
然後 , fid = fopen(filename,'r'); %二進位制格式開啟, 並準備讀取
同時, 用ultraEditor開啟同一個譜圖檔案:
首先, 第1~18個位元組代表了18個標識性字元, 'Spectral Data File', 可以用來作為判斷該檔案是否Nicolet *.spa格式的標識
其次, 第0x360H, 到0x36dH個位元組, 也就是第864~877位元組, 14個位元組, 共14個字元代表'%Transmittance',即資料是透過率方式表達的.
當前的發現是:
1. fseek(fid,hex2dec('41c'),'bof'); spectrum=fread(fid,1868,'float32'); %在偏移量0x41c處讀取1868個單精度浮點數, 得到譜圖.
其中資料點數1868來自後面的搜尋.
2. fseek(fid,576,'bof'); fread(fid,1,'single')
ans =
3.999639892578125e+003, 找到的是最大波數
3. fseek(fid,580,'bof'); fread(fid,1,'single')
ans =
3.991925964355469e+002, 找到的是最小波數
在找這兩個關鍵波數的位置的時候, 用到了下面的scripts:
clc
filename='c:/Documents and Settings/User Name/My Documents/051109 sample B.SPA';
fid=fopen(filename,'r');
fseek(fid,hex2dec('484'),'bof');
spectrum=fread(fid,934,'double'); % 只是確認找到的譜圖資料的位置而已
plot(spectrum,'r'); %此處的934, 不能再大, 但是卻可以更小... 不見得是934個數據點...
frewind(fid);
data=0;
position=0;
flags=1;
counts=0;
loops=0;
Number_to_be_found=3999.63989;
%580=position, find: 3999.63989;
%584=poistion, find: 399.192596;% 1.928467;
data_format= 'single';
while flags
while ~feof(fid)
data=fread(fid,1,data_format);
%if ~isempty(data)
position=position+4;
%end
loops=loops+1;
if ~isempty(data)
if abs(data-Number_to_be_found)<0.005
'find'
data
position
loops
break
end
end
end
counts=counts+1;
if counts<=8
frewind(fid);
header=char(fread(fid,counts,'uchar')')
%fseek(fid,counts,'cof');
position=counts;
else
flags=0;
end
end
data
position
loops
其它,
4. 譜圖檔名的位置: fseek(fid,hex2dec('23eb'),'bof'); fullfiname=char(fread(fid,260,'uchar')')可以得到
5. 關於譜圖的波數和精度, 奇怪怎麼是用文字的形式交代的
譜圖的背景掃描的時間方面, 星期幾: fseek(fid,hex2dec('32a'),'bof'); fullfiname=char(fread(fid,3,'uchar')')
月份: fseek(fid,hex2dec('32e'),'bof'); fullfiname=char(fread(fid,3,'uchar')')
日期: fseek(fid,hex2dec('332'),'bof'); fullfiname=char(fread(fid,2,'uchar')')
時刻: fseek(fid,hex2dec('335'),'bof'); fullfiname=char(fread(fid,8,'uchar')')
年份: fseek(fid,hex2dec('324'),'bof'); fullfiname=char(fread(fid,4,'uchar')')
時區: fseek(fid,hex2dec('343'),'bof'); fullfiname=char(fread(fid,11,'uchar')')
相鄰兩個資料點的 波數間隔
fseek(fid,hex2dec('37e'),'bof'); str2num(char(fread(fid,6,'uchar')'))
資料點的個數
fseek(fid,hex2dec('234'),'4c79'); fread(fid,1,'int32')
波數的最大值 和 最小值 之差 , 絕對值之後, 除以 波數間隔, 取四捨五入的結果, 再加1,