当前位置: 首页 > news >正文

MATLAB读取高光谱图像

一、常见高光谱数据格式

格式扩展名特点常用软件
ENVI格式.hdr+.dat/.raw行业标准格式,头文件+数据文件ENVI, MATLAB
TIFF格式.tif支持多波段,通用性强多数软件
HDF格式.hdf/.h5分层数据结构,适合大数据NASA工具
MAT格式.matMATLAB原生格式,便于处理MATLAB
BIL/BIP/BSQ无扩展名或.bil三种存储顺序遥感软件

二、MATLAB读取代码

2.1 主程序:read_hyperspectral_image.m

%% 高光谱图像读取主程序 % 功能:读取多种格式的高光谱图像数据 clear; clc; close all; %% 1. 文件路径设置 file_path = 'D:\HyperspectralData\'; % 修改为你的文件路径 file_name = 'indian_pines'; % 文件名(不带扩展名) fprintf('=== 高光谱图像读取系统 ===\n'); fprintf('文件路径: %s\n', file_path); fprintf('文件名: %s\n\n', file_name); %% 2. 检测文件格式并读取 [hypercube, metadata] = read_hyperspectral_file(file_path, file_name); %% 3. 显示基本信息 display_hyperspectral_info(hypercube, metadata); %% 4. 可视化高光谱数据 visualize_hyperspectral_data(hypercube, metadata); %% 5. 保存为MATLAB格式(可选) save_hyperspectral_mat(hypercube, metadata, file_path, file_name);

2.2 文件读取核心函数:read_hyperspectral_file.m

function [hypercube, metadata] = read_hyperspectral_file(file_path, file_name) % 读取高光谱图像文件,自动识别格式 fprintf('检测文件格式...\n'); % 检查常见文件格式 formats = { 'ENVI', [file_path file_name '.hdr'], 'read_envi_format' 'TIFF', [file_path file_name '.tif'], 'read_tiff_format' 'HDF', [file_path file_name '.hdf'], 'read_hdf_format' 'HDF5', [file_path file_name '.h5'], 'read_hdf5_format' 'MAT', [file_path file_name '.mat'], 'read_mat_format' 'BIL', [file_path file_name '.bil'], 'read_bil_format' }; % 尝试每种格式 for i = 1:size(formats, 1) format_name = formats{i, 1}; file_full_path = formats{i, 2}; read_function = formats{i, 3}; if exist(file_full_path, 'file') fprintf(' 检测到%s格式: %s\n', format_name, file_full_path); try [hypercube, metadata] = feval(read_function, file_full_path); fprintf(' %s格式读取成功!\n', format_name); return; catch ME fprintf(' %s格式读取失败: %s\n', format_name, ME.message); end end end error('未找到支持的高光谱文件格式!请检查文件路径和格式。'); end

2.3 ENVI格式读取:read_envi_format.m(最常用)

