近红外与可见光图像融合的多种方法实现
我将介绍七种不同的近红外(NIR)与可见光(RGB)图像融合方法 这些方法各具特点,适用于不同的场景。
核心融合方法 matlab
function fusedImage = fuseNIR_RGB(nirPath, rgbPath, method, varargin)% 读取图像nir = im2double(imread(nirPath));rgb = im2double(imread(rgbPath));% 确保图像尺寸一致if ~isequal(size(nir), size(rgb(:,:,1)))nir = imresize(nir, [size(rgb,1), size(rgb,2)]);end% 选择融合方法switch lower(method)case 'weighted_average'% 加权平均法alpha = 0.6; % NIR权重if nargin > 3, alpha = varargin{1}; endfusedImage = alpha * nir + (1-alpha) * mean(rgb, 3);case 'ihs'% IHS变换融合hsv = rgb2hsv(rgb);fusedImage = hsv;fusedImage(:,:,3) = nir; % 用NIR替换亮度分量fusedImage = hsv2rgb(fusedImage);case 'wavelet'% 小波变换融合level = 3; % 分解层数if nargin > 3, level = varargin{1}; end% 对每个通道分别处理fusedRGB = zeros(size(rgb));for c = 1:3[C_rgb, S] = wavedec2(rgb(:,:,c), level, 'db4');[C_nir, ~] = wavedec2(nir, level, 'db4');% 融合规则:低频取平均,高频取绝对值最大fusedCoeffs = zeros(size(C_rgb));for k = 1:level% 低频系数len = S(1,1)*S(1,2);idx = 1:len;fusedCoeffs(idx) = (C_rgb(idx) + C_nir(idx)) / 2;% 高频系数for d = 1:3 % 水平、垂直、对角startIdx = len + 1;len = S(k+1,1)*S(k+1,2);endIdx = startIdx + len - 1;% 取绝对值大的系数abs_rgb = abs(C_rgb(startIdx:endIdx));abs_nir = abs(C_nir(startIdx:endIdx));mask = abs_rgb > abs_nir;fusedCoeffs(startIdx:endIdx) = ...mask.*C_rgb(startIdx:endIdx) + ...~mask.*C_nir(startIdx:endIdx);endendfusedRGB(:,:,c) = waverec2(fusedCoeffs, S, 'db4');endfusedImage = fusedRGB;case 'pca'% PCA融合[height, width] = size(nir);dataMatrix = [nir(:), reshape(rgb, [height*width, 3])];[coeff, score, ~] = pca(dataMatrix);% 用第一主成分替换NIR通道fusedData = score * coeff';fusedImage = reshape(fusedData(:,2:end), [height, width, 3]);case 'laplacian'% 拉普拉斯金字塔融合levels = 5; % 金字塔层数if nargin > 3, levels = varargin{1}; end% 创建金字塔nirPyr = laplacianPyramid(nir, levels);rgbPyr = cell(1, levels);for c = 1:3rgbPyr{c} = laplacianPyramid(rgb(:,:,c), levels);end% 融合金字塔fusedPyr = cell(1, levels);for l = 1:levelsif l == levels % 顶层(最低频)fusedPyr{l} = (nirPyr{l} + mean(cat(3, rgbPyr{1}{l}, ...rgbPyr{2}{l}, rgbPyr{3}{l}), 3)) / 2;else% 高频层取绝对值大的系数abs_nir = abs(nirPyr{l});abs_rgb = mean(cat(3, abs(rgbPyr{1}{l}), ...abs(rgbPyr{2}{l}), abs(rgbPyr{3}{l})), 3);mask = abs_nir > abs_rgb;fusedPyr{l} = mask.*nirPyr{l} + ~mask.*mean(cat(3, ...rgbPyr{1}{l}, rgbPyr{2}{l}, rgbPyr{3}{l}), 3);endend% 重建融合图像fusedGray = reconstructPyramid(fusedPyr);fusedImage = rgb;for c = 1:3fusedImage(:,:,c) = imadjust(fusedImage(:,:,c), ...stretchlim(fusedImage(:,:,c)), [0 1]);endfusedImage = fusedGray * 0.6 + fusedImage * 0.4;case 'guided_filter'% 导向滤波融合radius = 15; % 滤波器半径eps = 0.01; % 正则化参数if nargin > 3, radius = varargin{1}; endif nargin > 4, eps = varargin{2}; endfusedImage = rgb;for c = 1:3fusedImage(:,:,c) = imguidedfilter(rgb(:,:,c), nir, ...'NeighborhoodSize', [radius, radius], 'DegreeOfSmoothing', eps);endcase 'deep_learning'% 深度学习融合(需要深度学习工具箱)if ~license('test', 'Neural_Network_Toolbox')error('深度学习融合需要神经网络工具箱');end% 创建简单的融合网络layers = [imageInputLayer([size(nir,1) size(nir,2) 4], 'Name', 'input')convolution2dLayer(3, 32, 'Padding', 'same', 'Name', 'conv1')batchNormalizationLayer('Name', 'bn1')reluLayer('Name', 'relu1')convolution2dLayer(3, 64, 'Padding', 'same', 'Name', 'conv2')batchNormalizationLayer('Name', 'bn2')reluLayer('Name', 'relu2')convolution2dLayer(3, 32, 'Padding', 'same', 'Name', 'conv3')batchNormalizationLayer('Name', 'bn3')reluLayer('Name', 'relu3')convolution2dLayer(3, 3, 'Padding', 'same', 'Name', 'conv4')regressionLayer('Name', 'output')];% 准备训练数据(这里使用示例数据)inputData = cat(3, nir, rgb);targetData = rgb; % 理想情况下应有真实融合图像% 训练选项options = trainingOptions('adam', ...'MaxEpochs', 20, ...'MiniBatchSize', 4, ...'Plots', 'training-progress');% 训练网络net = trainNetwork(inputData, targetData, layers, options);% 使用网络进行融合fusedImage = predict(net, inputData);otherwiseerror('未知融合方法: %s', method);end% 确保输出在[0,1]范围内fusedImage = min(max(fusedImage, 0), 1);
end%% 辅助函数:拉普拉斯金字塔
function pyr = laplacianPyramid(img, levels)pyr = cell(1, levels);current = img;for i = 1:levels-1[pyr{i}, current] = doPyramidLevel(current);endpyr{levels} = current; % 最顶层的低频部分
endfunction [high, low] = doPyramidLevel(img)% 高斯模糊和下采样low = imfilter(img, fspecial('gaussian', 5, 1), 'replicate');low = imresize(low, 0.5, 'bilinear');% 上采样并重建高频分量up = imresize(low, size(img), 'bilinear');high = img - up;
endfunction img = reconstructPyramid(pyr)img = pyr{end};for i = length(pyr)-1:-1:1up = imresize(img, size(pyr{i}), 'bilinear');img = pyr{i} + up;end
end
七种融合方法详解
1. 加权平均法
- 原理:对NIR和RGB的平均亮度进行加权平均
- 优点:计算简单,速度快
- 缺点:对比度降低,细节保留不足
- 适用:实时处理系统
2. IHS变换融合
- 原理:
- 将RGB图像转换到HSV色彩空间
- 用NIR图像替换亮度(V)通道
- 转换回RGB空间
- 优点:保持色彩信息,增强细节
- 缺点:可能引入色彩失真
- 适用:遥感图像增强
3. 小波变换融合
- 原理:
- 对NIR和RGB各通道进行小波分解
- 低频分量取平均
- 高频分量取绝对值大的系数
- 小波重构
- 优点:细节保留好,空间一致性高
- 缺点:计算复杂,可能产生伪影
- 适用:医学图像、高精度地形分析
4. PCA融合
- 原理:
- 将NIR和RGB通道组成数据矩阵
- 进行主成分分析
- 用第一主成分增强图像
- 优点:最大化信息保留
- 缺点:色彩保真度较低
- 适用:特征提取、目标检测
5. 拉普拉斯金字塔融合
- 原理:
- 构建多尺度拉普拉斯金字塔
- 在不同尺度应用不同融合规则
- 重建融合图像
- 优点:多尺度信息融合效果好
- 缺点:计算复杂度高
- 适用:多分辨率分析、图像增强
6. 导向滤波融合
- 原理:
- 使用NIR图像作为引导图像
- 对RGB各通道应用导向滤波
- 保持边缘同时传输NIR细节
- 优点:边缘保持性好,色彩自然
- 缺点:参数敏感
- 适用:图像去雾、增强现实
7. 深度学习融合
- 原理:
- 构建端到端的卷积神经网络
- 学习NIR和RGB的最优融合方式
- 自动生成融合结果
- 优点:自适应性强,效果最好
- 缺点:需要训练数据和计算资源
- 适用:高质量图像融合、专业应用
% 加载图像
nir = 'nir_image.jpg';
rgb = 'visible_image.jpg';% 创建融合结果比较图
methods = {'weighted_average', 'ihs', 'wavelet', 'pca', ...'laplacian', 'guided_filter', 'deep_learning'};
titles = {'加权平均', 'IHS变换', '小波变换', 'PCA融合', ...'拉普拉斯金字塔', '导向滤波', '深度学习'};figure('Position', [100, 100, 1400, 1000]);
subplot(3, 3, 1); imshow(imread(nir)); title('近红外图像');
subplot(3, 3, 2); imshow(imread(rgb)); title('可见光图像');for i = 1:7% 融合图像tic;fused = fuseNIR_RGB(nir, rgb, methods{i});time = toc;% 显示结果subplot(3, 3, i+2);imshow(fused);title(sprintf('%s (%.2fs)', titles{i}, time));% 保存结果imwrite(fused, sprintf('fused_%s.jpg', methods{i}));
end% 评估融合质量
fprintf('\n融合质量评估:\n');
fprintf('%-20s %-10s %-10s %-10s %-10s\n', '方法', 'PSNR', 'SSIM', 'EN', 'SF');
for i = 1:7fused = imread(sprintf('fused_%s.jpg', methods{i}));[psnr, ssim, en, sf] = evaluateFusion(rgb, fused);fprintf('%-20s %-10.2f %-10.4f %-10.2f %-10.2f\n', ...titles{i}, psnr, ssim, en, sf);
end%% 融合质量评估函数
function [psnr, ssim, en, sf] = evaluateFusion(refPath, fused)ref = im2double(imread(refPath));fused = im2double(fused);% PSNRmse = mean((ref(:) - fused(:)).^2);psnr = 10 * log10(1 / mse);% SSIMssim = ssim_index(ref, fused);% 信息熵 (EN)grayFused = rgb2gray(fused);en = entropy(grayFused);% 空间频率 (SF)[rows, cols] = size(grayFused);rf = sqrt(sum(sum(diff(grayFused,1,1).^2)) / (rows*(cols-1));cf = sqrt(sum(sum(diff(grayFused,1,2).^2)) / ((rows-1)*cols);sf = sqrt(rf^2 + cf^2);
end
参考代码 多种方法融合近红外与可见光图像 youwenfan.com/contentcsc/83473.html
融合方法选择指南
应用场景 | 推荐方法 | 理由 |
---|---|---|
实时监控 | 加权平均或IHS | 计算速度快 |
遥感图像处理 | IHS或小波变换 | 保持空间细节和色彩 |
医学成像 | 小波变换或拉普拉斯金字塔 | 多尺度细节保留 |
低光照增强 | 导向滤波 | 边缘保持,自然色彩 |
目标检测 | PCA融合 | 特征增强 |
高质量图像生成 | 深度学习 | 自适应最优融合 |
资源受限环境 | 加权平均 | 最低计算复杂度 |
性能优化建议
-
GPU加速:
% 将数据转移到GPU if gpuDeviceCount > 0nir = gpuArray(nir);rgb = gpuArray(rgb); end
-
并行计算:
% 对RGB通道并行处理 parfor c = 1:3channelResult = processChannel(rgb(:,:,c), nir);fused(:,:,c) = channelResult; end
-
多尺度加速:
% 使用图像金字塔加速处理 smallNIR = impyramid(nir, 'reduce'); smallRGB = impyramid(rgb, 'reduce'); fusedSmall = fuseMethod(smallNIR, smallRGB); fused = impyramid(fusedSmall, 'expand');
-
自适应融合:
% 根据局部特征调整融合策略 edgeMap = edge(nir, 'canny'); weightMap = imgaussfilt(double(edgeMap), 2); fused = weightMap.*fusionMethod1 + (1-weightMap).*fusionMethod2;
这些方法为近红外与可见光图像融合提供了全面的解决方案,可根据具体应用场景和性能要求选择最合适的方法。