MATLAB小波变换图像融合

如何使用小波变换进行图像融合。

matlab 复制代码
classdef WaveletImageFusion
    % 小波变换图像融合类
    % 支持多种小波基函数和融合策略
    
    properties
        waveletName = 'db4';      % 默认小波基函数
        decompositionLevel = 2;   % 默认分解层数
        fusionRule = 'max';       % 默认融合规则
        borderExtension = 'sym';  % 边界扩展模式
        originalImages = {};      % 存储原始图像
        fusedImage = [];          % 融合后的图像
        coeffs = {};              % 存储小波系数
    end
    
    methods
        function obj = WaveletImageFusion(waveletName, level)
            % 构造函数
            % 输入: 
            %   waveletName - 小波基函数名称 (如 'db4', 'haar', 'sym4')
            %   level - 小波分解层数
            if nargin > 0
                obj.waveletName = waveletName;
            end
            if nargin > 1
                obj.decompositionLevel = level;
            end
        end
        
        function obj = setFusionRule(obj, rule)
            % 设置融合规则
            % 可选: 'max', 'min', 'mean', 'energy', 'selective'
            validRules = {'max', 'min', 'mean', 'energy', 'selective'};
            if any(strcmpi(rule, validRules))
                obj.fusionRule = rule;
            else
                error('无效融合规则。请选择: max, min, mean, energy, selective');
            end
        end
        
        function obj = loadImages(obj, img1, img2)
            % 加载两幅待融合图像
            % 输入: 
            %   img1, img2 - 图像矩阵 (灰度或RGB)
            if size(img1) ~= size(img2)
                error('输入图像尺寸必须相同');
            end
            obj.originalImages{1} = im2double(img1);
            obj.originalImages{2} = im2double(img2);
        end
        
        function obj = performWaveletDecomposition(obj)
            % 执行小波分解
            if isempty(obj.originalImages)
                error('请先加载图像');
            end
            
            img1 = obj.originalImages{1};
            img2 = obj.originalImages{2};
            
            % 处理彩色图像
            if ndims(img1) == 3
                [cA1, cH1, cV1, cD1] = deal(cell(1,3));
                [cA2, cH2, cV2, cD2] = deal(cell(1,3));
                
                for ch = 1:3
                    [cA1{ch}, cH1{ch}, cV1{ch}, cD1{ch}] = ...
                        dwt2(obj.originalImages{1}(:,:,ch), obj.waveletName, obj.borderExtension);
                    
                    [cA2{ch}, cH2{ch}, cV2{ch}, cD2{ch}] = ...
                        dwt2(obj.originalImages{2}(:,:,ch), obj.waveletName, obj.borderExtension);
                end
                obj.coeffs = {cA1, cH1, cV1, cD1, cA2, cH2, cV2, cD2};
            else
                % 处理灰度图像
                [cA1, cH1, cV1, cD1] = dwt2(obj.originalImages{1}, obj.waveletName, obj.borderExtension);
                [cA2, cH2, cV2, cD2] = dwt2(obj.originalImages{2}, obj.waveletName, obj.borderExtension);
                obj.coeffs = {cA1, cH1, cV1, cD1, cA2, cH2, cV2, cD2};
            end
        end
        
        function obj = fuseCoefficients(obj)
            % 根据融合规则合并小波系数
            if isempty(obj.coeffs)
                error('请先执行小波分解');
            end
            
            [cA1, cH1, cV1, cD1, cA2, cH2, cV2, cD2] = deal(obj.coeffs{:});
            
            % 处理彩色图像
            if iscell(cA1)
                cAf = cell(1,3); cHf = cell(1,3); cVf = cell(1,3); cDf = cell(1,3);
                
                for ch = 1:3
                    [cAf{ch}, cHf{ch}, cVf{ch}, cDf{ch}] = ...
                        obj.fuseChannelCoeffs(cA1{ch}, cH1{ch}, cV1{ch}, cD1{ch}, ...
                                             cA2{ch}, cH2{ch}, cV2{ch}, cD2{ch});
                end
                obj.coeffsFused = {cAf, cHf, cVf, cDf};
            else
                % 处理灰度图像
                [cAf, cHf, cVf, cDf] = ...
                    obj.fuseChannelCoeffs(cA1, cH1, cV1, cD1, cA2, cH2, cV2, cD2);
                obj.coeffsFused = {cAf, cHf, cVf, cDf};
            end
        end
        
        function [cAf, cHf, cVf, cDf] = fuseChannelCoeffs(obj, cA1, cH1, cV1, cD1, cA2, cH2, cV2, cD2)
            % 融合单个通道的系数
            switch lower(obj.fusionRule)
                case 'max'
                    % 取绝对值最大的系数
                    cAf = max(abs(cA1), abs(cA2)) .* sign((abs(cA1) + abs(cA2))/2);
                    cHf = max(abs(cH1), abs(cH2)) .* sign((abs(cH1) + abs(cH2))/2);
                    cVf = max(abs(cV1), abs(cV2)) .* sign((abs(cV1) + abs(cV2))/2);
                    cDf = max(abs(cD1), abs(cD2)) .* sign((abs(cD1) + abs(cD2))/2);
                    
                case 'min'
                    % 取绝对值最小的系数
                    cAf = min(abs(cA1), abs(cA2)) .* sign((abs(cA1) + abs(cA2))/2);
                    cHf = min(abs(cH1), abs(cH2)) .* sign((abs(cH1) + abs(cH2))/2);
                    cVf = min(abs(cV1), abs(cV2)) .* sign((abs(cV1) + abs(cV2))/2);
                    cDf = min(abs(cD1), abs(cD2)) .* sign((abs(cD1) + abs(cD2))/2);
                    
                case 'mean'
                    % 取平均值
                    cAf = (cA1 + cA2) / 2;
                    cHf = (cH1 + cH2) / 2;
                    cVf = (cV1 + cV2) / 2;
                    cDf = (cD1 + cD2) / 2;
                    
                case 'energy'
                    % 基于能量的融合
                    energy1 = (cA1.^2 + cH1.^2 + cV1.^2 + cD1.^2);
                    energy2 = (cA2.^2 + cH2.^2 + cV2.^2 + cD2.^2);
                    mask = energy1 >= energy2;
                    
                    cAf = mask .* cA1 + (~mask) .* cA2;
                    cHf = mask .* cH1 + (~mask) .* cH2;
                    cVf = mask .* cV1 + (~mask) .* cV2;
                    cDf = mask .* cD1 + (~mask) .* cD2;
                    
                case 'selective'
                    % 选择性融合:低频平均,高频取大
                    cAf = (cA1 + cA2) / 2;
                    cHf = max(abs(cH1), abs(cH2)) .* sign((abs(cH1) + abs(cH2))/2);
                    cVf = max(abs(cV1), abs(cV2)) .* sign((abs(cV1) + abs(cV2))/2);
                    cDf = max(abs(cD1), abs(cD2)) .* sign((abs(cD1) + abs(cD2))/2);
                    
                otherwise
                    error('未知融合规则: %s', obj.fusionRule);
            end
        end
        
        function obj = performInverseTransform(obj)
            % 执行小波逆变换重建图像
            if isempty(obj.coeffsFused)
                error('请先融合系数');
            end
            
            [cAf, cHf, cVf, cDf] = deal(obj.coeffsFused{:});
            
            % 处理彩色图像
            if iscell(cAf)
                fusedImg = zeros(size(obj.originalImages{1}));
                
                for ch = 1:3
                    channelFused = idwt2(cAf{ch}, cHf{ch}, cVf{ch}, cDf{ch}, ...
                                        obj.waveletName, obj.borderExtension);
                    % 裁剪到原始尺寸
                    [origH, origW, ~] = size(obj.originalImages{1});
                    channelFused = channelFused(1:origH, 1:origW);
                    fusedImg(:,:,ch) = channelFused;
                end
            else
                % 处理灰度图像
                fusedImg = idwt2(cAf, cHf, cVf, cDf, obj.waveletName, obj.borderExtension);
                % 裁剪到原始尺寸
                [origH, origW] = size(obj.originalImages{1});
                fusedImg = fusedImg(1:origH, 1:origW);
            end
            
            % 确保值在[0,1]范围内
            obj.fusedImage = max(0, min(1, fusedImg));
        end
        
        function displayResults(obj)
            % 显示融合结果
            if isempty(obj.fusedImage)
                error('请先执行融合过程');
            end
            
            figure('Name', '小波图像融合结果', 'NumberTitle', 'off', 'Position', [100, 100, 1200, 500]);
            
            % 显示原始图像
            for i = 1:2
                subplot(1,3,i);
                if ndims(obj.originalImages{1}) == 3
                    imshow(obj.originalImages{i});
                else
                    imshow(obj.originalImages{i}, []);
                end
                title(sprintf('输入图像 %d', i));
            end
            
            % 显示融合结果
            subplot(1,3,3);
            if ndims(obj.fusedImage) == 3
                imshow(obj.fusedImage);
            else
                imshow(obj.fusedImage, []);
            end
            title(sprintf('融合结果 (%s, %s, L=%d)', ...
                obj.waveletName, obj.fusionRule, obj.decompositionLevel));
        end
        
        function displayWaveletDetails(obj)
            % 显示小波分解细节
            if isempty(obj.coeffs)
                error('请先执行小波分解');
            end
            
            [cA1, cH1, cV1, cD1, cA2, cH2, cV2, cD2] = deal(obj.coeffs{:});
            
            % 处理彩色图像
            if iscell(cA1)
                ch = 1; % 只显示第一个通道
                cA1 = cA1{ch}; cH1 = cH1{ch}; cV1 = cV1{ch}; cD1 = cD1{ch};
                cA2 = cA2{ch}; cH2 = cH2{ch}; cV2 = cV2{ch}; cD2 = cD2{ch};
            end
            
            figure('Name', '小波分解细节', 'NumberTitle', 'off', 'Position', [200, 200, 1000, 800]);
            
            % 显示第一幅图像的小波系数
            subplot(2,4,1); imshow(cA1, []); title('图像1 - 低频 (LL)');
            subplot(2,4,2); imshow(cH1, []); title('图像1 - 水平 (LH)');
            subplot(2,4,3); imshow(cV1, []); title('图像1 - 垂直 (HL)');
            subplot(2,4,4); imshow(cD1, []); title('图像1 - 对角 (HH)');
            
            % 显示第二幅图像的小波系数
            subplot(2,4,5); imshow(cA2, []); title('图像2 - 低频 (LL)');
            subplot(2,4,6); imshow(cH2, []); title('图像2 - 水平 (LH)');
            subplot(2,4,7); imshow(cV2, []); title('图像2 - 垂直 (HL)');
            subplot(2,4,8); imshow(cD2, []); title('图像2 - 对角 (HH)');
        end
        
        function displayFusedCoefficients(obj)
            % 显示融合后的小波系数
            if isempty(obj.coeffsFused)
                error('请先融合系数');
            end
            
            [cAf, cHf, cVf, cDf] = deal(obj.coeffsFused{:});
            
            % 处理彩色图像
            if iscell(cAf)
                ch = 1; % 只显示第一个通道
                cAf = cAf{ch}; cHf = cHf{ch}; cVf = cVf{ch}; cDf = cDf{ch};
            end
            
            figure('Name', '融合后的小波系数', 'NumberTitle', 'off', 'Position', [300, 300, 800, 600]);
            
            subplot(2,2,1); imshow(cAf, []); title('融合低频 (LL)');
            subplot(2,2,2); imshow(cHf, []); title('融合水平 (LH)');
            subplot(2,2,3); imshow(cVf, []); title('融合垂直 (HL)');
            subplot(2,2,4); imshow(cDf, []); title('融合对角 (HH)');
        end
        
        function evaluateFusion(obj)
            % 评估融合质量
            if isempty(obj.fusedImage)
                error('请先执行融合过程');
            end
            
            img1 = obj.originalImages{1};
            img2 = obj.originalImages{2};
            fused = obj.fusedImage;
            
            % 计算均方误差
            mse1 = immse(fused, img1);
            mse2 = immse(fused, img2);
            
            % 计算峰值信噪比
            psnr1 = psnr(fused, img1);
            psnr2 = psnr(fused, img2);
            
            % 计算结构相似性
            ssim1 = ssim(fused, img1);
            ssim2 = ssim(fused, img2);
            
            % 计算信息熵
            entropy1 = entropy(img1);
            entropy2 = entropy(img2);
            entropyFused = entropy(fused);
            
            % 显示评估结果
            fprintf('\n===== 融合质量评估 =====\n');
            fprintf('小波基: %s, 分解层数: %d, 融合规则: %s\n', ...
                obj.waveletName, obj.decompositionLevel, obj.fusionRule);
            fprintf('---------------------------------\n');
            fprintf('图像1 -> 融合图像:\n');
            fprintf('  MSE: %.4f, PSNR: %.2f dB, SSIM: %.4f\n', mse1, psnr1, ssim1);
            fprintf('图像2 -> 融合图像:\n');
            fprintf('  MSE: %.4f, PSNR: %.2f dB, SSIM: %.4f\n', mse2, psnr2, ssim2);
            fprintf('---------------------------------\n');
            fprintf('信息熵:\n');
            fprintf('  图像1: %.4f, 图像2: %.4f, 融合图像: %.4f\n', ...
                entropy1, entropy2, entropyFused);
            fprintf('=================================\n');
        end
        
        function runDemo()
            % 运行演示
            % 创建示例图像
            [x, y] = meshgrid(linspace(-2, 2, 256), linspace(-2, 2, 256));
            img1 = sin(2*pi*(x.^2 + y.^2)) .* exp(-(x.^2 + y.^2)/2);
            img2 = peaks(256);
            
            % 归一化到[0,1]
            img1 = (img1 - min(img1(:))) / (max(img1(:)) - min(img1(:)));
            img2 = (img2 - min(img2(:))) / (max(img2(:)) - min(img2(:)));
            
            % 创建融合器
            fusioner = WaveletImageFusion('db4', 2);
            fusioner = fusioner.setFusionRule('max');
            fusioner = fusioner.loadImages(img1, img2);
            
            % 执行融合
            fusioner = fusioner.performWaveletDecomposition();
            fusioner = fusioner.fuseCoefficients();
            fusioner = fusioner.performInverseTransform();
            
            % 显示结果
            fusioner.displayResults();
            fusioner.displayWaveletDetails();
            fusioner.displayFusedCoefficients();
            fusioner.evaluateFusion();
            
            % 彩色图像融合演示
            colorImg1 = imread('peppers.png');
            colorImg2 = imread('onion.png');
            
            % 调整尺寸相同
            minSize = min(size(colorImg1,1), size(colorImg2,1));
            colorImg1 = imresize(colorImg1, [minSize, min(minSize, size(colorImg1,2))]);
            colorImg2 = imresize(colorImg2, [minSize, min(minSize, size(colorImg2,2))]);
            
            % 创建融合器
            colorFusioner = WaveletImageFusion('coif2', 3);
            colorFusioner = colorFusioner.setFusionRule('selective');
            colorFusioner = colorFusioner.loadImages(rgb2gray(colorImg1), rgb2gray(colorImg2));
            
            % 执行融合
            colorFusioner = colorFusioner.performWaveletDecomposition();
            colorFusioner = colorFusioner.fuseCoefficients();
            colorFusioner = colorFusioner.performInverseTransform();
            
            % 显示结果
            figure('Name', '彩色图像融合演示', 'NumberTitle', 'off', 'Position', [100, 100, 1200, 500]);
            subplot(1,3,1); imshow(colorImg1); title('彩色图像1');
            subplot(1,3,2); imshow(colorImg2); title('彩色图像2');
            subplot(1,3,3); imshow(colorFusioner.fusedImage, []); 
            title(sprintf('融合结果 (%s, %s, L=%d)', ...
                colorFusioner.waveletName, colorFusioner.fusionRule, colorFusioner.decompositionLevel));
        end
    end
