小波变换、图像复原、边缘检测

这一部分和上一节是连在一起的,里面的一些函数在上一篇文章中已经给出,这里不重复给出。
图像可以根据小波变换变换成四幅图像。四幅图像分别是近似图像,水平细节图像,垂直细节图像和对角线细节图像。通过对这四个分量的调整,可以进行图像的边缘处理或者噪声去除。下面是本次实验的实验思路。

设计思路

小波变换实验思路

小波变换的步骤如下:
步骤 1:本次实验使用正交归一化四阶对称小波 h_phi,首先,根据公式
hpsi(i) = (−1)(i − 1) ∗ hphi(9 − i) 。求出函数 h_psi,之后变可以翻转变换得到 h0 h1 g0 g1,得到上面四个函数之后,便可以开始进行卷积操作。

步骤 2:之后使用上面得到的函数,对图像的列进行分解,分别于 h0 和 h1 进行卷积,之后进行列的以二为基的下采样,得到中间图像。

步骤 3:之后对中间图像的行进行分解,同样分别两次使用 h0 和 h1 进行卷积,之后进行行的以二为基的下采样,这时我们得到了四张图像,这四张图像便是近似图像 im_M ,水平细节图像 im_H,垂直细节图像 im_V 和对角线细节图像 im_D。

图像复原实验思路

图像的直接复原就是,利用小波反变换得到原来的图像。下面是处理步骤:

步骤 1:分组 im_M 和 im_H 一组,im_V 和 im_D 一组。首先对每组进行以二为基的行上采样,使用线性插值算法,之后分别与 g0,g1 进行卷积计算,得到两幅中间图像 im_M 1 和 im_D1。

步骤 2:im_M 1 和 im_D1 进行以二为基的列上采样,使用线性插值算法,之后分别与 g0, g1 进行卷积计算,得到合成图像 im_B。

边缘检测实验思路

仿照书中的处理方法,将一次小波变换的四幅图像中的近似图形再次进行小波变换,得到 im_MM ,im_MH,im_MV ,im_MD,将 im_MM 其全部置为 0,之后进行两次小波反变换,得到边缘检测的处理图像。
对纵向的边缘检测,将 im_MM ,im_MH,im_H 全部置为 0,之后进行两次小波反变换,得到纵向的边缘检测。

代码

主函数
%% 运行 exp7_12.m 

clc;
clear;
close all;

%% 课本图 7.12
% 读取图片
im = imread('demo-2.tif');   % 原始图像 uint8

%% 函数h_phi的正交归一化四阶对称小波滤波器系数
h_phi = [0.0322 -0.0126 -0.0992 0.2979 0.8037 0.4976 -0.0296 -0.0758];
h_psi = zeros(1,8); 
for i = 1:1:8
    h_psi(i) = (-1)^(i-1) * h_phi(9-i);
end
i = 1:1:8;
h0(i) = h_phi(9-i);
h1(i) = h_psi(9-i);
g0(i) = h_phi(i);
g1(i) = h_psi(i);

%% 小波变换
[im_M,im_H,im_V,im_D] = my_dwt(im,h0,h1);

%% 小波反变换(图像复原)
im_B1 = my_idwt(im_M,im_H,im_V,im_D,g0,g1);

%% 图像边缘检测
[im_MM,im_MH,im_MV,im_MD] = my_dwt(im_M,h0,h1);
% 去除尺度图像
[M,N] = size(im_MM);
im_MM = zeros(M,N);
% 图像复原
im_M1 = my_idwt(im_MM,im_MH,im_MV,im_MD,g0,g1);
im_B2 = my_idwt(im_M1,im_H,im_V,im_D,g0,g1);

% 去除横向的小波图像
[M,N] = size(im_MH);
im_MH = zeros(M,N);
[M,N] = size(im_H);


% 图像复原
im_M1 = my_idwt(im_MM,im_MH,im_MV,im_MD,g0,g1);
im_B3 = my_idwt(im_M1,im_HX,im_V,im_D,g0,g1);

%% 图像归一化显示
im_M = uint8(255.0*(mat2gray(im_M)));
im_V = uint8(255.0*(mat2gray(im_V)));
im_H = uint8(255.0*(mat2gray(im_H)));
im_D = uint8(255.0*(mat2gray(im_D)));
im_B1 = uint8(255.0*(mat2gray(im_B1)));
im_B2 = uint8(255.0*(mat2gray(im_B2)));
im_B3 = uint8(255.0*(mat2gray(im_B3)));

