空间滤波

                          
               

1.空间滤波   

   空间滤波,就是直接在灰度值上,做一些滤波操作。滤波一词,其实来源于频域,将某个频率成分滤除的意思。大部分线性的空间滤波器(比如均值滤波器),是在空间上进行一些灰度值上的操作,这个线性空间滤波器与频域滤波器有一一对应的关系(比如均值滤波器其本质就是低通滤波器),这样会有助于理解这个滤波器的特性。然而,对于非线性的滤波器(比如最大值,最小值和中央值滤波器)的话,则没有这样一个一一对应的关系。

   线性空间滤波所使用的运算是卷积,其计算如下所示。

空间滤波

在执行空间滤波的时候,我们都会使用到这个操作。

      这个式子可能会出现两个问题。这次是在空间域进行操作的,所以上式应该没什么问题。但是,如果换到频域,我们会发现,我们使用的滤波器是非因果的,按照我之前在数字信号处理的那一节,非因果具有零相位特性,但是是不可实现的,因为需要未来的输入。而在这,我们在图像处理的时候,都是一帧一帧的处理,所以,这里非因果性不是问题。而最重要的是,零相位特性不会使得图像变形,这是很重要的。

      还有一个问题就是边界问题,当滤波器的中心靠近图像边缘时候,滤波器的一部分会位于图像外,那么此时,我们通常会采用填0的操作来解决。但是,一些场合,直接填0操作会使得操作后的图像出现黑边。所以,常用的操作还有,①选择距离最近的点填充,②填充的点为圆图像的镜像,③将原图像当做周期信号来填充。


2.几个典型的空间滤波器

      2.1平滑滤波器

      在空间域上考虑,我们所指的平滑滤波器,有平均滤波与加权平均滤波两种形式。

空间滤波

这里很好理解,将滤波器范围内的点,求平均值(或者加权平均值)。这样会使得图像平滑,有助于去掉一些噪声。

      我们将其放到频域去考虑的话,其实这是一个很典型的低通滤波器。这个滤波器会滤掉高频成分,所以可以使得图像平滑。其频率响应如下所示。

空间滤波

3X3平均滤波的频率响应

空间滤波

3X3加权平均滤波的频率响应

       

       首先,对于两个滤波器的振幅特性。平均滤波器的通带要比加权平均滤波器的窄,故使用平均滤波器处理的图像要比加权滤波器处理的图像要模糊一些。

       注意平均滤波器的相位特性,其相位特性并不是一个平面,有的地方的值为π。首先,平均滤波器是一个偶实函数,其频率响应是一个实函数。但是,其频率响应有的部分为负值,这就造成了Matlab的angle()的计算结果为π。其实其还是具有0相位特性的。

       用其处理实际处理图像的话,会得到以下结果。

空间滤波

      看其处理结果,其实很难分辨出有什么区别。所以,加权平均滤波器和平均滤波器的区别,从频率响应来看的话,容易明白一些。本文只是简单的介绍一下均值滤波器,详细的,请参看[数字图像处理]图像去噪初步(1)--均值滤波器


      2.2统计排序滤波器

      统计排序滤波器的运用也广泛,其是很典型的非线性滤波器。主要包括了,最大值滤波器,最小值滤波器,中央值滤波器等等。这里作为代表的,主要说中央值滤波器,中央值滤波对于去除椒盐噪声特别有效。

      所谓中央值滤波器,就是将滤波器范围内的像素的灰度值,进行排序,选出中央值作为这个像素的灰度值。同理可解释最大值滤波器与最小值滤波器。

      我们将一幅图像添加椒盐噪声,然后尝试着用中央值滤波器去除。

空间滤波

空间滤波

从直方图中,可以看出,中央值滤波器对于椒盐噪声,有很好的去噪作用。关于非线性滤波的详细,请参看[数字图像处理]图像去噪初步(2)--非线性滤波器


      2.3锐化滤波器

      使用平均滤波器,可以将图像平滑,其本质是将图像在滤波器范围内求平均值。从频域上来看,平均滤波器是低通滤波器。然而,所谓的锐化,即是将图像的细节强调出来。这里进行了一个假设,假设细节部分是图像高频成分。从这里看来,其实锐化滤波器是与平均滤波器是相反的操作。

      对于一个一次元函数,其一阶微分为

