前面我们说到灰度图像的融合,其实我本意是想实现Pan和多光谱(MS)的融合的,但是由于无法解决Pan小波分解之后与MS小波分解后维度匹配上的差异,就放弃了。正如前面的博客的代码所描述的那样,其实单通道与单通道的小波分变换的融合是十分容易的。但是要从单通道跳跃到多通道,还需要一些小小的技巧。对于初看融合代码的我来说,确实没能轻松的跳过。
那如何将小波变换从单通道应用到多通道呢?
其实是一种很简单朴素的想法,就是将Pan扩展成同MS一样的通道数。这样就保证Pan在第三维度上同MS图像一样了。这里还有一个问题,由于低分辨率的多光谱图像的长、宽是小于Pan图的。所以此时将MS图像也上采样4倍(我们假设Pan和LMS分辨率相差4倍),这样Pan和MS在各维度上都一样了。分别对上述图像小波变换,接着用MS的低频部分去代替Pan的低频部分。最后实现小波逆变换就得到融合结果了。
引用自《A VARIATIONAL APPROACH FOR SHARPENING HIGH DIMENSIONAL IMAGES 》–MICHAEL MOLLER(2012)
主程序如下:
pan_file = 'big_pan.tif';
pan = imread(pan_file);
pan = double(pan) /256;
ms_file = 'LR.tif';
ms = imread(ms_file);
ms = imresize(ms,4); % LMS上采样4倍
ms = double(ms)/256;
res = waveletfusion(ms,pan);
figure(1);imshow(res,[]);title('融合结果');
以下是核心代码:
function solution = waveletfusion( lowres, panimage, level, waveletname)
% % % % % % % % % % % % % % % % % % % % % % %
% % @author chaolei
% % 2010/07/10
% % % % % % % % % % % % % % % % % % % % % % %
% % ================================================
% 设置默认小波基和分解尺度的默认值
% % ================================================
if ~exist('waveletname','var')
waveletname = 'haar';
end
if ~exist('level','var')
level = 2;
end
[height ,width ,channels] = size(lowres);
[panvec, s] = wavedec2(panimage,level,waveletname);
% % ================================================
% 开辟存储Pan和MS各波段的小波系数的空间
% % ================================================
length = size(panvec,2);
reconstvec = zeros(length,channels); % 复制Pan的小波系数 channels倍
lowresvec = zeros(length,channels); % 存储MS各波段小波系数
% % ================================================
% 对MS的各波段分别进行小波变换(小波分解)
% % ================================================
for i = 1:channels
reconstvec(:,i) = panvec;
lowresvec(:,i) = wavedec2(lowres(:,:,i),level,waveletname);
end
% % ================================================
% 融合策略:Pan的高频部分+MS各波段的低频部分得到结果
% % ================================================
j = s(1,1) * s(1,2);
reconstvec(1:j,:) = lowresvec(1:j,:);
% % ================================================
% 小波逆变换
% % ================================================
solution = zeros(height,width,channels);
for i=1:channels
solution(:,:,i) = waverec2(reconstvec(:,i),s,waveletname);
end
end
以上就是我找到的代码然后修改了,其实我有好几个自己实现的版本,这里就贴一个另一种的Pan扩展的思想的代码吧。为了避免繁琐,我不再写成子函数的形式。大家可以体会一下,下面的代码究竟与上面的代码有何不同。
pan_file = 'big_pan.tif';
pan = imread(pan_file);
pan = double(pan) /256;
pan = repmat(pan,1,1,3);
ms_file = 'LR.tif';
ms = imread(ms_file);
ms = imresize(ms,4); % 使MS同Pan尺寸一致
ms = double(ms)/256;
level =2;
waveletname = 'haar';
[panvec,s0] = wavedec2(pan,level,waveletname);
[msvec, s1] = wavedec2(ms,level,waveletname);
j = s0(1,1)*s0(1,2)*s0(1,3);
panvec(1,1:j) = msvec(1,1:j);
res = waverec2(panvec,s0,waveletname);
figure(3);imshow(res);title('融合结果');
需要注意的是,level参数要控制好,如果太大会造成光谱失真。适度的level可以保证很好的光谱保持。有兴趣的同学可以试试不同的level,看看最终的结果有何不同。