空间滤波,就是直接在灰度值上,做一些滤波操作。滤波一词,其实来源于频域,将某个频率成分滤除的意思。大部分线性的空间滤波器(比如均值滤波器),是在空间上进行一些灰度值上的操作,这个线性空间滤波器与频域滤波器有一一对应的关系(比如均值滤波器其本质就是低通滤波器),这样会有助于理解这个滤波器的特性。然而,对于非线性的滤波器(比如最大值,最小值和中央值滤波器)的话,则没有这样一个一一对应的关系。
线性空间滤波所使用的运算是卷积,其计算如下所示。
在执行空间滤波的时候,我们都会使用到这个操作。
这个式子可能会出现两个问题。这次是在空间域进行操作的,所以上式应该没什么问题。但是,如果换到频域,我们会发现,我们使用的滤波器是非因果的,按照我之前在数字信号处理的那一节,非因果具有零相位特性,但是是不可实现的,因为需要未来的输入。而在这,我们在图像处理的时候,都是一帧一帧的处理,所以,这里非因果性不是问题。而最重要的是,零相位特性不会使得图像变形,这是很重要的。
还有一个问题就是边界问题,当滤波器的中心靠近图像边缘时候,滤波器的一部分会位于图像外,那么此时,我们通常会采用填0的操作来解决。但是,一些场合,直接填0操作会使得操作后的图像出现黑边。所以,常用的操作还有,①选择距离最近的点填充,②填充的点为圆图像的镜像,③将原图像当做周期信号来填充。
在空间域上考虑,我们所指的平滑滤波器,有平均滤波与加权平均滤波两种形式。
这里很好理解,将滤波器范围内的点,求平均值(或者加权平均值)。这样会使得图像平滑,有助于去掉一些噪声。
我们将其放到频域去考虑的话,其实这是一个很典型的低通滤波器。这个滤波器会滤掉高频成分,所以可以使得图像平滑。其频率响应如下所示。
3X3平均滤波的频率响应
3X3加权平均滤波的频率响应
首先,对于两个滤波器的振幅特性。平均滤波器的通带要比加权平均滤波器的窄,故使用平均滤波器处理的图像要比加权滤波器处理的图像要模糊一些。
注意平均滤波器的相位特性,其相位特性并不是一个平面,有的地方的值为π。首先,平均滤波器是一个偶实函数,其频率响应是一个实函数。但是,其频率响应有的部分为负值,这就造成了Matlab的angle()的计算结果为π。其实其还是具有0相位特性的。
用其处理实际处理图像的话,会得到以下结果。
看其处理结果,其实很难分辨出有什么区别。所以,加权平均滤波器和平均滤波器的区别,从频率响应来看的话,容易明白一些。本文只是简单的介绍一下均值滤波器,详细的,请参看[数字图像处理]图像去噪初步(1)--均值滤波器
统计排序滤波器的运用也广泛,其是很典型的非线性滤波器。主要包括了,最大值滤波器,最小值滤波器,中央值滤波器等等。这里作为代表的,主要说中央值滤波器,中央值滤波对于去除椒盐噪声特别有效。
所谓中央值滤波器,就是将滤波器范围内的像素的灰度值,进行排序,选出中央值作为这个像素的灰度值。同理可解释最大值滤波器与最小值滤波器。
我们将一幅图像添加椒盐噪声,然后尝试着用中央值滤波器去除。
从直方图中,可以看出,中央值滤波器对于椒盐噪声,有很好的去噪作用。关于非线性滤波的详细,请参看[数字图像处理]图像去噪初步(2)--非线性滤波器
使用平均滤波器,可以将图像平滑,其本质是将图像在滤波器范围内求平均值。从频域上来看,平均滤波器是低通滤波器。然而,所谓的锐化,即是将图像的细节强调出来。这里进行了一个假设,假设细节部分是图像高频成分。从这里看来,其实锐化滤波器是与平均滤波器是相反的操作。
对于一个一次元函数,其一阶微分为
这样的微分被称为向前一次微分,这样的微分会产生一个采样点(针对图像来说,偏移一个像素)的偏移。为了避免这样的偏移,一般将向前一次微分与向后一次微分连用,这样就不会产生一些偏移,如下所示。
现在将其二阶段微分扩展到二次元的图像,如下所示。
将其写成滤波器的形式的话,如下左所示。我们为了强调其微分效果,也可以在斜方向上加上一个微分效果,如下右所示。我们将其称为拉普拉斯算子。
其频率响应如下所示。
四方向的拉普拉斯滤波器的频率响应
八方向的拉普拉斯滤波器的频率响应
我们可以看出,八方向的拉普拉斯滤波器对于高频成分的强调效果较强。其低频部分最小值为0,这意味着,进行拉普拉斯滤波之后,其实只剩下图像的高频部分了(在空间域里来讲,只剩下边缘部分了)。所以,若用于图像锐化的话,可以将所得结果叠加至原图像,其实也就相当与滤波器的振幅特性往上移动1,保证低频部分不变,强调高频部分。
-
close all;
-
clear all;
-
-
%% -------------Smoothing Lines Filters-----------------
-
f = imread(
'test_pattern_blurring_orig.tif');
-
f = mat2gray(f,[
0
255]);
-
-
w_1 = ones(
3)/
9; %%%%%
-
g_1 = imfilter(f,w_1,
'conv',
'symmetric',
'same');
-
-
w_2 = ones(
5)/
25; %%%%%
-
g_2 = imfilter(f,w_2,
'conv',
'symmetric',
'same');
-
-
w_3 = [
1
2
1;
-
2
4
2;
-
1
2
1]/
16; %%%%%
-
g_3 = imfilter(f,w_3,
'conv',
'symmetric',
'same');
-
-
figure();
-
subplot(
1,
2,
1);
-
imshow(f,[
0
1]);
-
xlabel(
'a).Original Image');
-
-
subplot(
1,
2,
2);
-
imshow(g_1,[
0
1]);
-
xlabel(
'b).Average Filter(size 3x3)');
-
-
figure();
-
subplot(
1,
2,
1);
-
imshow(g_2,[
0
1]);
-
xlabel(
'c).Average Filter(size 5x5)');
-
-
subplot(
1,
2,
2);
-
imshow(g_3,[
0
1]);
-
xlabel(
'd).Weighted Average Filter(size 3x3)');
-
-
%% ------------------------
-
M =
64;
-
N =
64;
-
[H_1,w1,w2] = freqz2(w_1,M,N);
-
figure();
-
subplot(
1,
2,
1);
-
mesh(w1(
1:M)*pi,w2(
1:N)*pi,
abs(H_1(
1:M,
1:N)));
-
axis([-pi pi -pi pi
0
1]);
-
xlabel(
'\omega_1 [rad]');ylabel(
'\omega_2 [rad]');
-
zlabel(
'|H(e^{j\omega_1},e^{j\omega_2})|');
-
-
-
%figure();
-
subplot(
1,
2,
2);
-
mesh(w1(
1:M)*pi,w2(
1:N)*pi,unwrap(angle(H_1(
1:M,
1:N))));
-
axis([-pi pi -pi pi -pi pi]);
-
xlabel(
'\omega_1 [rad]');ylabel(
'\omega_2 [rad]');
-
zlabel(
'\theta [rad]');
-
close all;
-
clear all;
-
-
%% ----------------Noise
type--------------------
-
f = imread(
'original_pattern.tif');
-
f = mat2gray(f,[
0
255]);
-
[M,N] = size(f);
-
-
g_gaussian = imnoise(f,
'gaussian',
0,
0.015);
-
g_salt_pepper = imnoise(f,
'salt & pepper',
0.15);
-
-
figure(
1);
-
subplot(
1,
2,
1);
-
imshow(f,[
0
1]);
-
xlabel(
'a).Original Image');
-
-
subplot(
1,
2,
2);
-
h = imhist(f)/(M*N);
-
bar(
0:
1/
255:
1,h);
-
axis([
-0.1
1.1
0
0.55]),grid;
-
axis square;
-
xlabel(
'b).The histogram of original image');
-
ylabel(
'Number of pixels');
-
-
figure(
2);
-
subplot(
1,
2,
1);
-
imshow(g_gaussian,[
0
1]);
-
xlabel(
'c).gaussian noise image');
-
-
subplot(
1,
2,
2);
-
h = imhist(g_gaussian)/(M*N);
-
bar(
0:
1/
255:
1,h);
-
axis([
-.1
1.1
0
0.05]),grid;
-
axis square;
-
xlabel(
'd).The histogram of c)');
-
ylabel(
'Number of pixels');
-
-
figure(
5);
-
subplot(
1,
2,
1);
-
imshow(g_salt_pepper,[
0
1]);
-
xlabel(
'i).salt & pepper noise image');
-
-
subplot(
1,
2,
2);
-
h = imhist(g_salt_pepper)/(M*N);
-
bar(
0:
1/
255:
1,h);
-
axis([
-.1
1.1
0
0.55]),grid;
-
axis square;
-
xlabel(
'j).The histogram of g)');
-
ylabel(
'Number of pixels');
-
-
%% -------------Nonlines Filters-----------------
-
g_med_wg = medfilt2(g_gaussian,
'symmetric',[
3
3]);
-
g_med_sp = medfilt2(g_salt_pepper,
'symmetric',[
3
3]);
-
-
figure(
3);
-
subplot(
1,
2,
1);
-
imshow(g_med_wg,[
0
1]);
-
xlabel(
'e).Result of median filter');
-
-
subplot(
1,
2,
2);
-
h = imhist(g_med_wg)/(M*N);
-
bar(
0:
1/
255:
1,h);
-
axis([
-.1
1.1
0
0.05]),grid;
-
axis square;
-
xlabel(
'f).The histogram of e)');
-
ylabel(
'Number of pixels');
-
-
-
figure(
6);
-
subplot(
1,
2,
1);
-
imshow(g_med_sp,[
0
1]);
-
xlabel(
'k).Result of median filter');
-
-
subplot(
1,
2,
2);
-
h = imhist(g_med_sp)/(M*N);
-
bar(
0:
1/
255:
1,h);
-
axis([
-.1
1.1
0
0.55]),grid;
-
axis square;
-
xlabel(
'l).The histogram of i)');
-
ylabel(
'Number of pixels');
-
-
-
%% -------------lines Filters-----------------
-
w_1 = [
1
2
1;
-
2
4
2;
-
1
2
1]/
16; %%%%%
-
g_ave_wg = imfilter(g_gaussian,w_1,
'conv',
'symmetric',
'same');
-
g_ave_sp = imfilter(g_salt_pepper,w_1,
'conv',
'symmetric',
'same');
-
-
figure(
4);
-
subplot(
1,
2,
1);
-
imshow(g_ave_wg,[
0
1]);
-
xlabel(
'g).Result of weighted average filter');
-
-
subplot(
1,
2,
2);
-
h = imhist(g_ave_wg)/(M*N);
-
bar(
0:
1/
255:
1,h);
-
axis([
-.1
1.1
0
0.05]),grid;
-
axis square;
-
xlabel(
'h).The histogram of k)');
-
ylabel(
'Number of pixels');
-
-
-
figure(
7);
-
subplot(
1,
2,
1);
-
imshow(g_ave_sp,[
0
1]);
-
xlabel(
'm).Result of weighted average filter');
-
-
subplot(
1,
2,
2);
-
h = imhist(g_ave_sp)/(M*N);
-
bar(
0:
1/
255:
1,h);
-
axis([
-.1
1.1
0
0.55]),grid;
-
axis square;
-
xlabel(
'n).The histogram of m)');
-
ylabel(
'Number of pixels');
-
close all;
-
clear all;
-
-
%% -------------Sharpening Spatial Filters-----------------
-
f = imread(
'blurry_moon.tif');
-
f = mat2gray(f,[
0
255]);
-
-
w_L = [
0
1
0
-
1 -
4
1
-
0
1
0];
-
g_L_whitout = imfilter(f,w_L,
'conv',
'symmetric',
'same');
-
g_L = mat2gray(g_L_whitout);
-
g = f - g_L_whitout;
-
g = mat2gray(g ,[
0
1]);
-
-
figure();
-
subplot(
1,
2,
1);
-
imshow(f,[
0
1]);
-
xlabel(
'a).Original Image');
-
-
subplot(
1,
2,
2);
-
imshow(g_L_whitout,[
0
1]);
-
xlabel(
'b).The Laplacian');
-
-
figure();
-
subplot(
1,
2,
1);
-
imshow(g_L,[
0
1]);
-
xlabel(
'c).The Laplacian with scaling');
-
-
subplot(
1,
2,
2);
-
imshow(g,[
0
1]);
-
xlabel(
'd).Result Image');
-
-
%% ------------------------
-
[M,N] = size(f);
-
[H,w1,w2] = freqz2(w_L,N,M);
-
figure();
-
subplot(
1,
2,
1);
-
mesh(w1(
1:
10:N)*pi,w2(
1:
10:M)*pi,
abs(H(
1:
10:M,
1:
10:N)));
-
axis([-pi pi -pi pi
0
12]);
-
xlabel(
'\omega_1 [rad]');ylabel(
'\omega_2 [rad]');
-
zlabel(
'|H(e^{j\omega_1},e^{j\omega_2})|');
-
-
-
%figure();
-
subplot(
1,
2,
2);
-
mesh(w1(
1:
10:N)*pi,w2(
1:
10:M)*pi,unwrap(angle(H(
1:
10:M,
1:
10:N))));
-
axis([-pi pi -pi pi -pi pi]);
-
xlabel(
'\omega_1 [rad]');ylabel(
'\omega_2 [rad]');
-
zlabel(
'\theta [rad]');
-
close all;
-
clear all;
-
-
%% -------------Unsharp Masking
and Highboots Filtering-----------------
-
close all;
-
clear all;
-
-
f = imread(
'dipxe_text.tif');
-
f = mat2gray(f,[
0
255]);
-
-
w_Gaussian = fspecial(
'gaussian',[
3,
3],
1);
-
g_Gaussian = imfilter(f,w_Gaussian,
'conv',
'symmetric',
'same');
-
-
g_mask = f - g_Gaussian;
-
-
g_Unsharp = f + g_mask;
-
g_hb = f + (
4.5 * g_mask);
-
f = mat2gray(f,[
0
1]);
-
-
figure();
-
subplot(
2,
2,
1);
-
imshow(f,[
0
1]);
-
xlabel(
'a).Original Image');
-
-
subplot(
2,
2,
2);
-
imshow(g_Gaussian,[
0
1]);
-
xlabel(
'b).Result of Gaussian Filter');
-
-
subplot(
2,
2,
3);
-
imshow(mat2gray(g_mask),[
0
1]);
-
xlabel(
'a).Unsharp Mask');
-
-
subplot(
2,
2,
4);
-
imshow(g_hb,[
0
1]);
-
xlabel(
'b).Result of Highboots Filter');
-
-
-
%%
-
[M,N] = size(f);
-
-
figure();
-
%subplot(
1,
2,
1);
-
plot(
1:N,f(
77,
1:N),
'r');
-
axis([
1,N,
0,
1]),grid;
-
axis square;
-
xlabel(
'a).Original Image(77th column)');
-
ylabel(
'intensity level');
-
-
figure();
-
%subplot(
1,
2,
2);
-
plot(
1:N,f(
77,
1:N),
'r',
1:N,g_Gaussian(
77,
1:N),
'--b');
-
legend(
'Original',
'Result');
-
axis([
1,N,
0,
1]),grid;
-
axis square;
-
xlabel(
'b).Result of gaussian filter(77th column)');
-
ylabel(
'intensity level');
-
-
figure();
-
%subplot(
1,
2,
1);
-
plot(
1:N,g_mask(
77,
1:N));
-
axis([
1,N,-.
1,.
1]),grid;
-
axis square;
-
xlabel(
'c).Result of gaussian filter (77th column)');
-
ylabel(
'intensity level');
-
-
figure();
-
%subplot(
1,
2,
2);
-
plot(
1:N,g_hb(
77,
1:N));
-
axis([
1,N,
0,
1.1]),grid;
-
axis square;
-
xlabel(
'd).Result of Highboots Filtering(77th column)');
-
ylabel(
'intensity level');
-
close all;
-
clear all;
-
-
%% -------------The Gradient-----------------
-
f = imread(
'contact_lens_original.tif');
-
f = mat2gray(f,[
0
255]);
-
-
sobel_x = [-
1 -
2 -
1;
-
0
0
0;
-
1
2
1];
-
sobel_y = [-
1
0
1;
-
-
2
0
2;
-
-
1
0
1];
-
-
g_x =
abs(imfilter(f,sobel_x,
'conv',
'symmetric',
'same'));
-
g_y =
abs(imfilter(f,sobel_y,
'conv',
'symmetric',
'same'));
-
g_sobel = g_x + g_y;
-
-
figure();
-
subplot(
1,
2,
1);
-
imshow(f,[
0
1]);
-
xlabel(
'a).Original Image');
-
-
subplot(
1,
2,
2);
-
imshow(g_sobel,[
0
1]);
-
xlabel(
'b).Result of Sobel Operators');
-
-
figure();
-
subplot(
1,
2,
1);
-
imshow(g_x,[
0
1]);
-
xlabel(
'c).Result of Sx');
-
-
subplot(
1,
2,
2);
-
imshow(g_y,[
0
1]);
-
xlabel(
'd).Result of Sy');
-
-
-
%% ------------------------
-
M =
64;
-
N =
64;
-
[H,w1,w2] = freqz2(sobel_x,N,M);
-
figure();
-
subplot(
1,
2,
1);
-
mesh(w1(
1:N)*pi,w2(
1:M)*pi,
abs(H(
1:M,
1:N)));
-
axis([-pi pi -pi pi
0
12]);
-
xlabel(
'\omega_1 [rad]');ylabel(
'\omega_2 [rad]');
-
zlabel(
'|H(e^{j\omega_1},e^{j\omega_2})|');
-
-
-
%figure();
-
subplot(
1,
2,
2);
-
mesh(w1(
1:N)*pi,w2(
1:M)*pi,unwrap(angle(H(
1:M,
1:N))));
-
axis([-pi pi -pi pi -pi pi]);
-
xlabel(
'\omega_1 [rad]');ylabel(
'\omega_2 [rad]');
-
zlabel(
'\theta [rad]');
-
-
-
[H,w1,w2] = freqz2(sobel_y,N,M);
-
figure();
-
subplot(
1,
2,
1);
-
mesh(w1(
1:N)*pi,w2(
1:M)*pi,
abs(H(
1:M,
1:N)));
-
axis([-pi pi -pi pi -
12
12]);
-
xlabel(
'\omega_1 [rad]');ylabel(
'\omega_2 [rad]');
-
zlabel(
'|H(e^{j\omega_1},e^{j\omega_2})|');
-
-
%figure();
-
subplot(
1,
2,
2);
-
mesh(w1(
1:N)*pi,w2(
1:M)*pi,unwrap(angle(H(
1:M,
1:N))));
-
axis([-pi pi -pi pi -pi pi]);
-
xlabel(
'\omega_1 [rad]');ylabel(
'\omega_2 [rad]');
-
zlabel(
'\theta [rad]');