**
芬兰SPECIM高光谱相机数据处理(一)
**
读取高光谱数据
1、光谱数据结构
该研究是基于芬兰SPECIM两款相机采集的数据,其余高光谱设备采集的数据结构和特点可能会有一些差别。首先我们要说明一下高光谱数据的特点,这对于后续的分析分析非常有用。
文件夹capture中存放了高光谱数据;文件夹metadata中存放了相关配置文件;一张图片是高光谱数据的可视化,他是有上个波长数据融合成的三通道彩色图像,主要是便于用户图像处理,提取感性提取区域等。我们主要介绍capture中相关数据。
芬兰SPECIM采集到的高光谱数据格式为RAW,是一种ENVI的标准格式。在数据文件夹中还包含了设备暗电流和白平衡数据。并且包含了数据的说明文件(huangshuizhong.hdr),其中包括数据的层数、尺寸、波段中采样的具体波长等等,可以点开文件查看。接下来我们直接入正题,即光谱数据的白平衡校正和暗电流校正。
2、在matlab中的数据读取方法
先上代码,再说闲话。
%% 读取文件raw的hdr文件
function [samples,lines,bands,precision,interleave,wavelength]=read_ENVIrawhdr(rawfilename)
%% 获取hdr文件路径
hdrfilename=strcat(rawfilename(1: (length(rawfilename)-4)), '.hdr');
%% 读取头文件
fid = fopen(hdrfilename, 'r');
info = fread(fid,'char=>char');
info=info';%默认读入列向量,须要转置为行向量才适于显示
%% 获取samples值
a=strfind(info,'samples = ');
b=length('samples = ');
c=strfind(info,'bands');
samples=[];
for i=a+b:c(1)-1
samples=[samples,info(i)];
end
samples=str2num(samples);
%% 获取bands值
a=strfind(info,'bands = ');
b=length('bands = ');
c=strfind(info,'lines');
bands=[];
for i=a+b:c(1)-1
bands=[bands,info(i)];
end
bands=str2num(bands);
%% 获取lines值
a=strfind(info,'lines = ');
b=length('lines = ');
c=strfind(info,'errors');
lines=[];
for i=a+b:c(1)-1
lines=[lines,info(i)];
end
lines=str2num(lines);
%% 查找数据类型
a=strfind(info,'data type = ');
b=length('data type = ');
c=strfind(info,'header offset');
datatype=[];
for i=a+b:c-1
datatype=[datatype,info(i)];
end
datatype=str2num(datatype);
precision = [];
switch datatype
case 1
precision='uint8=>uint8';%头文件中datatype=1对应ENVI中数据类型为Byte,对应MATLAB中数据类型为uint8
case 2
precision='int16=>int16';%头文件中datatype=2对应ENVI中数据类型为Integer,对应MATLAB中数据类型为int16
case 12
precision='uint16=>uint16';%头文件中datatype=12对应ENVI中数据类型为Unsighed Int,对应MATLAB中数据类型为uint16
case 3
precision='int32=>int32';%头文件中datatype=3对应ENVI中数据类型为Long Integer,对应MATLAB中数据类型为int32
case 13
precision='uint32=>uint32';%头文件中datatype=13对应ENVI中数据类型为Unsighed Long,对应MATLAB中数据类型为uint32
case 4
precision='float32=>float32';%头文件中datatype=4对应ENVI中数据类型为Floating Point,对应MATLAB中数据类型为float32
case 5
precision='double=>double';%头文件中datatype=5对应ENVI中数据类型为Double Precision,对应MATLAB中数据类型为double
otherwise
error('invalid datatype');%除以上几种常见数据类型之外的数据类型视为无效的数据类型
end
%% 查找数据格式
a=strfind(info,'interleave = ');
b=length('interleave = ');
c=strfind(info,'data type');
interleave=[];
for i=a+b:c-1
interleave=[interleave,info(i)];
end
interleave=strtrim(interleave);
%% 查找波长
a=strfind(info,'interleave = ');
b=length('interleave = ');
c=strfind(info,'data type');
interleave=[];
for i=a+b:c-1
interleave=[interleave,info(i)];
end
interleave=strtrim(interleave);
%% 查找波长
a=strfind(info,'Wavelength = {');
b=length('Wavelength = {');
c=strfind(info,',');
d=length(c);
for j=1:d
if c(j)-a-b>0
break;
end
end
Wavelength=[];wavelength=[];
for i=a+b:c(j)-1
Wavelength=[Wavelength,info(i)];
end
Wavelength=str2num(Wavelength);
wavelength(1)=Wavelength;
g=2;
for k=j:j+bands-3
Wavelength=0;
for i=c(k)+1:c(k+1)-1
Wavelength=[Wavelength,info(i)];
end
Wavelength=str2num(Wavelength);
wavelength(g)=Wavelength;
g=g+1;
end
Wavelength=0;
e=strfind(info,'}');
f=length(e);
for j=1:f
if e(j)-c(k+1)>0
break;
end
end
for i=c(k+1)+1:e(j)-1
Wavelength=[Wavelength,info(i)];
end
Wavelength=str2num(Wavelength);
wavelength(g)=Wavelength;
fclose(fid);
这是一个通过标准ENVI头文件(.hdr)读取光谱数据的方法,其中需要注意的是,你必须要注意自己的高光谱书的存储格式,即代码中的datatype,这在ENVI头文件中可以轻松找到。
需要说明的是,该函数的输入参数rawfilename
指向的是高光谱数据的地址(..\name.raw)
。
函数的输出值包括尺寸信息samples,lines,bands
这些参数在头文件中都有详细的描述,它代表的数据的波段数(bands),扫描行数(lines)以及传感器的靶面宽度(samples)。…等,你可以对照程序的注释逐一查看读取的数据相关参数。得到相关参数之后,我们既可以通过参数将数据按照结构重写构造出标准的光谱数据
function [bands,inputdata,inputdata_w,inputdata_d,wavelength]=Read_spectral(Intput_path,Input_Name)
% 获取光谱、白板、暗电流路径
FilePath=strcat(Intput_path,Input_Name);
FilePath_w=strcat(Intput_path,'WHITEREF_',Input_Name);
FilePath_d=strcat(Intput_path,'DARKREF_',Input_Name);
% 打开光谱数据
[samples,lines,bands,precision,interleave,wavelength]=read_ENVIrawhdr(FilePath);
inputdata = multibandread(FilePath,[lines,samples,bands],precision,0,interleave,'ieee-le');
% 打开白板数据
[samples_w,lines_w,bands_w,precision_w,interleave_w,wavelength_w]=read_ENVIrawhdr(FilePath_w);
inputdata_w = multibandread(FilePath_w,[lines_w,samples_w,bands_w],precision_w,0,interleave_w,'ieee-le');
% 打开暗电流数据
[samples_d,lines_d,bands_d,precision_d,interleave_d,wavelength_d]=read_ENVIrawhdr(FilePath_d);
inputdata_d = multibandread(FilePath_d,[lines_d,samples_d,bands_d],precision_d,0,interleave_d,'ieee-le');
数据读取完成,其中inputdata
为高光谱数据,inputdata_w
为白板数据,inputdata_d
为暗电流数据。读取的数据结构为
至此,高光谱数据读取完成,下一节将介绍数据校正以及ROI的提取。