如何使用小波变换进行图像融合。
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
应用场景
- 多传感器图像融合
- 红外与可见光图像融合
- 医学影像融合(CT/MRI/PET)
- 遥感图像融合
- 多聚焦图像融合
- 全清晰图像合成
- 显微镜图像融合
- 全景图拼接
- 图像增强
- 去噪与细节增强
- 超分辨率重建
- 低光照图像增强
- 计算机视觉
- 目标检测与识别
- 图像分割
- 三维重建
总结
本MATLAB实现提供了基于小波变换的图像融合完整解决方案,具有以下特点:
- 多小波基支持:支持Haar、Daubechies、Symlets等多种小波基
- 多融合策略:提供5种不同的融合规则
- 多分辨率分析:支持任意层数的小波分解
- 彩色图像处理:自动处理RGB图像
- 质量评估:提供多种客观评价指标
- 可视化功能:直观展示小波系数和融合结果
- 专业应用:针对多聚焦、红外-可见光、医学图像等场景优化