空间滤波

这样的微分被称为向前一次微分,这样的微分会产生一个采样点(针对图像来说,偏移一个像素)的偏移。为了避免这样的偏移,一般将向前一次微分与向后一次微分连用,这样就不会产生一些偏移,如下所示。

空间滤波

现在将其二阶段微分扩展到二次元的图像,如下所示。

空间滤波

将其写成滤波器的形式的话,如下左所示。我们为了强调其微分效果,也可以在斜方向上加上一个微分效果,如下右所示。我们将其称为拉普拉斯算子。

空间滤波

       其频率响应如下所示。

空间滤波

方向的拉普拉斯滤波器的频率响应

空间滤波

八方向的拉普拉斯滤波器的频率响应


      我们可以看出,八方向的拉普拉斯滤波器对于高频成分的强调效果较强。其低频部分最小值为0,这意味着,进行拉普拉斯滤波之后,其实只剩下图像的高频部分了(在空间域里来讲,只剩下边缘部分了)。所以,若用于图像锐化的话,可以将所得结果叠加至原图像,其实也就相当与滤波器的振幅特性往上移动1,保证低频部分不变,强调高频部分。

空间滤波


       2.4高提升滤波

       高提升滤波一般用于使得图片更加清晰。其步骤大致如下,首先将图片模糊化,然后从原图中,将其模糊形式去除。
空间滤波
从而得到图像的反锐化掩蔽,然后用将其叠加至原图上,从而使得图像更清晰。
空间滤波
当k=1的时候,这个操作称为反锐化掩蔽。当k>1时候,这个操作称为高提升滤波。
       其实,高提升滤波也是一种锐化滤波,其强调的也是图像的边缘部分(或者跳变部分)。用以下实验可以加深对高提升滤波的理解。
空间滤波
        得到的结果确实比原图更加的清晰了。为了更深一步理解,我们将第77行的灰度曲线画出来,看看具体啥样的。
        首先是原图的77行与高斯模糊后的77行。
空间滤波空间滤波
然后是原图与模糊后的图像的差,其图像如下所示。
空间滤波
可以看出,边缘部分都凸显出来了,下面,我们将这个部分乘以某个常数,再叠加回原图,就可以得到高提升滤波的结果,如下所示。
空间滤波
      可以看出,字体的边缘部分被强调了。这样会使得字体在感觉上,更加的清晰。 

      2.5 sobel滤波器

      sobel滤波器也是一个常用的滤波器。其原理与锐化滤波器也很像,其运用了一阶微分,使得边缘部分得到保留,滤除了其余的平滑部分。
      现在来分析一下sobel滤波器。纵向看这个滤波器,是一个中心2次式微分运算,这个运算是一个高通滤波器。由此可以确定,sobel滤波器是可以提取图像的边缘。再看纵向,纵向其实是一个加权平均滤波器,这也就说明了,其实sobel滤波器有一定的平滑作用。综上,sobel滤波器是由以下两个滤波器合成的。
       空间滤波
        Sobel滤波器有两个方向,所以,其两个方向的频响如下所示。
空间滤波
空间滤波
       
         sobel滤波器可以抽出图像的边缘部分。从频域上来看,其保留了图像的中部频段部分。
空间滤波