function [hypercube, metadata] = read_envi_format(hdr_file) % 读取ENVI格式高光谱图像 fprintf(' 读取ENVI格式...\n'); % 1. 读取头文件 metadata = read_envi_header(hdr_file); % 2. 确定数据文件路径 [hdr_path, hdr_name, ~] = fileparts(hdr_file); if isfield(metadata, 'file_type') && strcmp(metadata.file_type, 'ENVI Standard') % 查找对应的数据文件 possible_extensions = {'.dat', '.raw', '.img', ''}; data_file = ''; for ext = possible_extensions test_file = fullfile(hdr_path, [hdr_name ext{:}]); if exist(test_file, 'file') data_file = test_file; break; end end if isempty(data_file) error('找不到对应的数据文件!'); end else data_file = fullfile(hdr_path, [hdr_name '.dat']); end fprintf(' 头文件: %s\n', hdr_file); fprintf(' 数据文件: %s\n', data_file); % 3. 根据头文件信息读取数据 % 确定数据类型 dtype_map = containers.Map({'1', '2', '3', '4', '5', '6', '9', '12'}, ... {'uint8', 'int16', 'int32', 'float32', 'float64', 'uint16', 'uint32', 'double'}); if isfield(metadata, 'data_type') precision = dtype_map(char(metadata.data_type)); else precision = 'float32'; % 默认 end % 确定波段顺序 interleave_map = containers.Map({'bsq', 'bil', 'bip'}, {'BandSequential', 'BandInterleavedLine', 'BandInterleavedPixel'}); if isfield(metadata, 'interleave') interleave = interleave_map(char(metadata.interleave)); else interleave = 'BandSequential'; % 默认BSQ end % 4. 使用multibandread读取 rows = str2double(metadata.lines); cols = str2double(metadata.samples); bands = str2double(metadata.bands); fprintf(' 图像尺寸: %d × %d × %d\n', rows, cols, bands); fprintf(' 数据类型: %s\n', precision); fprintf(' 存储顺序: %s\n', interleave); % 读取数据 hypercube = multibandread(data_file, [rows, cols, bands], precision, 0, interleave, 'ieee-le'); % 5. 处理字节顺序 if isfield(metadata, 'byte_order') && strcmp(metadata.byte_order, '1') hypercube = swapbytes(hypercube); end % 6. 添加元数据 metadata.rows = rows; metadata.cols = cols; metadata.bands = bands; metadata.precision = precision; metadata.interleave = interleave; fprintf(' ENVI数据读取完成!\n'); end function metadata = read_envi_header(hdr_file) % 读取ENVI头文件 metadata = struct(); % 读取头文件内容 fid = fopen(hdr_file, 'r'); if fid == -1 error('无法打开头文件: %s', hdr_file); end header_lines = textscan(fid, '%s', 'Delimiter', '\n'); fclose(fid); % 解析头文件 for i = 1:length(header_lines{1}) line = strtrim(header_lines{1}{i}); if isempty(line) || startsWith(line, ';') continue; end % 分割键值对 eq_idx = strfind(line, '='); if ~isempty(eq_idx) key = strtrim(line(1:eq_idx(1)-1)); value = strtrim(line(eq_idx(1)+1:end)); % 移除引号 value = strrep(value, '"', ''); value = strrep(value, '''', ''); % 存储到元数据 metadata.(matlab.lang.makeValidName(lower(key))) = value; end end end

2.4 TIFF格式读取:read_tiff_format.m

function [hypercube, metadata] = read_tiff_format(tiff_file) % 读取TIFF格式高光谱图像 fprintf(' 读取TIFF格式...\n'); % 使用MATLAB内置函数读取 info = imfinfo(tiff_file); % 获取图像信息 metadata = struct(); metadata.format = 'TIFF'; metadata.rows = info.Height; metadata.cols = info.Width; metadata.bands = info.SamplesPerPixel; metadata.precision = info.BitDepth; metadata.photometric = info.PhotometricInterpretation; fprintf(' 图像尺寸: %d × %d × %d\n', metadata.rows, metadata.cols, metadata.bands); fprintf(' 位深度: %d bits\n', metadata.precision); % 读取数据 if metadata.bands == 1 % 单波段图像 hypercube = imread(tiff_file); hypercube = reshape(hypercube, [metadata.rows, metadata.cols, 1]); else % 多波段图像 hypercube = zeros(metadata.rows, metadata.cols, metadata.bands, 'uint16'); for band = 1:metadata.bands [~, map] = imread(tiff_file, band); if isempty(map) hypercube(:,:,band) = imread(tiff_file, band); else % 有颜色映射的情况 hypercube(:,:,band) = ind2gray(imread(tiff_file, band), map); end end end % 转换为double类型以便处理 hypercube = double(hypercube); fprintf(' TIFF数据读取完成!\n'); end

2.5 HDF格式读取:read_hdf_format.m

function [hypercube, metadata] = read_hdf_format(hdf_file) % 读取HDF格式高光谱图像(如AVIRIS数据) fprintf(' 读取HDF格式...\n'); % 检查HDF工具箱是否可用 if ~license('test', 'hdf_toolbox') error('需要HDF工具箱来读取HDF文件!'); end % 打开HDF文件 file_id = hdfopen(hdf_file, 'rdonly'); if file_id == -1 error('无法打开HDF文件: %s', hdf_file); end try % 获取文件信息 info = hdfinfo(hdf_file); metadata = struct(); metadata.format = 'HDF'; % 查找高光谱数据集 dataset_name = ''; if isfield(info, 'SDS') % 科学数据集 sds_info = info.SDS; for i = 1:length(sds_info) if sds_info(i).Rank == 3 dataset_name = sds_info(i).Name; break; end end end if isempty(dataset_name) error('在HDF文件中未找到3D高光谱数据集!'); end % 读取数据集 sds_id = hdfsd('select', file_id, dataset_name); [hypercube, status] = hdfsd('readdata', sds_id, [0 0 0], [info.SDS(1).Dims(1).Count info.SDS(1).Dims(2).Count info.SDS(1).Dims(3).Count], [1 1 1]); hdfsd('endaccess', sds_id); % 获取元数据 metadata.rows = size(hypercube, 1); metadata.cols = size(hypercube, 2); metadata.bands = size(hypercube, 3); metadata.dataset_name = dataset_name; fprintf(' 数据集: %s\n', dataset_name); fprintf(' 图像尺寸: %d × %d × %d\n', metadata.rows, metadata.cols, metadata.bands); catch ME error('HDF读取错误: %s', ME.message); finally hdfclose(file_id); end fprintf(' HDF数据读取完成!\n'); end

2.6 其他格式读取函数

function [hypercube, metadata] = read_hdf5_format(h5_file) % 读取HDF5格式 fprintf(' 读取HDF5格式...\n'); % 列出所有数据集 info = h5info(h5_file); % 查找3D数据集 dataset_name = ''; for i = 1:length(info.Datasets) if length(info.Datasets(i).Dimensions) == 3 dataset_name = info.Datasets(i).Name; break; end end if isempty(dataset_name) error('未找到3D数据集!'); end % 读取数据 hypercube = h5read(h5_file, ['/' dataset_name]); % 获取元数据 metadata = struct(); metadata.format = 'HDF5'; metadata.rows = size(hypercube, 1); metadata.cols = size(hypercube, 2); metadata.bands = size(hypercube, 3); metadata.dataset_name = dataset_name; fprintf(' HDF5数据读取完成!\n'); end function [hypercube, metadata] = read_mat_format(mat_file) % 读取MATLAB格式 fprintf(' 读取MAT格式...\n'); data = load(mat_file); % 查找高光谱数据变量 vars = fieldnames(data); hypercube = []; for i = 1:length(vars) var_data = data.(vars{i}); if ndims(var_data) == 3 && size(var_data, 3) > 3 hypercube = double(var_data); metadata = struct(); metadata.format = 'MAT'; metadata.rows = size(hypercube, 1); metadata.cols = size(hypercube, 2); metadata.bands = size(hypercube, 3); metadata.variable_name = vars{i}; break; end end if isempty(hypercube) error('MAT文件中未找到高光谱数据!'); end fprintf(' MAT数据读取完成!\n'); end function [hypercube, metadata] = read_bil_format(bil_file) % 读取BIL格式 fprintf(' 读取BIL格式...\n'); % 通常需要对应的头文件 [bil_path, bil_name, ~] = fileparts(bil_file); hdr_file = fullfile(bil_path, [bil_name '.hdr']); if exist(hdr_file, 'file') % 使用ENVI读取器 [hypercube, metadata] = read_envi_format(hdr_file); else error('找不到BIL文件的头文件!'); end end

2.7 信息显示函数:display_hyperspectral_info.m

function display_hyperspectral_info(hypercube, metadata) % 显示高光谱图像基本信息 fprintf('\n=== 高光谱图像信息 ===\n'); % 基本尺寸信息 fprintf('图像尺寸:\n'); fprintf(' 行数: %d\n', metadata.rows); fprintf(' 列数: %d\n', metadata.cols); fprintf(' 波段数: %d\n', metadata.bands); fprintf(' 总像素数: %d\n', metadata.rows * metadata.cols); fprintf(' 数据大小: %.2f MB\n', numel(hypercube) * 8 / 1024 / 1024); % 数据范围 fprintf('\n数据范围:\n'); fprintf(' 最小值: %.4f\n', min(hypercube(:))); fprintf(' 最大值: %.4f\n', max(hypercube(:))); fprintf(' 平均值: %.4f\n', mean(hypercube(:))); fprintf(' 标准差: %.4f\n', std(hypercube(:))); % 格式信息 fprintf('\n格式信息:\n'); fprintf(' 文件格式: %s\n', metadata.format); if isfield(metadata, 'precision') fprintf(' 数据类型: %s\n', metadata.precision); end if isfield(metadata, 'interleave') fprintf(' 存储顺序: %s\n', metadata.interleave); end % 波长信息(如果有) if isfield(metadata, 'wavelength') wavelengths = str2num(metadata.wavelength); if ~isempty(wavelengths) fprintf('\n波长信息:\n'); fprintf(' 波长范围: %.2f - %.2f nm\n', min(wavelengths), max(wavelengths)); fprintf(' 光谱分辨率: %.2f nm\n', mean(diff(wavelengths))); end end % 空间分辨率 if isfield(metadata, 'pixel_size') fprintf(' 空间分辨率: %s\n', metadata.pixel_size); end end

2.8 数据可视化:visualize_hyperspectral_data.m

function visualize_hyperspectral_data(hypercube, metadata) % 可视化高光谱数据 figure('Name', '高光谱图像可视化', 'Color', 'white', 'Position', [100, 100, 1400, 800]); % 1. RGB合成图(假彩色) subplot(2,3,1); rgb_image = create_rgb_composite(hypercube, metadata); imshow(rgb_image); title('RGB假彩色合成'); colorbar; % 2. 单波段显示 subplot(2,3,2); band_idx = round(metadata.bands/2); % 中间波段 band_image = hypercube(:,:,band_idx); imagesc(band_image); colormap(gray); colorbar; title(sprintf('波段 %d', band_idx)); axis image; % 3. 光谱曲线 subplot(2,3,3); [rows, cols, bands] = size(hypercube); center_pixel = [round(rows/2), round(cols/2)]; spectrum = squeeze(hypercube(center_pixel(1), center_pixel(2), :)); % 获取波长信息 if isfield(metadata, 'wavelength') wavelengths = str2num(metadata.wavelength); plot(wavelengths, spectrum, 'b-', 'LineWidth', 2); xlabel('波长 (nm)'); else plot(1:bands, spectrum, 'b-', 'LineWidth', 2); xlabel('波段编号'); end ylabel('反射率/辐射值'); title(sprintf('像素(%d,%d)光谱曲线', center_pixel(1), center_pixel(2))); grid on; % 4. 波段统计直方图 subplot(2,3,4); band_for_hist = hypercube(:,:,band_idx); histogram(band_for_hist(:), 100, 'FaceColor', 'cyan', 'EdgeColor', 'black'); xlabel('像素值'); ylabel('频数'); title(sprintf('波段 %d 直方图', band_idx)); grid on; % 5. 3D数据立方体切片 subplot(2,3,5); slice_idx = round(bands/3); slice_image = hypercube(:,:,slice_idx); surf(slice_image); shading interp; colormap jet; colorbar; title(sprintf('波段 %d 3D视图', slice_idx)); view(45, 45); % 6. 波段相关性矩阵 subplot(2,3,6); % 随机选择几个波段计算相关性 n_sample_bands = min(10, bands); sample_bands = round(linspace(1, bands, n_sample_bands)); correlation_matrix = zeros(n_sample_bands, n_sample_bands); for i = 1:n_sample_bands for j = 1:n_sample_bands band_i = hypercube(:,:,sample_bands(i)); band_j = hypercube(:,:,sample_bands(j)); correlation_matrix(i,j) = corr2(band_i, band_j); end end imagesc(correlation_matrix); colormap hot; colorbar; set(gca, 'XTick', 1:n_sample_bands, 'XTickLabel', sample_bands); set(gca, 'YTick', 1:n_sample_bands, 'YTickLabel', sample_bands); xlabel('波段编号'); ylabel('波段编号'); title('波段相关性矩阵'); end function rgb_image = create_rgb_composite(hypercube, metadata) % 创建RGB假彩色合成 [rows, cols, bands] = size(hypercube); rgb_image = zeros(rows, cols, 3); % 选择三个波段作为RGB if bands >= 3 % 简单选择:近红外、红光、绿光 nir_band = round(bands * 0.7); % 近红外波段 red_band = round(bands * 0.5); % 红光波段 green_band = round(bands * 0.3); % 绿光波段 rgb_image(:,:,1) = hypercube(:,:,nir_band); % R通道 rgb_image(:,:,2) = hypercube(:,:,red_band); % G通道 rgb_image(:,:,3) = hypercube(:,:,green_band); % B通道 else % 单波段复制为RGB rgb_image(:,:,1) = hypercube(:,:,1); rgb_image(:,:,2) = hypercube(:,:,1); rgb_image(:,:,3) = hypercube(:,:,1); end % 归一化到0-1 for i = 1:3 band_data = rgb_image(:,:,i); min_val = min(band_data(:)); max_val = max(band_data(:)); if max_val > min_val rgb_image(:,:,i) = (band_data - min_val) / (max_val - min_val); end end end

2.9 保存为MAT格式:save_hyperspectral_mat.m

function save_hyperspectral_mat(hypercube, metadata, file_path, file_name) % 保存为高光谱MAT格式 % 询问是否保存 save_option = questdlg('是否保存为高光谱MAT格式?', '保存选项', '是', '否', '是'); if strcmp(save_option, '是') mat_file = fullfile(file_path, [file_name '_hyperspectral.mat']); % 保存数据 save(mat_file, 'hypercube', 'metadata', '-v7.3'); fprintf('\n高光谱数据已保存为: %s\n', mat_file); fprintf('文件大小: %.2f MB\n', dir(mat_file).bytes / 1024 / 1024); end end

参考代码 读取高光谱图像www.youwenfan.com/contentcsu/60174.html

三、实用工具函数

3.1 高光谱数据预处理

function preprocessed_cube = preprocess_hyperspectral(hypercube, metadata) % 高光谱数据预处理 fprintf('高光谱数据预处理...\n'); % 1. 去噪 fprintf(' 1. 去噪处理...\n'); preprocessed_cube = denoise_hyperspectral(hypercube); % 2. 辐射校正(如果有暗电流) fprintf(' 2. 辐射校正...\n'); preprocessed_cube = radiance_calibration(preprocessed_cube, metadata); % 3. 大气校正 fprintf(' 3. 大气校正...\n'); preprocessed_cube = atmospheric_correction(preprocessed_cube, metadata); % 4. 几何校正 fprintf(' 4. 几何校正...\n'); preprocessed_cube = geometric_correction(preprocessed_cube, metadata); fprintf('预处理完成!\n'); end function denoised_cube = denoise_hyperspectral(hypercube) % 高光谱去噪(主成分分析) [rows, cols, bands] = size(hypercube); % 重塑为2D矩阵 data_2d = reshape(hypercube, rows*cols, bands); % PCA去噪 [coeff, score, latent] = pca(data_2d); % 保留前95%的能量 cum_var = cumsum(latent) / sum(latent); n_components = find(cum_var >= 0.95, 1); % 重建 denoised_2d = score(:, 1:n_components) * coeff(:, 1:n_components)'; denoised_cube = reshape(denoised_2d, rows, cols, bands); end

3.2 批量读取工具

function batch_read_hyperspectral(folder_path, output_folder) % 批量读取文件夹中所有高光谱文件 fprintf('批量读取高光谱数据...\n'); fprintf('输入文件夹: %s\n', folder_path); fprintf('输出文件夹: %s\n', output_folder); % 获取所有文件 files = dir(fullfile(folder_path, '*.hdr')); if isempty(files) error('文件夹中没有找到.hdr文件!'); end % 创建输出文件夹 if ~exist(output_folder, 'dir') mkdir(output_folder); end % 逐个读取 for i = 1:length(files) fprintf('\n处理文件 %d/%d: %s\n', i, length(files), files(i).name); [hypercube, metadata] = read_envi_format(fullfile(folder_path, files(i).name)); % 保存为MAT格式 mat_file = fullfile(output_folder, [files(i).name(1:end-4) '_processed.mat']); save(mat_file, 'hypercube', 'metadata', '-v7.3'); fprintf(' 已保存: %s\n', mat_file); end fprintf('\n批量处理完成!共处理 %d 个文件。\n', length(files)); end
http://www.jsqmd.com/news/773945/

相关文章:

  • C++BFS广度优先搜索全解
  • MetaGPT 论文精读:ICLR 2024 Oral,角色化流水线式多Agent协作
  • 不花一分钱,年省200块18小时,2026年ipad录音转文字高ROI工具冷静评测
  • 企业布局 GEO 项目的 5 大优势|抢占 AI 流量入口,构建长效增长壁垒
  • Ubuntu 22.04 在 CloudCone 上安装 Docker 报错 gpg 密钥失效怎么办?
  • AI代理氛围感设计:从情感化交互到工程化实现
  • CodeSelect:AI编程助手专用代码分享工具,智能分析依赖关系
  • 你相信光吗?| Samtec助力AI/ML系统拓扑中的光连接
  • AI智能体执行引擎OpenClaw-Worker:从原理到实战部署
  • 【仅剩47席】SITS2026认证讲师私藏:AISMM评估模拟打分沙盘(含真实金融/医疗行业脱敏案例)
  • 观察不同模型在 Taotoken 平台上的实际调用响应速度
  • BepInEx终极指南:从零开始掌握游戏插件框架的完整秘籍
  • Prompt Poet:用结构化模板重构LLM提示词工程,告别字符串拼接
  • 甄别二手办公家具品质有哪些实用方法?
  • MCPJam Inspector:全栈MCP开发者的调试、评估与协作平台
  • 企业知识竞赛系统选型避坑指南
  • 基于TinyGo的ESP32 Go语言服务器开发:物联网边缘计算实践
  • wordpress 插件 Converter for Media 如何使用
  • 基于agentsrc-py框架的AI智能体开发:从原理到工程实践
  • Docker容器化入门:从核心概念到实战部署全解析
  • 长期运行的服务接入Taotoken后观察到的API可用性与容灾体验
  • 优势明显:电视浏览器相比专用APP的优势
  • WIN10系统介绍
  • 山东广电浪潮盒子刷机避坑指南:Hi3798MV310+ RTL8822BS 型号区分与WiFi功能恢复
  • ComfyUI-Impact-Pack技术深度解析:模块化图像增强与工作流自动化
  • AI开发环境标准化:ai-setup框架解决CUDA与Python依赖冲突
  • Eagle 2.5:长上下文视觉语言模型的数据策略与工程优化解析
  • 将hermes agent工具链与taotoken对接的配置要点详解
  • Anime4K终极指南:如何让动画视频实时高清化的完整教程
  • GetQzonehistory:如何一键永久备份你的QQ空间青春记忆