相关笔记
高斯金字塔:
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