3.参考用代码

  1. close all;
  2. clear all;
  3. %% -------------Smoothing Lines Filters-----------------
  4. f = imread('test_pattern_blurring_orig.tif');
  5. f = mat2gray(f,[0 255]);
  6. w_1 = ones(3)/9;  %%%%%
  7. g_1 = imfilter(f,w_1,'conv','symmetric','same');
  8. w_2 = ones(5)/25;  %%%%%
  9. g_2 = imfilter(f,w_2,'conv','symmetric','same');
  10. w_3 = [1 2 1;
  11.        2 4 2;
  12.        1 2 1]/16;  %%%%%
  13. g_3 = imfilter(f,w_3,'conv','symmetric','same');
  14. figure();
  15. subplot(1,2,1);
  16. imshow(f,[0 1]);
  17. xlabel('a).Original Image');
  18. subplot(1,2,2);
  19. imshow(g_1,[0 1]);
  20. xlabel('b).Average Filter(size 3x3)');
  21. figure();
  22. subplot(1,2,1);
  23. imshow(g_2,[0 1]);
  24. xlabel('c).Average Filter(size 5x5)');
  25. subplot(1,2,2);
  26. imshow(g_3,[0 1]);
  27. xlabel('d).Weighted Average Filter(size 3x3)');
  28. %% ------------------------
  29. M = 64;
  30. N = 64;
  31. [H_1,w1,w2] = freqz2(w_1,M,N);
  32. figure();
  33. subplot(1,2,1);
  34. mesh(w1(1:M)*pi,w2(1:N)*pi,abs(H_1(1:M,1:N)));
  35. axis([-pi pi -pi pi 0 1]);
  36. xlabel('\omega_1 [rad]');ylabel('\omega_2 [rad]');
  37. zlabel('|H(e^{j\omega_1},e^{j\omega_2})|');
  38. %figure();
  39. subplot(1,2,2);
  40. mesh(w1(1:M)*pi,w2(1:N)*pi,unwrap(angle(H_1(1:M,1:N))));
  41. axis([-pi pi -pi pi -pi pi]);
  42. xlabel('\omega_1 [rad]');ylabel('\omega_2 [rad]');
  43. zlabel('\theta [rad]');
  1. close all;
  2. clear all;
  3. %% ----------------Noise type--------------------
  4. f = imread('original_pattern.tif');
  5. f = mat2gray(f,[0 255]);
  6. [M,N] = size(f);
  7. g_gaussian = imnoise(f,'gaussian',0,0.015);
  8. g_salt_pepper = imnoise(f,'salt & pepper',0.15);
  9. figure(1);
  10. subplot(1,2,1);
  11. imshow(f,[0 1]);
  12. xlabel('a).Original Image');
  13. subplot(1,2,2);
  14. h = imhist(f)/(M*N);
  15. bar(0:1/255:1,h);
  16. axis([-0.1 1.1 0 0.55]),grid;
  17. axis square;
  18. xlabel('b).The histogram of original image');
  19. ylabel('Number of pixels');
  20. figure(2);
  21. subplot(1,2,1);
  22. imshow(g_gaussian,[0 1]);
  23. xlabel('c).gaussian noise image');
  24. subplot(1,2,2);
  25. h = imhist(g_gaussian)/(M*N);
  26. bar(0:1/255:1,h);
  27. axis([-.1 1.1 0 0.05]),grid;
  28. axis square;
  29. xlabel('d).The histogram of c)');
  30. ylabel('Number of pixels');
  31. figure(5);
  32. subplot(1,2,1);
  33. imshow(g_salt_pepper,[0 1]);
  34. xlabel('i).salt & pepper noise image');
  35. subplot(1,2,2);
  36. h = imhist(g_salt_pepper)/(M*N);
  37. bar(0:1/255:1,h);
  38. axis([-.1 1.1 0 0.55]),grid;
  39. axis square;
  40. xlabel('j).The histogram of g)');
  41. ylabel('Number of pixels');
  42. %% -------------Nonlines Filters-----------------
  43. g_med_wg = medfilt2(g_gaussian,'symmetric',[3 3]);
  44. g_med_sp = medfilt2(g_salt_pepper,'symmetric',[3 3]);
  45. figure(3);
  46. subplot(1,2,1);
  47. imshow(g_med_wg,[0 1]);
  48. xlabel('e).Result of median filter');
  49. subplot(1,2,2);
  50. h = imhist(g_med_wg)/(M*N);
  51. bar(0:1/255:1,h);
  52. axis([-.1 1.1 0 0.05]),grid;
  53. axis square;
  54. xlabel('f).The histogram of e)');
  55. ylabel('Number of pixels');
  56. figure(6);
  57. subplot(1,2,1);
  58. imshow(g_med_sp,[0 1]);
  59. xlabel('k).Result of median filter');
  60. subplot(1,2,2);
  61. h = imhist(g_med_sp)/(M*N);
  62. bar(0:1/255:1,h);
  63. axis([-.1 1.1 0 0.55]),grid;
  64. axis square;
  65. xlabel('l).The histogram of i)');
  66. ylabel('Number of pixels');
  67. %% -------------lines Filters-----------------
  68. w_1 = [1 2 1;
  69.        2 4 2;
  70.        1 2 1]/16;  %%%%%
  71. g_ave_wg = imfilter(g_gaussian,w_1,'conv','symmetric','same');
  72. g_ave_sp = imfilter(g_salt_pepper,w_1,'conv','symmetric','same');
  73. figure(4);
  74. subplot(1,2,1);
  75. imshow(g_ave_wg,[0 1]);
  76. xlabel('g).Result of weighted average filter');
  77. subplot(1,2,2);
  78. h = imhist(g_ave_wg)/(M*N);
  79. bar(0:1/255:1,h);
  80. axis([-.1 1.1 0 0.05]),grid;
  81. axis square;
  82. xlabel('h).The histogram of k)');
  83. ylabel('Number of pixels');
  84. figure(7);
  85. subplot(1,2,1);
  86. imshow(g_ave_sp,[0 1]);
  87. xlabel('m).Result of weighted average filter');
  88. subplot(1,2,2);
  89. h = imhist(g_ave_sp)/(M*N);
  90. bar(0:1/255:1,h);
  91. axis([-.1 1.1 0 0.55]),grid;
  92. axis square;
  93. xlabel('n).The histogram of m)');
  94. ylabel('Number of pixels');
  1. close all;
  2. clear all;
  3. %% -------------Sharpening Spatial Filters-----------------
  4. f = imread('blurry_moon.tif');
  5. f = mat2gray(f,[0 255]);
  6. w_L = [0  1 0
  7.        1 -4 1
  8.        0  1 0];
  9. g_L_whitout  = imfilter(f,w_L,'conv','symmetric','same');
  10. g_L = mat2gray(g_L_whitout);
  11. g = f - g_L_whitout;
  12. g = mat2gray(g ,[0 1]);
  13. figure();
  14. subplot(1,2,1);
  15. imshow(f,[0 1]);
  16. xlabel('a).Original Image');
  17. subplot(1,2,2);
  18. imshow(g_L_whitout,[0 1]);
  19. xlabel('b).The Laplacian');
  20. figure();
  21. subplot(1,2,1);
  22. imshow(g_L,[0 1]);
  23. xlabel('c).The Laplacian with scaling');
  24. subplot(1,2,2);
  25. imshow(g,[0 1]);
  26. xlabel('d).Result Image');
  27. %% ------------------------
  28. [M,N] = size(f);
  29. [H,w1,w2] = freqz2(w_L,N,M);
  30. figure();
  31. subplot(1,2,1);
  32. mesh(w1(1:10:N)*pi,w2(1:10:M)*pi,abs(H(1:10:M,1:10:N)));
  33. axis([-pi pi -pi pi 0 12]);
  34. xlabel('\omega_1 [rad]');ylabel('\omega_2 [rad]');
  35. zlabel('|H(e^{j\omega_1},e^{j\omega_2})|');
  36. %figure();
  37. subplot(1,2,2);
  38. mesh(w1(1:10:N)*pi,w2(1:10:M)*pi,unwrap(angle(H(1:10:M,1:10:N))));
  39. axis([-pi pi -pi pi -pi pi]);
  40. xlabel('\omega_1 [rad]');ylabel('\omega_2 [rad]');
  41. zlabel('\theta [rad]');
  1. close all;
  2. clear all;
  3. %% -------------Unsharp Masking and Highboots Filtering-----------------
  4. close all;
  5. clear all;
  6. f = imread('dipxe_text.tif');
  7. f = mat2gray(f,[0 255]);
  8. w_Gaussian = fspecial('gaussian',[3,3],1);
  9. g_Gaussian = imfilter(f,w_Gaussian,'conv','symmetric','same');
  10. g_mask = f - g_Gaussian;
  11. g_Unsharp = f + g_mask;
  12. g_hb = f + (4.5 * g_mask);
  13. f = mat2gray(f,[0 1]);
  14. figure();
  15. subplot(2,2,1);
  16. imshow(f,[0 1]);
  17. xlabel('a).Original Image');
  18. subplot(2,2,2);
  19. imshow(g_Gaussian,[0 1]);
  20. xlabel('b).Result of Gaussian Filter');
  21. subplot(2,2,3);
  22. imshow(mat2gray(g_mask),[0 1]);
  23. xlabel('a).Unsharp Mask');
  24. subplot(2,2,4);
  25. imshow(g_hb,[0 1]);
  26. xlabel('b).Result of Highboots Filter');
  27. %%
  28. [M,N] = size(f);
  29. figure();
  30. %subplot(1,2,1);
  31. plot(1:N,f(77,1:N),'r');
  32. axis([1,N,0,1]),grid;
  33. axis square;
  34. xlabel('a).Original Image(77th column)');
  35. ylabel('intensity level');
  36. figure();
  37. %subplot(1,2,2);
  38. plot(1:N,f(77,1:N),'r',1:N,g_Gaussian(77,1:N),'--b');
  39. legend('Original','Result');
  40. axis([1,N,0,1]),grid;
  41. axis square;
  42. xlabel('b).Result of gaussian filter(77th column)');
  43. ylabel('intensity level');
  44. figure();
  45. %subplot(1,2,1);
  46. plot(1:N,g_mask(77,1:N));
  47. axis([1,N,-.1,.1]),grid;
  48. axis square;
  49. xlabel('c).Result of gaussian filter (77th column)');
  50. ylabel('intensity level');
  51. figure();
  52. %subplot(1,2,2);
  53. plot(1:N,g_hb(77,1:N));
  54. axis([1,N,0,1.1]),grid;
  55. axis square;
  56. xlabel('d).Result of Highboots Filtering(77th column)');
  57. ylabel('intensity level');
  1. close all;
  2. clear all;
  3. %% -------------The Gradient-----------------
  4. f = imread('contact_lens_original.tif');
  5. f = mat2gray(f,[0 255]);
  6. sobel_x = [-1 -2 -1;
  7.             0  0  0;
  8.             1  2  1];
  9. sobel_y = [-1  0  1;
  10.            -2  0  2;
  11.            -1  0  1];
  12. g_x = abs(imfilter(f,sobel_x,'conv','symmetric','same'));       
  13. g_y = abs(imfilter(f,sobel_y,'conv','symmetric','same'));  
  14. g_sobel = g_x + g_y;
  15. figure();
  16. subplot(1,2,1);
  17. imshow(f,[0 1]);
  18. xlabel('a).Original Image');
  19. subplot(1,2,2);
  20. imshow(g_sobel,[0 1]);
  21. xlabel('b).Result of Sobel Operators');
  22. figure();
  23. subplot(1,2,1);
  24. imshow(g_x,[0 1]);
  25. xlabel('c).Result of Sx');
  26. subplot(1,2,2);
  27. imshow(g_y,[0 1]);
  28. xlabel('d).Result of Sy');
  29. %% ------------------------
  30. M = 64;
  31. N = 64;
  32. [H,w1,w2] = freqz2(sobel_x,N,M);
  33. figure();
  34. subplot(1,2,1);
  35. mesh(w1(1:N)*pi,w2(1:M)*pi,abs(H(1:M,1:N)));
  36. axis([-pi pi -pi pi 0 12]);
  37. xlabel('\omega_1 [rad]');ylabel('\omega_2 [rad]');
  38. zlabel('|H(e^{j\omega_1},e^{j\omega_2})|');
  39. %figure();
  40. subplot(1,2,2);
  41. mesh(w1(1:N)*pi,w2(1:M)*pi,unwrap(angle(H(1:M,1:N))));
  42. axis([-pi pi -pi pi -pi pi]);
  43. xlabel('\omega_1 [rad]');ylabel('\omega_2 [rad]');
  44. zlabel('\theta [rad]');
  45. [H,w1,w2] = freqz2(sobel_y,N,M);
  46. figure();
  47. subplot(1,2,1);
  48. mesh(w1(1:N)*pi,w2(1:M)*pi,abs(H(1:M,1:N)));
  49. axis([-pi pi -pi pi -12 12]);
  50. xlabel('\omega_1 [rad]');ylabel('\omega_2 [rad]');
  51. zlabel('|H(e^{j\omega_1},e^{j\omega_2})|');
  52. %figure();
  53. subplot(1,2,2);
  54. mesh(w1(1:N)*pi,w2(1:M)*pi,unwrap(angle(H(1:M,1:N))));
  55. axis([-pi pi -pi pi -pi pi]);
  56. xlabel('\omega_1 [rad]');ylabel('\omega_2 [rad]');
  57. zlabel('\theta [rad]');