高斯金字塔和拉普拉斯金字塔实现图像融合

相关笔记

高斯金字塔:

repeat{
1.对图像进行高斯滤波(平滑化);
2.抛除偶数行和列,依次缩小图片尺寸。
// 每进行一轮循环,得到一层金字塔,每层金字塔图像大小都是上一层的一半。
// 该过程称为下采样,金字塔底层即原图。
}

拉普拉斯金字塔:

repeat{
1.对某一层的图像进行扩充,变为其原大小二倍,中间新增的行列补0。
2.对图像进行高斯滤波(实现细节:滤波器放大倍数)。
3.用对应层级、对应大小的高斯金字塔图像,与该操作得到的图像作差,插值即属于拉普拉斯金字塔。
// 拉普拉斯金字塔的顶层(即图像尺寸最小的那一层),直接使用高斯金字塔的顶层图像(最小的那一层)。
//此过程为上采样。
}

关于拉普拉斯金字塔的认识:

认识1:一个金字塔,就是一系列(N个)图像的集合。 // 图像大小逐层递减(1/2)
认识2:拉普拉斯金字塔的意义,类似于“残差”图,保留的是与“原图”的差异。拉普拉斯金字塔的L_i层图像,就是高斯金字塔G_i+1层图像上采样后的G’_i图像与原高斯金字塔中G_i层图像的差值图像
认识3:只需要有一个拉普拉斯金字塔,就可以自底向上地重构出一个完整的原图。//因为拉普拉斯金字塔的顶层并非残差,而是高斯金字塔顶层(原图的直接缩小化)。

图像融合

融合图X,融合图Y,二值掩模图像B。假设构造金字塔层数为N
融合操作:
1.对图X、图Y分别构造拉普拉斯金字塔LX,LY。 // 有N层的图像集合
2.对二值掩模图像B构造高斯金字塔GB。 // 有N层的图像集合
3.对上述的每一层进行插值 RES = LX .* GB + LY .* (1-GB)。 // RES也是有N层的图像集合
4.对金字塔RES实现拉普拉斯金字塔的重构,得到的最大图像原图即为融合图像。

matlab实现

完整代码

mainBlend.m

clear;clc;

% 通过各种方式控制图片大小为(2^N)的倍数,这里采取N层金字塔。设置N到blend.m中。
Iapple = imread('1.jpg');
Iorange = imread('2.jpg');

Apple = im2single(Iapple);
Orange = im2single(Iorange);

[M, N, ~] = size(Apple);
% imshow(Apple);

% 手动绘制二值掩模
maskB = zeros(M,N);
maskB(:,(N/2+1):end) = 1.0;
%maskB(M/4:M*3/4,N/4:N*3/4) = 1.0;
%maskB(M/2+1:end,:) = 1.0;
%for i=1:M
%    for j=1:N
%        if (i-M/2)^2+(j-N/2)^2 < (N/4)*(N/2)
%            maskB(i,j) = 1.0;
%        end
%    end
%end
%imshow(maskB);

% 对于rgb三通道,每一通道单独取出,分别进行一系列融合操作,最后再合并在一起。
redApple = Apple(:,:,1);
greenApple = Apple(:,:,2);
blueApple = Apple(:,:,3);

redOrange = Orange(:,:,1);
greenOrange = Orange(:,:,2);
blueOrange = Orange(:,:,3);

redBlend = blend(redOrange, redApple, maskB);
greenBlend = blend(greenOrange, greenApple, maskB);
blueBlend = blend(blueOrange, blueApple, maskB);

% 合并操作。
result = cat(3,redBlend,greenBlend,blueBlend);

imshow(result);

blend.m

