高光谱数据多元散射校正(MSC)+ 平滑去噪(Savitzky-Golay)— MATLAB

一、核心思路

  1. 多元散射校正(MSC):消除颗粒大小、散射效应导致的基线漂移 → 每个像素光谱与参考光谱(平均光谱)做线性回归校正。
  2. 平滑去噪(Savitzky-Golay):用局部多项式拟合平滑光谱,抑制随机噪声。

二、代码(主脚本)

2.1 主程序 hyperspectral_msc_smooth.m

matlab 复制代码
%% hyperspectral_msc_smooth.m
% 高光谱数据预处理:多元散射校正 + Savitzky-Golay平滑
clear; clc; close all;

%% ===== 1. 加载/生成高光谱数据 =====
% 假设你已有高光谱数据 cube: [行, 列, 波段]
% 这里生成一个模拟数据(含散射和噪声)
[rows, cols, bands] = deal(100, 100, 200);
cube = simulate_hyperspectral_data(rows, cols, bands);  % 手写模拟函数

fprintf('高光谱数据尺寸: %d × %d × %d\n', rows, cols, bands);

%% ===== 2. 多元散射校正(MSC)=====
fprintf('执行多元散射校正(MSC)...\n');
cube_msc = msc_correction(cube);

%% ===== 3. Savitzky-Golay 平滑去噪 =====
fprintf('执行 Savitzky-Golay 平滑...\n');
window_size = 11;   % 平滑窗口(奇数,建议 5~21)
poly_order = 2;     % 多项式阶数(2或3)
cube_smooth = savitzky_golay_smooth(cube_msc, window_size, poly_order);

%% ===== 4. 结果可视化 =====
visualize_results(cube, cube_msc, cube_smooth, bands);

%% ===== 5. 保存结果 =====
save('hyperspectral_processed.mat', 'cube_msc', 'cube_smooth');
fprintf('处理完成,结果已保存。\n');

三、核心函数

3.1 多元散射校正(MSC)--- 核心算法

matlab 复制代码
function cube_msc = msc_correction(cube)
% 多元散射校正(Multivariate Scattering Correction)
% 输入: cube - [rows, cols, bands]
% 输出: cube_msc - 校正后的数据

[rows, cols, bands] = size(cube);
N = rows * cols;  % 总像素数

% 1. 计算参考光谱(所有像素的平均光谱)
ref_spec = mean(reshape(cube, N, bands), 1);  % 1 × bands

% 2. 对每个像素进行线性回归校正
cube_msc = zeros(size(cube));
for r = 1:rows
    for c = 1:cols
        % 当前像素光谱
        spec = squeeze(cube(r, c, :))';  % bands × 1
        
        % 线性回归: spec = a * ref_spec + b
        X = [ref_spec' ones(bands,1)];   % 设计矩阵
        beta = X \ spec;                  % 最小二乘解 [a; b]
        
        % 校正: spec_msc = (spec - b) / a
        spec_msc = (spec - beta(2)) / beta(1);
        
        cube_msc(r, c, :) = spec_msc';
    end
end
end

3.2 Savitzky-Golay 平滑

matlab 复制代码
function cube_smooth = savitzky_golay_smooth(cube, window, order)
% Savitzky-Golay 平滑滤波
% window: 窗口大小(奇数)
% order: 多项式阶数

[rows, cols, bands] = size(cube);
cube_smooth = zeros(size(cube));

% 1. 生成SG卷积核
kernel = sg_kernel(window, order);  % 手写函数
half_win = floor(window/2);

% 2. 对每个像素的光谱进行平滑
for r = 1:rows
    for c = 1:cols
        spec = squeeze(cube(r, c, :))';  % bands × 1
        
        % 边界处理:镜像填充
        spec_pad = [flip(spec(1:half_win)); spec; flip(spec(end-half_win+1:end))];
        
        % 卷积平滑
        spec_smooth = zeros(bands,1);
        for b = 1:bands
            idx = b + half_win;
            spec_smooth(b) = sum(kernel .* spec_pad(idx-half_win:idx+half_win));
        end
        
        cube_smooth(r, c, :) = spec_smooth';
    end
end
end

function kernel = sg_kernel(window, order)
% 生成Savitzky-Golay卷积核
half_win = floor(window/2);
x = (-half_win:half_win)';
X = zeros(window, order+1);
for i = 0:order
    X(:, i+1) = x.^i;
end
% 最小二乘解: kernel = X * inv(X'X) * [1; 0; ...]
XTX_inv = inv(X' * X);
kernel = X * XTX_inv(:,1);  % 第一列对应平滑
end

3.3 模拟高光谱数据(用于测试)

matlab 复制代码
function cube = simulate_hyperspectral_data(rows, cols, bands)
% 生成含散射和噪声的高光谱数据
cube = zeros(rows, cols, bands);

% 基础光谱(高斯峰)
lambda = linspace(400, 1000, bands);  % 波长
base_spec = 0.5 * exp(-((lambda-600)/100).^2) + ...
            0.3 * exp(-((lambda-750)/80).^2);

% 添加散射效应(不同像素有不同的基线漂移)
for r = 1:rows
    for c = 1:cols
        % 散射参数(模拟颗粒大小差异)
        scatter = 0.2 * randn();  % 随机散射偏移
        spec = base_spec + scatter * linspace(0,1,bands);
        
        % 添加噪声
        spec = spec + 0.02 * randn(size(spec));
        
        cube(r, c, :) = spec;
    end
end
end

3.4 结果可视化

matlab 复制代码
function visualize_results(cube_raw, cube_msc, cube_smooth, bands)
% 可视化校正和平滑效果
figure('Color','w','Position',[100 100 1200 400]);

% 选择中心像素
[r0, c0] = deal(50, 50);
spec_raw = squeeze(cube_raw(r0,c0,:))';
spec_msc = squeeze(cube_msc(r0,c0,:))';
spec_smooth = squeeze(cube_smooth(r0,c0,:))';

lambda = linspace(400, 1000, bands);

subplot(1,3,1);
plot(lambda, spec_raw, 'k-', 'LineWidth',1.5);
title('原始光谱'); xlabel('波长 (nm)'); ylabel('反射率'); grid on;

subplot(1,3,2);
plot(lambda, spec_msc, 'b-', 'LineWidth',1.5);
title('MSC校正后'); xlabel('波长 (nm)'); ylabel('反射率'); grid on;

subplot(1,3,3);
plot(lambda, spec_smooth, 'r-', 'LineWidth',1.5);
title('平滑后'); xlabel('波长 (nm)'); ylabel('反射率'); grid on;

sgtitle('高光谱数据预处理效果对比', 'FontSize',14, 'FontWeight','bold');
end

四、运行说明

  1. 直接运行 :执行 hyperspectral_msc_smooth.m
  2. 替换真实数据 :将 simulate_hyperspectral_data 替换为你的真实高光谱数据加载代码(如 multibandread 读取 ENVI 文件)。
  3. 参数调整
    • window_size:建议 5~21(奇数,越大平滑越强)
    • poly_order:2 或 3(阶数越高保留细节越多,但可能过拟合)

参考代码 可对高光谱数据进行多元散射校正处理,平滑光谱去噪 www.youwenfan.com/contentcsw/81945.html

五、预期效果

处理步骤 效果
原始光谱 含基线漂移、散射噪声、随机噪声
MSC校正 消除基线漂移,光谱形状更一致
SG平滑 抑制随机噪声,光谱更平滑