使用matlab读取ENVI_standard格式数据的方法
程序员文章站
2024-03-24 22:31:28
...
寻找文中这三种方法花了我一下午的时间,把他们发出来希望能给同行们便利。
所有方法均非原创!只是想汇集起来方便大家ctrl+C
ENVI_standard文件的获取
方法①:matlab内置函数
在matlab中输入:help multibandread
看看介绍说明基本就懂了。
用写字板打开.hdr文件,可以找到参数。
(关于data type,在方法③的M文件里有说明)
例子如下:
inputimg = multibandread('tifname',[M,N,D],'uint16',0,'bsq','ieee-le' );
方法②:freadenvi.M
M文件如下:
function [image,p,t]=freadenvi(fname);
%%%%%%%%%%%%%
% Parameters initialization
elements={'samples ' 'lines ' 'bands ' 'data type '};
d={'bit8' 'int16' 'int32' 'float32' 'float64' 'uint16' 'uint32' 'int64' 'uint64'};
% Check user input
if ~ischar(fname)
error('fname should be a char string');
end
% Open ENVI header file to retreive s, l, b & d variables
rfid = fopen(strcat(fname,'.hdr'),'r');
% Check if the header file is correctely open
if rfid == -1
error('Input header file does not exist');
end;
% Read ENVI image header file and get p(1) : nb samples,
% p(2) : nb lines, p(3) : nb bands and t : data type
while 1
tline = fgetl(rfid);
if ~ischar(tline), break, end
[first,second]=strtok(tline,'=');
switch first
case elements(1)
[f,s]=strtok(second);
p(1)=str2num(s);
case elements(2)
[f,s]=strtok(second);
p(2)=str2num(s);
case elements(3)
[f,s]=strtok(second);
p(3)=str2num(s);
case elements(4)
[f,s]=strtok(second);
t=str2num(s);
switch t
case 1
t=d(1);
case 2
t=d(2);
case 3
t=d(3);
case 4
t=d(4);
case 5
t=d(5);
case 12
t=d(6);
case 13
t=d(7);
case 14
t=d(8);
case 15
t=d(9);
otherwise
error('Unknown image data type');
end
end
end
fclose(rfid);
t=t{1,1};
disp([('Opening '),(num2str(p(1))),('cols x '),(num2str(p(2))),('lines x '),(num2str(p(3))),('bands')]);
disp([('of type '), (t), (' image...')]);
fid=fopen(fname);
image=fread(fid,t);
image=reshape(image,[p(1),p(2),p(3)]);
fclose(fid);
matlab里输入:[image,p,t]=freadenvi('filename');
即可得到输出。
注意:输出是列×行×波段的格式! 我试了把它转置能M×N×D形式,和方法①的结果完全相同。
方法③:read_ENVIimagefile.M
M文件如下:
function data=read_ENVIimagefile(imgfilename)
if length(imgfilename)>=4
switch strcmp(imgfilename(length(imgfilename)-3:end), '.img')
case 0
hdrfilename=strcat(imgfilename, '.hdr');
case 1
hdrfilename=strcat(imgfilename(1: (length(imgfilename)-4)), '.hdr');
end
else
hdrfilename=strcat(imgfilename, '.hdr');
end
fid = fopen(hdrfilename, 'r');
info = fread(fid,'char=>char');
info=info';%默认读入列向量,须要转置为行向量才适于显示
fclose(fid);
a=strfind(info,'samples = ');
b=length('samples = ');
c=strfind(info,'lines');
samples=[];
for i=a+b:c-1
samples=[samples,info(i)];
end
samples=str2num(samples);
%查找行数
a=strfind(info,'lines = ');
b=length('lines = ');
c=strfind(info,'bands');
lines=[];
for i=a+b:c-1
lines=[lines,info(i)];
end
lines=str2num(lines);
%查找波段数
a=strfind(info,'bands = ');
b=length('bands = ');
c=strfind(info,'header offset');
bands=[];
for i=a+b:c-1
bands=[bands,info(i)];
end
bands=str2num(bands);
%查找数据类型
a=strfind(info,'data type = ');
b=length('data type = ');
c=strfind(info,'interleave');
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,'sensor type');
interleave=[];
for i=a+b:c-1
interleave=[interleave,info(i)];
end
interleave=strtrim(interleave);%删除字符串中的空格
%读取图像文件
fid = fopen(imgfilename, 'r');
data = multibandread(imgfilename ,[lines, samples, bands],precision,0,interleave,'ieee-le');
data= double(data);
end
在matlab里输入:image=read_ENVIimagefile('filename');
即可得到相同的输出。
上一篇: Python GDAL学习笔记(一)
推荐阅读