end

使用示例

1. 基本使用

matlab 复制代码
% 创建小波图像融合器
fusioner = WaveletImageFusion('db4', 2);  % 使用db4小波,2层分解

% 设置融合规则
fusioner = fusioner.setFusionRule('max');  % 取绝对值最大的系数

% 加载图像
img1 = imread('image1.jpg');
img2 = imread('image2.jpg');
fusioner = fusioner.loadImages(img1, img2);

% 执行小波分解
fusioner = fusioner.performWaveletDecomposition();

% 融合系数
fusioner = fusioner.fuseCoefficients();

% 执行逆变换重建图像
fusioner = fusioner.performInverseTransform();

% 显示结果
fusioner.displayResults();

% 评估融合质量
fusioner.evaluateFusion();

2. 不同融合规则比较

matlab 复制代码
% 加载图像
img1 = im2double(imread('cameraman.tif'));
img2 = im2double(imread('tire.tif'));

% 定义要测试的融合规则
rules = {'max', 'min', 'mean', 'energy', 'selective'};
wavelets = {'haar', 'db2', 'db4', 'sym4'};

% 创建结果图
figure('Name', '不同融合规则比较', 'Position', [100, 100, 1200, 800]);

for w = 1:length(wavelets)
    for r = 1:length(rules)
        % 创建融合器
        fusioner = WaveletImageFusion(wavelets{w}, 2);
        fusioner = fusioner.setFusionRule(rules{r});
        fusioner = fusioner.loadImages(img1, img2);
        
        % 执行融合
        fusioner.performWaveletDecomposition();
        fusioner.fuseCoefficients();
        fusioner.performInverseTransform();
        
        % 显示结果
        subplot(length(wavelets), length(rules), (w-1)*length(rules)+r);
        imshow(fusioner.fusedImage);
        title(sprintf('%s/%s', wavelets{w}, rules{r}), 'FontSize', 10);
    end
