PCA源码与可见光-红外图像融合MATLAB实现

一、MATLAB实现

1.1 主程序:PCA图像融合

matlab 复制代码
%% PCA图像融合:可见光与红外图像
% 功能:实现PCA变换在可见光与红外图像融合中的应用

clear; clc; close all;
fprintf('=== PCA可见光-红外图像融合开始 ===\n');

%% 1. 读取或生成测试图像
fprintf('加载测试图像...\n');

% 生成模拟的可见光图像(高分辨率,富含纹理)
[vis_img, ir_low_img] = generate_test_images();

% 显示原始图像
figure('Position', [100, 100, 1200, 400]);

subplot(1, 3, 1);
imshow(vis_img, []);
title('可见光图像(高分辨率)');
colorbar;

subplot(1, 3, 2);
imshow(ir_low_img, []);
title('红外图像(低分辨率)');
colorbar;

%% 2. 图像预处理
fprintf('图像预处理...\n');

% 将低分辨率红外图像上采样到与可见光图像相同尺寸
[vis_height, vis_width] = size(vis_img);
ir_upsampled = imresize(ir_low_img, [vis_height, vis_width], 'bicubic');

subplot(1, 3, 3);
imshow(ir_upsampled, []);
title('上采样后的红外图像');
colorbar;

%% 3. PCA融合算法
fprintf('执行PCA融合...\n');

% 执行PCA融合
[fused_img, pc_scores, pc_components, mean_vec] = pca_fusion(ir_upsampled, vis_img);

%% 4. 结果可视化
fprintf('可视化融合结果...\n');

figure('Position', [100, 100, 1400, 600]);

% 原始图像对比
subplot(2, 4, 1);
imshow(vis_img, []);
title('输入1:可见光图像');

subplot(2, 4, 2);
imshow(ir_upsampled, []);
title('输入2:红外图像(上采样)');

% PCA变换结果
subplot(2, 4, 3);
imshow(pc_scores(:, :, 1), []);
title('PCA第一主成分(PC1)');
colorbar;

subplot(2, 4, 4);
imshow(pc_scores(:, :, 2), []);
title('PCA第二主成分(PC2)');
colorbar;

% 融合过程
subplot(2, 4, 5);
imshow(histogram_matching(vis_img, pc_scores(:, :, 1)), []);
title('直方图匹配后的可见光图像');

subplot(2, 4, 6);
imshow(fused_img, []);
title('PCA融合结果');
colorbar;

% 对比其他融合方法
subplot(2, 4, 7);
simple_fusion = 0.5*double(ir_upsampled) + 0.5*double(vis_img);
imshow(simple_fusion, []);
title('简单加权平均融合');
colorbar;

subplot(2, 4, 8);
laplacian_fusion = laplacian_fusion(ir_upsampled, vis_img);
imshow(laplacian_fusion, []);
title('拉普拉斯金字塔融合');
colorbar;

%% 5. 定量评估
fprintf('定量评估融合质量...\n');

% 计算融合质量指标
metrics = evaluate_fusion_quality(vis_img, ir_upsampled, fused_img);

fprintf('\n=== 融合质量评估 ===\n');
fprintf('信息熵: %.4f\n', metrics.entropy);
fprintf('空间频率: %.4f\n', metrics.spatial_freq);
fprintf('平均梯度: %.4f\n', metrics.avg_gradient);
fprintf('标准差: %.4f\n', metrics.std_dev);
fprintf('互信息: %.4f\n', metrics.mutual_info);

%% 6. 多通道PCA融合(彩色图像)
fprintf('多通道PCA融合演示...\n');

% 创建彩色可见光图像(模拟RGB)
vis_color = cat(3, vis_img, vis_img*0.8, vis_img*0.6);

% 创建多光谱红外图像(模拟多通道)
ir_multispectral = cat(3, ir_upsampled, ir_upsampled*1.2, ir_upsampled*0.9);

