function info = read_envihdr(hdrfile)
% READ_ENVIHDR 读取并返回 ENVI 图像头文件信息.
% INFO = READ_ENVIHDR('HDR_FILE') 读取ASCII ENVI生成的图像头文件,并返回参数结构中的所有信息。
%
% 输出:
% * Info - 具有ENVI文件中提供的字段的结构。ENVI标头格式需要以下字段:
% * samples - 图像中的样本数(列)
% * lines - 图像中的行数(行)
% * bands - 图像中的条带数。如果提供了所有3个维度,则将创建info.size
% [info.lines info.samples info.bands]
% * data_type - 存储为1-15范围内的整数的图像的数据类型。
% 如果提供,则会创建info.format,其中包含带有Matlab类型名称的字符串。
% * interleave - 文件带交错类型;bip、bsq或bil都是可能的
% * byte_order - 字节顺序(0是小端序[最低有效字节优先],1是大端序[最高有效字节优先)。
% 如果提供了info.machine,则会创建一个包含“ieee-le”或“ieee-be”字符串的机器。
%
% 例子 1:
% >> info = read_envihdr('my_envi_image.hdr')
% info =
% description: [1x101 char]
% samples: 658
% lines: 749
% bands: 3
% size: [749 658 3]
% header_offset: 0
% file_type: 'ENVI Standard'
% data_type: 4
% format : 'single'
% interleave: 'bsq'
% sensor_type: 'Unknown'
% byte_order: 0
% map_info: [1x1 struct]
% projection_info: [1x102 char]
% wavelength_units: 'Unknown'
% pixel_size: [1x1 struct]
% band_names: [1x154 char]
% Example 2:
% >> info = read_envihdr('my_envi_image.hsi');
% >> Z = multibandread(gFile, info.size, [info.format '=>double'], ...
% >> info.header_offset, info.interleave, info.machine);
%
% Author: Jarek Tuszynski (jaroslaw.w.tuszynski@saic.com)
% License: BSD (Berkeley Software Distribution)
%
% See Also
% * MATLAB function multibandread
% * http://geol.hu/data/online_help/ENVI_Header_Format.html
%% 如果文件没有“hdr”扩展名,则检查是否有匹配的
% 头文件
[FilePath, FileRoot, FileExt] = fileparts(hdrfile);
if ~strcmp(FileExt, '.hdr') % 若文件后缀不是.hdr
fname = hdrfile;
hdrfile = [fname '.hdr']; % 将文件名给位.hdr后缀
if ~exist(hdrfile,'file')
hdrfile = [FilePath '\' FileRoot '.hdr']; % 替换扩展名
if ~exist(hdrfile,'file')
hdrfile = fname;
end
end
end
%% 将整个头文件加载到字符串中
fid = fopen(hdrfile);
if fid<0, error('%s 不存在 \n', hdrfile); end
str = fread(fid,'uint8=>char')';
fclose(fid);
%% 将字符串拆分成行
flag = 0;
str(str==10) = 13;
str=strrep(str,char([13 13]), char(13)); % 将换行符号编程一个空格
for i = 1:length(str)
switch str(i)
case '{'
flag=flag+1;
case 13
if (flag), str(i)=10; end
case '}'
flag=flag-1;
end
end
lines = textscan(str,'%s','Delimiter',char(13));
lines = lines{1};
%% 将每一行解析为结构的一个字段
info = [];
for iLine=1:length(lines)
[info, param] = ParseLine(lines{iLine}, info);
if ~isempty(param) && ischar(info.(param)) && nnz(info.(param)=='{')
% 如果找到“{”比解析多一层
line = info.(param);
if nnz(info.(param)=='=')==0 % 字符串没有 "=" -> 检查它是否是数字数组,没有‘=’的情况
%nnz()函数表示计算矩阵中非0元素的个数
line(line<32) = []; % 去掉空值
line(line == '{') = '['; % 替换
line(line == '}') = ']'; % 替换
num = str2double(line); % 转化为数字,字符去除
if isnumeric(num) && ~isempty(num)
info.(param) = num;
elseif nnz(info.(param)==',')>0 % string has "," -> split into string cell array
line(line == '[' | line == ']') = [];
lines2 = textscan(line,'%s','Delimiter',',');
info.(param) = lines2{1};
end
else % 存在 "="
line(line == '{' | line == '}') = []; % 取{}内的字符串
lines2 = textscan(line,'%s','Delimiter',newline);
lines2 = lines2{1};
info2 = [];
for jLine=1:length(lines2)
info2 = ParseLine(lines2{jLine}, info2);
end
info.(param) = info2;
end
end
end
%% 创建 属性大小 info.size
if isfield(info, 'lines') && isfield(info, 'samples') && isfield(info, 'bands')
info.size = [info.lines info.samples info.bands];
end
%% fix 'byte_order' field
if isfield(info,'byte_order') % 确定输入是否为结构体数组字段
switch info.byte_order
case 0 % info.byte_order = 0时
info.machine = 'ieee-le';
case 1 % info.byte_order = 1时
info.machine = 'ieee-be';
otherwise % info.byte_order 其它情况
info.machine = 'n';
end
end
%% fix 'data_type' field
if isfield(info,'data_type') % 确定输入是否为结构体数组字段
info.iscomplex=false; % 如果这是
switch info.data_type %
case 1 % info.data_type = 1
info.format = 'uint8';
case 2 % info.data_type = 2
info.format= 'int16';
case 3 % info.data_type = 3
info.format= 'int32';
case 4 % info.data_type = 4
info.format= 'single';
case 5 % info.data_type = 5
info.format= 'double';
case 6 % info.data_type = 6
info.iscomplex=true;
info.format= 'single';
case 9 % info.data_type = 9
info.iscomplex=true;
info.format= 'double';
case 12 % info.data_type = 12
info.format= 'uint16';
case 13 % info.data_type = 13
info.format= 'uint32';
case 14 % info.data_type = 14
info.format= 'int64';
case 15 % info.data_type = 15
info.format= 'uint64';
otherwise % info.data_type 其它情况
error(['文件中 data type对应的值: ',num2str(dtype),' -程序不支持']);
end
end
function [struc, param] = ParseLine(line, struc)
param='';
eqsn = find(line=='=',1,'first'); % 寻找前(frist)1(n)个个“=”
if ~isempty(eqsn)
param = strtrim(line(1:eqsn-1)); % 删除字符串前后空格
param(strfind(param,' ')) = '_'; % 将文字中间的空格换成"_"
%param = genvarname(param); % 将行拆分为 param
param = matlab.lang.makeValidName(param); % 将行拆分为 param
value = strtrim(line(eqsn+1:end)); % and value
if strcmp(param,upper(param)) % 是不是所有的字母都是大写的...
param = lower(param); % 转换为小写字符串
end
% 将值保存为结构的字段
try
struc.(param) = eval(value); % 执行文本中的 MATLAB 表达式 尝试转换为数字等。
catch ME %#ok<NASGU>
struc.(param) = value;
end
else
struc.CONTENT = line;
end
没有合适的资源?快使用搜索试试~ 我知道了~
利用matlab读取ENVI标准格式的数据
共2个文件
m:2个
5星 · 超过95%的资源 需积分: 5 17 下载量 16 浏览量
2023-03-29
16:07:32
上传
评论 3
收藏 3KB ZIP 举报
温馨提示
本博客主要包含2份代码文件,一份是main文件、一份是read_envihdr文件,这个文件是一个Matlab官网上公开的代码,我在里面详细注释。 % READ_ENVIHDR 读取并返回 ENVI 图像头文件信息. % INFO = READ_ENVIHDR('HDR_FILE') 读取ASCII ENVI生成的图像头文件,并返回参数结构中的所有信息。 % 输出: % * Info - 具有ENVI文件中提供的字段的结构。ENVI标头格式需要以下字段: % * samples - 图像中的样本数(列) % * lines - 图像中的行数(行) % * bands - 图像中的条带数 % * data_type - 存储为1-15范围内的整数的图像的数据类型。 % * interleave - 文件带交错类型; % * byte_order - 字节顺序 % 例子 1: % >> info = read_envihdr('my_envi_image.hdr') 如果有所帮助,请点赞+关注+收藏
资源推荐
资源详情
资源评论
收起资源包目录
read_envihdr.zip (2个子文件)
main.m 380B
read_envihdr.m 7KB
共 2 条
- 1
资源评论
- 张盛锋2023-07-26作者用清晰的语言和详细的步骤,指导了如何使用Matlab进行ENVI数据读取,非常实用。
- 小小二-yan2023-07-26这个文件提供了一个简单而实用的方法,可以让使用者轻松地读取ENVI标准格式的数据。
- daidaiyijiu2023-07-26这篇文章介绍了一种方法,能够很容易地读取ENVI数据,给遥感数据领域的研究者们提供了一种简便的解决方案。
- SLHJ-Translator2023-07-26这篇文章介绍了一个非常有用的工具,对于那些处理遥感数据的人来说简直是福音。
- 一曲歌长安2023-07-26作者清晰地展示了如何使用Matlab来读取ENVI标准格式的数据,非常适合初学者入门使用。
心网千结
- 粉丝: 863
- 资源: 24
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功