end

3. 多分辨率融合

matlab 复制代码
% 加载图像
img1 = im2double(imread('rice.png'));
img2 = im2double(imread('cameraman.tif'));

% 创建融合器
fusioner = WaveletImageFusion('bior4.4', 3);  % 3层分解
fusioner = fusioner.setFusionRule('selective');
fusioner = fusioner.loadImages(img1, img2);

% 执行融合
fusioner.performWaveletDecomposition();
fusioner.fuseCoefficients();
fusioner.performInverseTransform();

% 显示结果
fusioner.displayResults();
fusioner.displayWaveletDetails();
fusioner.displayFusedCoefficients();

算法原理

1. 小波变换基础

小波变换是一种时频分析方法,通过母小波的伸缩和平移来分析信号。在图像处理中,通常使用二维离散小波变换(DWT):

  • 分解过程
    • 图像被分解为四个子带:
      • LL (低频子带):包含图像的主要能量
      • LH (水平高频子带):包含水平边缘信息
      • HL (垂直高频子带):包含垂直边缘信息
      • HH (对角高频子带):包含对角线边缘信息
    • 可以对LL子带进一步分解,实现多分辨率分析
  • 重构过程
    • 使用逆小波变换(IDWT)从子带系数重建图像

2. 图像融合策略

不同的融合规则适用于不同的应用场景:

