计算机视觉系列教程 (二)卷积与滤波详解

什么是滤波?

要了解什么是滤波,首先要知道什么是波。

图像原本只是一种随时间推移的波形图,也就是图像一开始处于时域状态,而我们并不能从时域图像中看出什么东西(除了一堆突起),而伟大的傅里叶公式让图像从时域中转换到的频域中。

引用一幅图 会看的更加清楚http://blog.jobbole.com/70549/



从这幅图中可以看出来,图像其实是由不同频率的波长组成的,存在着高频部分和低频部分,当然这之间没有明确界限,我们需要知道的是高频部分和低频部分到底代表着什么。


高频部分其实就是代表着这幅图像的边缘信息,也就是锐度。

低频部分刚好相反,代表的是这幅图像的灰度变化信息,也就是内容。

那么我们把高频部分的波称作为高频波,低频部分的则称为低频波。这就是波。


那么什么事滤波呢,顾名思义,就是将某一部分波过滤掉。

什么是卷积?

卷积的运用很广泛,在数据结构中也有相对应 的卷积,而在图像处理中,卷积就更加有用了。

通俗的讲,卷积其实就是加权求和,卷积模板就是权值。


比如 下面这幅图





我们挑选这点(2,2)的周围(3*3)区域作为卷积对象,首先,我们要设定卷积模板(当然模板也要3*3)

首先 我们假定这3*3区域内的灰度值为  (3,3,3;2,2,1;1,2,3);

那么我们假定一个卷积模板为(1,2,1;0,0,0,-1,-2,-1);

则我们做卷积运算,对应加权求和:   sum=1*3+3*2+3*1+0*2+0*2+0*1+(-1)*1+(-2)*2+(-1)*3;

算下来为sum=4;

我们把灰度值4作为(2,2)点的新灰度,就完成了这次卷积运算。很简单是不是。



了解过卷积以后,我们就懂了一个新的名词————滤波器,滤波器就是一个特定的公式导出的一个特定的卷积模板。


高通滤波器


高通滤波器 就是让图像高频波通过,滤掉低频波部分,保留边缘信息。

我们常见的高通滤波器有:sobel,Laplacian等


Sobel算子,就是对图像求导(一阶导数),x方向 y方向对应着两个不同的算子

x方向(1,0,-1;2,0,-2,;1,0,-1);

y方向(1,2,1;0,0,0;-1,-2,-1);


Laplacian算子 这个算子是对图像求二阶导数,就一个算子

(0,1,0;1,-4,1;0,1,0);


为了亮度归一化 算子求和一般为0;


我们写个小程序来试一下效果,首先我们利用自己的算法来实现一下。


首先我们建立一个Laplacian小模板(3*3)的;


 
 
  1. Mat ModelLaplacian(3,3,CV_8SC1);
  2. ModelLaplacian.at< char>( 0, 0)= 0;
  3. ModelLaplacian.at< char>( 0, 1)= 1;
  4. ModelLaplacian.at< char>( 0, 2)= 0;
  5. ModelLaplacian.at< char>( 1, 0)= 1;
  6. ModelLaplacian.at< char>( 1, 1)= -4;
  7. ModelLaplacian.at< char>( 1, 2)= 1;
  8. ModelLaplacian.at< char>( 2, 0)= 0;
  9. ModelLaplacian.at< char>( 2, 1)= 1;
  10. ModelLaplacian.at< char>( 2, 2)= 0;



然后我们对每一个图像点进行加权赋值(注意边界点的处理,可以摄取,也可以利用半模板加权)



 
 
  1. Mat lapimage=Mat(image.rows,image.cols,CV_8UC1);
  2. for ( int i= 1;i<image.rows -1;i++){
  3. for( int j= 1;j<image.cols -1;j++){
  4. int sum= 0; //加权求和
  5. for ( int m= 0;m< 3;m++){
  6. for( int n= 0;n< 3;n++){
  7. sum+=(( int)ModelLaplacian.at< char>(m,n)*( int)image.at<uchar>(i+m -1,j+n -1));
  8. }
  9. }
  10. lapimage.at<uchar>(i,j)=sum;
  11. }
  12. }

这样就完成了整个过程 下面是所有代码:


 
 
  1. #include <iostream>
  2. #include <opencv.hpp>
  3. using namespace cv;
  4. using namespace std;
  5. int main(){
  6. Mat image=imread( "mountain.jpg", 1);
  7. //imshow("result",image);
  8. //waitKey(0);
  9. GaussianBlur(image,image,cvSize( 5, 5), 5, 5); //高斯模糊
  10. cvtColor(image,image,CV_RGB2GRAY);
  11. //cout<<image;
  12. Mat ModelLaplacian(3,3,CV_8SC1);
  13. ModelLaplacian.at< char>( 0, 0)= 0;
  14. ModelLaplacian.at< char>( 0, 1)= 1;
  15. ModelLaplacian.at< char>( 0, 2)= 0;
  16. ModelLaplacian.at< char>( 1, 0)= 1;
  17. ModelLaplacian.at< char>( 1, 1)= -4;
  18. ModelLaplacian.at< char>( 1, 2)= 1;
  19. ModelLaplacian.at< char>( 2, 0)= 0;
  20. ModelLaplacian.at< char>( 2, 1)= 1;
  21. ModelLaplacian.at< char>( 2, 2)= 0;
  22. Mat lapimage=Mat(image.rows,image.cols,CV_8UC1);
  23. for ( int i= 1;i<image.rows -1;i++){
  24. for( int j= 1;j<image.cols -1;j++){
  25. int sum= 0; //加权求和
  26. for ( int m= 0;m< 3;m++){
  27. for( int n= 0;n< 3;n++){
  28. sum+=(( int)ModelLaplacian.at< char>(m,n)*( int)image.at<uchar>(i+m -1,j+n -1));
  29. }
  30. }
  31. lapimage.at<uchar>(i,j)=sum;
  32. }
  33. }
  34. imshow( "result",lapimage);
  35. waitKey( 0);
  36. system( "pause");
  37. return 0;
  38. }

下面是效果:









低通滤波器

低通滤波器就是将高频部分滤掉,保留低频部分,其实就是模糊,降噪。

通常低通滤波器有高斯滤波器等。

高斯滤波就是利用了正态分布方程作为卷积模板的建立方程,所能去除的是高斯噪声。

函数实现起来也很简单 和上面的滤波一样 只是卷积模板要通过高斯方程求解一下而已。

opencvAPI也就一句话 GaussianBlur,这个函数利用了高斯方程的高阶可分离性,将二位的卷积计算转化为两次一维运算,大大减少运行时间。





滤波器的作用


滤波器通常用在预处理图像上,就比如我刚刚想要用拉普拉斯算子做二阶边缘提取,我先是用了高斯模糊去除了高斯噪声,因为拉普拉斯算子对噪声非常敏感,如果不去除高斯噪声将会像下图一样






很乱 很难看 很没有价值 很多时候,一个好的预处理可以将一个算法提高到一个新的效果。滤波就担任着这样的职责!!!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值