%% 将结果保存到当前目录下的result文件夹下
imwrite(im_M, sprintf('result/_%s.jpg', 'im_M'));
imwrite(im_H, sprintf('result/_%s.jpg','im_H'));
imwrite(im_V, sprintf('result/_%s.jpg','im_V'));
imwrite(im_D, sprintf('result/_%s.jpg','im_D'));
imwrite(im_B1, sprintf('result/_%s.jpg', 'im_B1'));
imwrite(im_B2, sprintf('result/_%s.jpg', 'im_B2'));
imwrite(im_B3, sprintf('result/_%s.jpg', 'im_B3'));

%% 显示结果
figure(1); 
subplot(241); imshow(im_M); title('尺度图像'); axis on
subplot(242); imshow(im_H); title('H小波图像'); axis on
subplot(243); imshow(im_V); title('V小波图像'); axis on
subplot(244); imshow(im_D); title('D小波图像'); axis on
subplot(245); imshow(im); title('原图像'); axis on
subplot(246); imshow(im_B1); title('复原图像'); axis on
subplot(247); imshow(im_B2); title('边缘检测图像1'); axis on
subplot(248); imshow(im_B3); title('边缘检测图像2'); axis on
小波变换
function [im_M,im_H,im_V,im_D] = my_dwt(im,h0,h1)

%% 列维度处理
im_r_h0 = convolution_r(im,h0);
im_r_h1 = convolution_r(im,h1);

%% 行维度处理
im_M = convolution_l(im_r_h0,h0);
im_H = convolution_l(im_r_h0,h1);
im_V = convolution_l(im_r_h1,h0);
im_D = convolution_l(im_r_h1,h1);
end
function im_h = convolution_l(im,h)

% 得到图像的行数、列数、以及每像素的维数(防止出现RGB图像)
im = im(:,:,1);
[line,row,v]=size(im);% 对称式延拓,一共延拓14行
im = [im(7,:);im(6,:);im(5,:);im(4,:);im(3,:);im(2,:);im(1,:);im;im(line,:); im(line-1,:); im(line-2,:); im(line-3,:) ;im(line-4,:) ;im(line-5,:); im(line-6,:)];
[line,row,v]=size(im);

%im_double = mat2gray(im,[0 255]);
im_double = double(im);

im_f = zeros(line,row);
for j = 1:1:line
    for k = 1:1:line
        if (j-k>0 && j-k<9)
            im_f(j,:) = im_f(j,:) + h(j-k) * im_double(k,:);
        end
    end
end

% im_f = mat2gray(im_f);
% im_f = uint8(round(im_f*255));

line = floor((line-14)/2);
im_h = zeros(line,row);

i = 0:1:line-1;
im_h(i + 1,:) = im_f(2*i+13,:);
%im_h = uint8(im_h);
end
function im_h = convolution_r(im,h)

% 得到图像的行数、列数、以及每像素的维数(防止出现RGB图像)
im = im(:,:,1);
[line,row,v]=size(im);% 对称式延拓,一共延拓14列
im = [im(:,7) im(:,6) im(:,5) im(:,4) im(:,3) im(:,2) im(:,1) im im(:,row) im(:,row-1) im(:,row-2) im(:,row-3) im(:,row-4) im(:,row-5) im(:,row-6)];
[line,row,v]=size(im);

%im_double = mat2gray(im,[0 255]);
im_double = double(im);

im_f = zeros(line,row);
for j = 1:1:row
    for k = max(1,j-8):1:min(row,j-1)
        im_f(:,j) = im_f(:,j) + h(j-k) * im_double(:,k);
    end
end

% im_f = mat2gray(im_f);
% im_f = uint8(round(im_f*255));

row = floor((row-14)/2);
im_h = zeros(line,row);

i = 0:1:row-1;
im_h(:,i + 1) = im_f(:,2*i+13);
%im_h = uint8(im_h);
end
图像复原

im_l0 = Combim(convolution_gl(im_D, g1), convolution_gl(im_V, g0)); im_l1 = Combim(convolution_gl(im_H, g1), convolution_gl(im_M, g0)); im_B = Combim(convolution_gr(im_l0, g1), convolution_gr(im_l1, g0));
Combin 是求和的函数,即让两幅图像叠加
convolution 是求卷积的函数,同时内部有以二为基的上采样

function im_B = my_idwt(im_M,im_H,im_V,im_D,g0,g1)
% 两倍上采样 卷积 求和
im_l0 = Combim(convolution_gl(im_D,g1) , convolution_gl(im_V,g0));

im_l1 = Combim(convolution_gl(im_H,g1) , convolution_gl(im_M,g0));