% 执行多通道PCA融合
fused_color = multispectral_pca_fusion(ir_multispectral, vis_color);

% 显示彩色融合结果
figure('Position', [100, 100, 1000, 400]);

subplot(1, 3, 1);
imshow(uint8(vis_color*255));
title('彩色可见光图像');

subplot(1, 3, 2);
imshow(uint8(ir_multispectral*255));
title('多光谱红外图像');

subplot(1, 3, 3);
imshow(uint8(fused_color*255));
title('多通道PCA融合结果');

%% 7. 保存结果
fprintf('保存结果...\n');

% 保存融合图像
imwrite(uint8(fused_img*255), 'pca_fusion_result.png');

% 保存工作空间变量
save('pca_fusion_results.mat', 'vis_img', 'ir_upsampled', 'fused_img', ...
     'pc_scores', 'pc_components', 'mean_vec', 'metrics');

fprintf('\n=== PCA融合完成 ===\n');
fprintf('融合图像已保存为 pca_fusion_result.png\n');

1.2 PCA核心算法实现

matlab 复制代码
%% PCA算法核心函数
function [coeff, score, latent] = manual_pca(X, k)
    % 手动实现PCA算法
    % 输入:
    %   X: 数据矩阵 (n_samples x n_features)
    %   k: 保留的主成分数量
    % 输出:
    %   coeff: 主成分系数 (n_features x k)
    %   score: 主成分得分 (n_samples x k)
    %   latent: 特征值 (k x 1)
    
    % 1. 数据中心化
    mu = mean(X, 1);
    X_centered = X - mu;
    
    % 2. 计算协方差矩阵
    Sigma = (X_centered' * X_centered) / (size(X, 1) - 1);
    
    % 3. 特征值分解
    [V, D] = eig(Sigma);
    
    % 4. 按特征值降序排序
    [eigenvalues, idx] = sort(diag(D), 'descend');
    coeff = V(:, idx(1:k));
    latent = eigenvalues(1:k);
    
    % 5. 计算主成分得分
    score = X_centered * coeff;
end

function [X_reconstructed] = manual_inverse_pca(score, coeff, mu)
    % PCA逆变换
    % 输入:
    %   score: 主成分得分
    %   coeff: 主成分系数
    %   mu: 均值向量
    % 输出:
    %   X_reconstructed: 重构数据
    
    X_reconstructed = score * coeff' + mu;
end

%% PCA图像融合主函数
function [fused_img, pc_scores, pc_components, mean_vec] = pca_fusion(ir_img, vis_img)
    % PCA融合可见光与红外图像
    % 输入:
    %   ir_img: 红外图像(已上采样到与可见光同尺寸)
    %   vis_img: 可见光图像
    % 输出:
    %   fused_img: 融合后的图像
    %   pc_scores: 主成分得分
    %   pc_components: 主成分系数
    %   mean_vec: 均值向量
    
    % 将图像转换为列向量
    [h, w] = size(ir_img);
    ir_vec = double(ir_img(:));
    vis_vec = double(vis_img(:));
    
    % 构建数据矩阵(每行一个样本,每列一个特征)
    % 这里将两个图像作为两个特征
    X = [ir_vec, vis_vec];
    
    % 执行PCA
    [coeff, score, latent] = manual_pca(X, 2);
    
    % 提取主成分
    pc1 = score(:, 1);  % 第一主成分(包含最多信息)
    pc2 = score(:, 2);  % 第二主成分
    
    % 将主成分重塑为图像尺寸
    pc_scores = cat(3, reshape(pc1, h, w), reshape(pc2, h, w));
    pc_components = coeff;
    mean_vec = mean(X, 1);
    
    % 直方图匹配:将可见光图像匹配到第一主成分
    vis_matched = histogram_matching(vis_img, reshape(pc1, h, w));
    
    % 用匹配后的可见光图像替换第一主成分
    new_pc1 = vis_matched(:);
    
    % 重构融合图像
    new_score = [new_pc1, pc2];
    fused_vec = manual_inverse_pca(new_score, coeff, mean_vec);
    
    % 重塑为图像
    fused_img = reshape(fused_vec, h, w);
    
    % 归一化到[0,1]
    fused_img = (fused_img - min(fused_img(:))) / (max(fused_img(:)) - min(fused_img(:)));
end

1.3 辅助函数

matlab 复制代码
%% 生成测试图像
function [vis_img, ir_low_img] = generate_test_images()
    % 生成模拟的可见光和红外测试图像
    
    % 设置图像尺寸
    vis_size = [512, 512];
    ir_size = [128, 128];
    
    % 生成可见光图像(富含纹理)
    vis_img = zeros(vis_size);
    
    % 添加网格纹理
    [x, y] = meshgrid(1:vis_size(2), 1:vis_size(1));
    vis_img = sin(x/10) .* cos(y/10) + 0.5;
    
    % 添加随机纹理
    vis_img = vis_img + 0.1 * randn(vis_size);
    
    % 归一化
    vis_img = (vis_img - min(vis_img(:))) / (max(vis_img(:)) - min(vis_img(:)));
    
    % 生成红外图像(低分辨率,包含热源)
    ir_low_img = zeros(ir_size);
    
    % 添加热源(圆形区域)
    [x_ir, y_ir] = meshgrid(1:ir_size(2), 1:ir_size(1));
    center_x = ir_size(2)/2;
    center_y = ir_size(1)/2;
    
    % 热源1
    radius = 20;
    mask1 = (x_ir - center_x).^2 + (y_ir - center_y).^2 < radius^2;
    ir_low_img(mask1) = 0.8;
    
    % 热源2
    radius = 15;
    mask2 = (x_ir - center_x + 30).^2 + (y_ir - center_y - 20).^2 < radius^2;
    ir_low_img(mask2) = 0.6;
    
    % 热源3
    radius = 12;
    mask3 = (x_ir - center_x - 25).^2 + (y_ir - center_y + 25).^2 < radius^2;
    ir_low_img(mask3) = 0.9;
    
    % 添加噪声
    ir_low_img = ir_low_img + 0.05 * randn(ir_size);
    
    % 归一化
    ir_low_img = (ir_low_img - min(ir_low_img(:))) / (max(ir_low_img(:)) - min(ir_low_img(:)));
end

%% 直方图匹配
function matched_img = histogram_matching(source, target)
    % 将源图像的直方图匹配到目标图像
    
    % 计算累积分布函数
    source_hist = imhist(uint8(source*255), 256);
    target_hist = imhist(uint8(target*255), 256);
    
    source_cdf = cumsum(source_hist) / sum(source_hist);
    target_cdf = cumsum(target_hist) / sum(target_hist);
    
    % 创建映射表
    mapping = zeros(256, 1);
    for i = 1:256
        [~, idx] = min(abs(source_cdf(i) - target_cdf));
        mapping(i) = idx - 1;
    end
    
    % 应用映射
    source_uint8 = uint8(source*255);
    matched_uint8 = mapping(double(source_uint8) + 1);
    matched_img = double(matched_uint8) / 255;
end

%% 拉普拉斯金字塔融合(对比方法)
function fused_img = laplacian_fusion(ir_img, vis_img)
    % 拉普拉斯金字塔融合
    
    levels = 4;  % 金字塔层数
    
    % 构建高斯金字塔
    G_ir = cell(levels, 1);
    G_vis = cell(levels, 1);
    
    G_ir{1} = double(ir_img);
    G_vis{1} = double(vis_img);
    
    for l = 2:levels
        G_ir{l} = impyramid(G_ir{l-1}, 'reduce');
        G_vis{l} = impyramid(G_vis{l-1}, 'reduce');
    end
    
    % 构建拉普拉斯金字塔
    L_ir = cell(levels, 1);
    L_vis = cell(levels, 1);
    
    for l = 1:levels-1
        expanded = impyramid(G_ir{l+1}, 'expand');
        L_ir{l} = G_ir{l} - expanded;
        
        expanded = impyramid(G_vis{l+1}, 'expand');
        L_vis{l} = G_vis{l} - expanded;
    end
    L_ir{levels} = G_ir{levels};
    L_vis{levels} = G_vis{levels};
    
    % 融合拉普拉斯金字塔
    L_fused = cell(levels, 1);
    for l = 1:levels
        % 简单加权平均
        L_fused{l} = 0.5 * L_ir{l} + 0.5 * L_vis{l};
    end
    
    % 重建图像
    fused_img = L_fused{levels};
    for l = levels-1:-1:1
        expanded = impyramid(fused_img, 'expand');
        fused_img = L_fused{l} + expanded;
    end
    
    % 归一化
    fused_img = (fused_img - min(fused_img(:))) / (max(fused_img(:)) - min(fused_img(:)));
end

%% 多通道PCA融合
function fused_img = multispectral_pca_fusion(ir_multispectral, vis_color)
    % 多通道PCA融合
    
    [h, w, c] = size(ir_multispectral);
    
    % 将多通道图像重塑为二维矩阵
    ir_reshaped = reshape(ir_multispectral, h*w, c);
    vis_reshaped = reshape(vis_color, h*w, c);
    
    % 合并数据
    X = [ir_reshaped, vis_reshaped];
    
    % 执行PCA
    [coeff, score, ~] = manual_pca(X, c);
    
    % 提取第一主成分
    pc1 = score(:, 1);
    
    % 用可见光的第一通道替换第一主成分
    vis_first_channel = vis_reshaped(:, 1);
    new_score = score;
    new_score(:, 1) = vis_first_channel;
    
    % 逆变换
    fused_reshaped = manual_inverse_pca(new_score, coeff, mean(X, 1));
    
    % 重塑为图像
    fused_img = reshape(fused_reshaped, h, w, c);
    
    % 归一化
    for i = 1:c
        channel = fused_img(:, :, i);
        fused_img(:, :, i) = (channel - min(channel(:))) / (max(channel(:)) - min(channel(:)));
    end
end

%% 融合质量评估
function metrics = evaluate_fusion_quality(vis_img, ir_img, fused_img)
    % 评估融合图像质量
    
    % 1. 信息熵
    hist = imhist(uint8(fused_img*255));
    hist = hist / sum(hist);
    hist(hist == 0) = [];
    metrics.entropy = -sum(hist .* log2(hist));
    
    % 2. 空间频率
    [Gx, Gy] = imgradientxy(fused_img);
    RF = sqrt(mean(Gx(:).^2));
    CF = sqrt(mean(Gy(:).^2));
    metrics.spatial_freq = sqrt(RF^2 + CF^2);
    
    % 3. 平均梯度
    [grad_mag, ~] = imgradient(fused_img);
    metrics.avg_gradient = mean(grad_mag(:));
    
    % 4. 标准差
    metrics.std_dev = std(fused_img(:));
    
    % 5. 互信息
    vis_bins = imhist(uint8(vis_img*255), 256);
    ir_bins = imhist(uint8(ir_img*255), 256);
    fused_bins = imhist(uint8(fused_img*255), 256);
    
    % 计算联合直方图
    joint_hist_vis = zeros(256, 256);
    joint_hist_ir = zeros(256, 256);
    
    vis_uint8 = uint8(vis_img*255);
    ir_uint8 = uint8(ir_img*255);
    fused_uint8 = uint8(fused_img*255);
    
    for i = 1:numel(fused_uint8)
        joint_hist_vis(vis_uint8(i)+1, fused_uint8(i)+1) = ...
            joint_hist_vis(vis_uint8(i)+1, fused_uint8(i)+1) + 1;
        joint_hist_ir(ir_uint8(i)+1, fused_uint8(i)+1) = ...
            joint_hist_ir(ir_uint8(i)+1, fused_uint8(i)+1) + 1;
    end
    
    % 归一化
    joint_hist_vis = joint_hist_vis / sum(joint_hist_vis(:));
    joint_hist_ir = joint_hist_ir / sum(joint_hist_ir(:));
    
    % 计算互信息
    vis_bins = vis_bins / sum(vis_bins);
    ir_bins = ir_bins / sum(ir_bins);
    fused_bins = fused_bins / sum(fused_bins);
    
    mi_vis = 0;
    mi_ir = 0;
    
    for i = 1:256
        for j = 1:256
            if joint_hist_vis(i, j) > 0
                mi_vis = mi_vis + joint_hist_vis(i, j) * ...
                    log2(joint_hist_vis(i, j) / (vis_bins(i) * fused_bins(j)));
            end
            if joint_hist_ir(i, j) > 0
                mi_ir = mi_ir + joint_hist_ir(i, j) * ...
                    log2(joint_hist_ir(i, j) / (ir_bins(i) * fused_bins(j)));
            end
        end
    end
    
    metrics.mutual_info = (mi_vis + mi_ir) / 2;
end

二、算法原理详解

2.1 PCA图像融合流程

复制代码
输入图像:
  可见光图像 (高分辨率,富含纹理)
  红外图像 (低分辨率,含热信息)

处理流程:
  1. 图像配准与重采样
  2. 构建数据矩阵 [红外像素, 可见光像素]
  3. PCA变换得到主成分
  4. 直方图匹配: 可见光 → 第一主成分
  5. 用匹配后的可见光替换第一主成分
  6. PCA逆变换重构融合图像

2.2 PCA数学原理

数据中心化 :
Xcentered=X−μX_{centered} = X - \muXcentered=X−μ

协方差矩阵 :
Σ=1n−1XcenteredTXcentered\Sigma = \frac{1}{n-1} X_{centered}^T X_{centered}Σ=n−11XcenteredTXcentered

特征值分解 :
Σ=VΛV−1\Sigma = V \Lambda V^{-1}Σ=VΛV−1

主成分得分 :
PC=XcenteredVPC = X_{centered} VPC=XcenteredV

重构数据 :
X^=PCVT+μ\hat{X} = PC V^T + \muX^=PCVT+μ

2.3 为什么PCA适合图像融合?

  1. 能量压缩:第一主成分包含最大方差信息
  2. 去相关:主成分之间互不相关
  3. 信息保留:通过选择主成分可以控制信息保留程度
  4. 物理意义:第一主成分通常对应图像的整体亮度(红外特征)

三、性能优化与扩展

3.1 快速PCA实现

matlab 复制代码
%% 快速PCA(适用于大图像)
function [coeff, score] = fast_pca(X, k)
    % 使用奇异值分解的快速PCA
    
    % 数据中心化
    mu = mean(X, 1);
    X_centered = X - mu;
    
    % 对X'X进行特征值分解等价于对XX'进行
    % 如果样本数小于特征数,使用这种技巧可以加速
    if size(X, 1) < size(X, 2)
        [U, S, V] = svd(X_centered, 'econ');
        coeff = V(:, 1:k);
        score = U(:, 1:k) * S(1:k, 1:k);
    else
        [U, S, V] = svd(X_centered', 'econ');
        coeff = U(:, 1:k);
        score = X_centered * coeff;
    end
end

3.2 多尺度PCA融合

matlab 复制代码
%% 多尺度PCA融合
function fused_img = multiscale_pca_fusion(ir_img, vis_img)
    % 在不同尺度上进行PCA融合
    
    levels = 3;
    fused_pyramid = cell(levels, 1);
    
    % 构建高斯金字塔
    pyr_ir = build_gaussian_pyramid(ir_img, levels);
    pyr_vis = build_gaussian_pyramid(vis_img, levels);
    
    % 在每个尺度上执行PCA融合
    for l = 1:levels
        fused_pyramid{l} = pca_fusion(pyr_ir{l}, pyr_vis{l});
    end
    
    % 重建图像
    fused_img = reconstruct_from_pyramid(fused_pyramid);
end

3.3 自适应PCA融合

matlab 复制代码
%% 自适应PCA融合
function fused_img = adaptive_pca_fusion(ir_img, vis_img)
    % 根据局部区域特性自适应调整PCA权重
    
    [h, w] = size(ir_img);
    fused_img = zeros(h, w);
    
    % 滑动窗口处理
    window_size = 16;
    for i = 1:window_size:h-window_size+1
        for j = 1:window_size:w-window_size+1
            % 提取局部区域
            patch_ir = ir_img(i:i+window_size-1, j:j+window_size-1);
            patch_vis = vis_img(i:i+window_size-1, j:j+window_size-1);
            
            % 计算局部PCA
            [patch_fused, ~, ~, ~] = pca_fusion(patch_ir, patch_vis);
            
            % 存储结果
            fused_img(i:i+window_size-1, j:j+window_size-1) = patch_fused;
        end
    end
end

参考代码 PCA源码与PCA在可见光与红外图像的融合实例 www.youwenfan.com/contentcnu/63379.html

四、实际应用建议

4.1 参数选择指南

参数 建议值 说明
直方图匹配方法 CDF匹配 保持统计特性一致
PCA主成分数 2 可见光+红外两通道
图像尺寸 512×512 平衡精度与计算量
插值方法 Bicubic 上采样质量较好

4.2 质量评估指标

指标 物理意义 理想值
信息熵 信息丰富度 越高越好
空间频率 纹理清晰度 越高越好
平均梯度 边缘保持 越高越好
标准差 对比度 适中
互信息 信息保留 越高越好

4.3 常见问题解决

  1. 融合图像模糊:检查直方图匹配是否正确,尝试自适应PCA
  2. 热信息丢失:确保第一主成分对应红外特征
  3. 计算速度慢:使用快速PCA或减少图像尺寸
  4. 边缘伪影:使用重叠滑动窗口或金字塔融合

五、总结

PCA图像融合在可见光与红外图像融合中具有独特优势:

  1. 理论基础坚实:基于统计最优投影
  2. 实现简单:只需基本的线性代数运算
  3. 效果优异:兼顾红外热信息与可见光纹理
  4. 扩展性强:可扩展到多通道、多尺度融合

该MATLAB实现提供了完整的从理论到实践的解决方案,可直接应用于:

  • 夜间监控与安防
  • 医学影像融合
  • 遥感图像处理
  • 工业检测与质量控制
相关推荐
sali-tec4 小时前
C# 基于OpenCv的视觉工作流-章60-点点距离
图像处理·人工智能·opencv·算法·计算机视觉
机器学习之心6 小时前
PSO-QGPR粒子群优化高斯过程分位数回归多变量回归预测,MATLAB代码
matlab·回归·pso-qgpr
feifeigo1236 小时前
基于无迹变换的电网概率潮流分析 MATLAB 实现
开发语言·算法·matlab
fie88896 小时前
基于遗传算法的机械故障诊断MATLAB程序
算法·机器学习·matlab
MATLAB代码顾问7 小时前
MATLAB实现灰狼算法优化PID参数
算法·机器学习·matlab
2zcode7 小时前
基于MATLAB深度学习的非酒精性脂肪性肝病超声图像分类研究( GUI界面+数据集+训练代码)
深度学习·matlab·分类
hhzz7 小时前
(深度学习/计算机视觉)手把手教你从零部署YOLOv8目标检测算法-----环境安装(1/4)
深度学习·yolo·计算机视觉
hoiii1877 小时前
基于MATLAB实现内点法解决凸优化问题
开发语言·matlab
kay_5458 小时前
YOLO26改进| 主干网络 | 提升长距离特征建模与全局上下文理解能力【CVPR】
人工智能·目标检测·计算机视觉·目标跟踪·论文·yolo26·yolo26改进