融合规则 描述 适用场景
max 取绝对值最大的系数 突出显著特征,增强对比度
min 取绝对值最小的系数 平滑区域融合,减少噪声
mean 取系数平均值 平衡融合,保留整体信息
energy 基于局部能量选择系数 突出重要特征,保留细节
selective 低频平均,高频取大 综合全局信息和局部细节

3. 小波基函数选择

不同的小波基函数具有不同的特性:

小波基 特点 适用场景
Haar 最简单的小波,计算快 实时处理,边缘检测
Daubechies (dbN) 紧支撑正交小波,N表示消失矩阶数 一般图像处理,db4常用
Symlets (symN) 近似对称的Daubechies小波 需要对称性的场合
Coiflets (coifN) 高阶消失矩,近似对称性 高精度图像处理
Biorthogonal (biorNr.Nd) 线性相位,适合图像压缩 JPEG2000标准

参考代码 matlab小波变换图像融合源代码 www.youwenfan.com/contentcss/98762.html

扩展功能

1. 多聚焦图像融合

matlab 复制代码
function multiFocusFusion(obj, img1, img2)
    % 多聚焦图像融合专用方法
    % 图像1前景清晰,背景模糊;图像2背景清晰,前景模糊
    
    obj.loadImages(img1, img2);
    obj.setFusionRule('selective');  % 选择性融合最适合多聚焦
    
    % 执行融合
    obj.performWaveletDecomposition();
    obj.fuseCoefficients();
    obj.performInverseTransform();
    
    % 显示结果
    obj.displayResults();