im_B = Combim(convolution_gr(im_l0,g1) , convolution_gr(im_l1,g0));
end
function im_g = convolution_gl(im,g)
im = myBilinear(im, 2,1);
% 得到图像的行数、列数、以及每像素的维数(防止出现RGB图像)
im = im(:,:,1);
[line,row,v]=size(im);% 对称式延拓,一共延拓14行
im = [im(7,:);im(6,:);im(5,:);im(4,:);im(3,:);im(2,:);im(1,:);im;im(line,:); im(line-1,:); im(line-2,:); im(line-3,:) ;im(line-4,:) ;im(line-5,:); im(line-6,:)];
[line,row,v]=size(im);

%im_double = mat2gray(im,[0 255]);
im_double = double(im);

im_f = zeros(line,row);
for j = 1:1:line
    for k = 1:1:line
        if (j-k>0 && j-k<9)
            im_f(j,:) = im_f(j,:) + g(j-k) * im_double(k,:);
        end
    end
end
line = floor((line-14));
im_g = zeros(line,row);

% im_f = mat2gray(im_f);
% im_f = uint8(round(im_f*255));

i = 0:1:line-1;
im_g(i + 1,:) = im_f(i + 13,:);
%im_g = uint8(im_g);
end
function im_g = convolution_gr(im,g)

im = myBilinear(im,1,2);
% 得到图像的行数、列数、以及每像素的维数(防止出现RGB图像)
im = im(:,:,1);
[line,row,v]=size(im);% 对称式延拓,一共延拓14列
im = [im(:,7) im(:,6) im(:,5) im(:,4) im(:,3) im(:,2) im(:,1) im im(:,row) im(:,row-1) im(:,row-2) im(:,row-3) im(:,row-4) im(:,row-5) im(:,row-6)];
[line,row,v]=size(im);

%im_double = mat2gray(im,[0 255]);
im_double = double(im);

im_f = zeros(line,row);
for j = 1:1:row
    for k = max(1,j-8):1:min(row,j-1)
        im_f(:,j) = im_f(:,j) + g(j-k) * im_double(:,k);
    end
end

%im_f = mat2gray(im_f);
%im_f = uint8(round(im_f*255));

row = floor((row-14));
im_g = zeros(line,row);

i = 0:1:row-1;
im_g(:,i + 1) = im_f(:,i+13);
%im_g = uint8(im_g);
end
边缘检测

im_MM = zeros(M, N ); 尺度图像置零
im_M 1 = my_idwt(im_MM, im_MH, im_MV, im_MD, g0, g1);图像复原im_B2 = my_idwt(im_M 1, im_H, im_V, im_D, g0, g1); 图像复原
im_MH = zeros(M, N ); im_HX = zeros(M, N ); 横向细节图像置零
im_M 1 = my_idwt(im_MM, im_MH, im_MV, im_MD, g0, g1);图像复原im_B3 = my_idwt(im_M 1, im_H, im_V, im_D, g0, g1); 图像复原

实验结果

本次实验中使用了四阶对称小波进行小波变换得到四张图像。最后使用一些边缘检测的小技巧————通过置零近似图形可以复原出边缘图像、通过置零横向细节图像和近似图像 最后得到原图像的纵向边缘。

python基于小波的边缘检测 小波变换 边缘检测_边缘检测

python基于小波的边缘检测 小波变换 边缘检测_python基于小波的边缘检测_02

由上图可以看出,小波变换几乎可以无损的复原图像,之后开始对图像进行处理,利用对各个图像分量的调整,来求出图像的边缘,下面是提取边缘的结果,左图是全局的边缘图像,右图是纵向的边缘图像

python基于小波的边缘检测 小波变换 边缘检测_边缘检测_03

实验分析

这次实验发现,利用小波分析可以对图像进行较好的处理,对图像的边缘、噪声细节等等有很好的区分能力。在本次实验中使用了对称小波,对图像卷积时采用了对称延拓得到了较好的处理结果。最后显示图像时,使用了归一化函数,从而得到了较好的显示效果,和书中一致。

实验小结

本次实验,研究了图像金字塔和拉普拉斯金字塔,认识到了其在图像处理中的作用。之后深入学习了小波变换的原理、性质、数学计算、使用方法,并且将其运用在在实际使用中。小波变换对信号检测,图像压缩,噪声去除,有着极其重要的作用。这次学习中,不仅学习了其运行的方法,还学习了小波变换的思想,将空域和频域的图像综合看待,得到一种从某些角度优于傅里叶变换的图像处理方式。