function res = blend(scA, scB, maskB)
    %% 函数介绍 
     
    % 完成某一通道的融合工作。
    % 参数输入:sc即single channel单通道,scA和scB分别代表要融合的图,maskB即二值掩模。
    % 输出:res,融合完毕的图像。
    % -----------------------------------------------------------------
    
    %% 构建scA和scB的拉普拉斯金字塔LA和LB 与 二值掩模图像的高斯金字塔GmaskB
    
    % 预设金字塔的层数
    N = 9;
    
    % 分配一个元胞,用于存储gauss金字塔
    gaussA = cell(1,N);
    gaussB = cell(1,N);
    
    % 分配元胞用于存储拉普拉斯金字塔
    laplaceA = cell(1,N);
    laplaceB = cell(1,N);
    
    % 分配元胞用于存储二值掩模高斯金字塔
    gaussGmaskB = cell(1,N);
    
    % 初始化
    gaussA{1} = scA;
    gaussB{1} = scB;
    gaussGmaskB{1} = maskB;
    
    % 构建高斯金字塔和拉普拉斯金字塔
    for i=2:N
        gaussA{i} = pryDown(gaussA{i-1});
        laplaceA{i-1} = gaussA{i-1} - pryUp(gaussA{i});
        
        gaussB{i} = pryDown(gaussB{i-1});
        laplaceB{i-1} = gaussB{i-1} - pryUp(gaussB{i});
        
        gaussGmaskB{i} = pryDown(gaussGmaskB{i-1});
    end
    
    laplaceA{N} = gaussA{N};
    laplaceB{N} = gaussB{N};
    
    %% 和二值掩模图像进行插值得RES拉普拉斯金字塔
    
    RES = cell(1,N);
    
    for i=1:N
        RES{i} = laplaceA{i} .* gaussGmaskB{i} + laplaceB{i} .* (1 - gaussGmaskB{i});
    end
    
    
    %% 插值后的RES拉普拉斯金字塔进行重建还原
    
    RES_rebuild = cell(1,N);
    
    RES_rebuild{N} = RES{N};
    
    for i=N-1:-1:1
        RES_rebuild{i} = pryUp(RES_rebuild{i+1}) + RES{i};
    end
    
    res = RES_rebuild{1};
end

pryUp.m

function res = pryUp(Image)
    %% 函数介绍 
     
    % 完成拉普拉斯金字塔构建中的上采样操作
    % 参数输入:输入的图像Image
    % 输出:得到Image的下一层图像
    % -----------------------------------------------------------------
    
    %% 实现
    
    [M, N] = size(Image);
     
    % 扩充图像,以0填补
    Image_E = zeros(M*2, N*2);
    Image_E(1:2:end,1:2:end) = Image;
    
    % 上采样高斯滤波,参数输入0
    res = Gauss(Image_E, 0);
    
end

pryDown.m

function res = pryDown(Image)
    %% 函数介绍 
     
    % 完成高斯金字塔构建中的下采样操作
    % 参数输入:输入的图像Image
    % 输出:得到Image的下一层图像
    % -----------------------------------------------------------------
    
    %% 实现
     
    % 下采样高斯滤波,参数输入1
    Img = Gauss(Image, 1);
    
    % 仅提取奇数行列
    res = Img(1:2:end,1:2:end);
    
end

Gauss.m

function Img = Gauss(Image, flag)
    %% 函数介绍 
     
    % 完成对图像Image的高斯滤波
    % 参数输入:Image即输入图像,flag为1则判定是下采样的gauss滤波,为0则判定是上采样的gauss滤波
    % 输出:Img,滤波完毕后的图像。
    % -----------------------------------------------------------------
    
    %% 高斯滤波的实现
    
    [M, N] = size(Image);
    
    Num = 16.0;
    
    % 若为0,则上采样时要对滤波高斯核进行扩大。
    if flag == 0
        Num = 8.0;
    end
    
    %  手动制作5*5的卷积核,此处为行向量
    kernel = [1,4,6,4,1] / Num;
    
    % 对图像进行预处理,即扩展——增加padding
    Image_E = zeros(M + 4, N+4);
    Image_E(3:end-2,3:end-2) = Image;
    
    % 进行滤波操作
    % 进行行滤波,tmpImage_E用于存放中间结果
    tmpImage_E = zeros(M + 4, N+4);
    for i=3:M+2
        for j=3:N+2
            tmpImage_E(i,j) = Image_E(i,j-2:j+2) * kernel'; 
        end
    end
    % 用得到的中间结果tmpImage_E,进行列向滤波
    for j=3:N+2
        for i=3:M+2
            Image_E(i,j) = kernel * tmpImage_E(i-2:i+2,j); 
        end
    end
    
    Img = Image_E(3:end-2,3:end-2);
    
end

版权声明:本文为ph631718930原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。