end

2. 红外可见光图像融合

matlab 复制代码
function infraredVisibleFusion(obj, irImg, visImg)
    % 红外与可见光图像融合
    % 红外图像包含热辐射信息,可见光图像包含纹理细节
    
    % 预处理:直方图匹配使图像强度分布相似
    matchedVis = imhistmatch(visImg, irImg);
    
    obj.loadImages(irImg, matchedVis);
    obj.setFusionRule('energy');  % 基于能量的融合适合此场景
    
    % 执行融合
    obj.performWaveletDecomposition();
    obj.fuseCoefficients();
    obj.performInverseTransform();
    
    % 后处理:对比度增强
    obj.fusedImage = imadjust(obj.fusedImage);
    
    % 显示结果
    obj.displayResults();
end

3. 医学图像融合

matlab 复制代码
function medicalImageFusion(obj, ctImg, mriImg)
    % CT与MRI医学图像融合
    % CT显示骨骼结构,MRI显示软组织
    
    % 预处理:配准图像
    if size(ctImg) ~= size(mriImg)
        mriImg = imresize(mriImg, size(ctImg));
    end
    
    obj.loadImages(ctImg, mriImg);
    obj.setFusionRule('selective');
    obj.waveletName = 'coif4';  % 使用coif4小波
    obj.decompositionLevel = 4;  % 4层分解
    
    % 执行融合
    obj.performWaveletDecomposition();
    obj.fuseCoefficients();
    obj.performInverseTransform();
    
    % 显示结果
    obj.displayResults();
    
    % 专业评估
    obj.evaluateMedicalFusion();
end

function evaluateMedicalFusion(obj)
    % 医学图像专用评估指标
    % 计算互信息(MI)、QAB/F等指标
    % 实现略...
end

应用场景

  1. 多传感器图像融合
    • 红外与可见光图像融合
    • 医学影像融合(CT/MRI/PET)
    • 遥感图像融合
  2. 多聚焦图像融合
    • 全清晰图像合成
    • 显微镜图像融合
    • 全景图拼接
  3. 图像增强
    • 去噪与细节增强
    • 超分辨率重建
    • 低光照图像增强
  4. 计算机视觉
    • 目标检测与识别
    • 图像分割
    • 三维重建

总结

本MATLAB实现提供了基于小波变换的图像融合完整解决方案,具有以下特点:

  1. 多小波基支持:支持Haar、Daubechies、Symlets等多种小波基
  2. 多融合策略:提供5种不同的融合规则
  3. 多分辨率分析:支持任意层数的小波分解
  4. 彩色图像处理:自动处理RGB图像
  5. 质量评估:提供多种客观评价指标
  6. 可视化功能:直观展示小波系数和融合结果
  7. 专业应用:针对多聚焦、红外-可见光、医学图像等场景优化
相关推荐
maverick_1112 小时前
【FPGA】关于两个数相加的“坑”
c语言·matlab·fpga开发
这张生成的图像能检测吗2 小时前
(论文速读)MoECLIP:零射异常检测补丁专家
人工智能·深度学习·计算机视觉·异常检测·clip·zero-shot方法
Fleshy数模3 小时前
基于OpenCV实现人脸与微笑检测:从入门到实战
人工智能·opencv·计算机视觉
我材不敲代码3 小时前
OpenCV 实战——Python 实现图片人脸检测 + 视频人脸微笑检测
人工智能·python·opencv
纤纡.4 小时前
从单图风格迁移到实时视频四宫格滤镜:OpenCV DNN 实战全解析
人工智能·opencv·dnn
春日见4 小时前
从底层思维3分钟彻底弄清卷积神经网络CNN
人工智能·深度学习·神经网络·计算机视觉·docker·cnn·计算机外设
FelixZhang0286 小时前
从 PDF 到 AI 知识库:RAG 数据预处理的六步标准流水线 (SOP)
人工智能·python·目标检测·计算机视觉·语言模型·ocr·numpy
盼小辉丶6 小时前
Transformer实战(38)——视觉Transformer (Vision Transformer, ViT)
深度学习·计算机视觉·transformer
feasibility.6 小时前
OpenCV图像滤波算法应用:常见滤波器的原理与效果对比(含c++/python代码与中文显示)
c++·opencv·算法