Opencv卷积滤波cvFilter2D-高通与低通

时间:2023-02-07 13:43:42

原文: http://blog.sina.com.cn/s/blog_6df50e1a01019z95.html

1.使用模板处理图像相关概念    
   模板:矩阵方块,其数学含义是一种卷积运算。
   卷积运算:可看作是加权求和的过程,使用到的图像区域中的每个像素分别于卷积核(权矩阵)的每个元素对应相乘,所有乘积之和作为区域中心像素的新值。
   卷积核:卷积时使用到的用一个矩阵表示,该矩阵与使用的图像区域大小相同,其行、列都是奇数,是一个权矩阵
   卷积示例:3 * 3 的像素区域R与卷积核G的卷积运算 R5(中心像素)=R1G1 + R2G2 + R3G3 + R4G4 +R5G5 + R6G6 + R7G7 + R8G8 + R9G9
Opencv卷积滤波cvFilter2D-高通与低通

 

2.使用模板处理图像的问题
   边界问题:当处理图像边界像素时,卷积核与图像使用区域不能匹配,卷积核的中心与边界像素点对应,卷积运算将出现问题。
   处理办法:
  A.忽略边界像素,即处理后的图像将丢掉这些像素。
  B.保留原边界像素,即copy边界像素到处理后的图像。

 

3.常用模板

Opencv卷积滤波cvFilter2D-高通与低通

 

4.卷积的概念
   如果你刚刚接触图像处理,或者离开大学很长时间,一看到卷积这个东西,肯定和我一样感到晕菜.那么就复习一下,并且实际的写个程序验证一下,我保证你这辈子不会再忘记卷积的概念了。我们来看一下一维卷积的概念。
   连续空间的卷积定义是 f(x)与g(x)的卷积是 f(t-x)g(x)在t从负无穷到正无穷的积分值。t-x要在f(x)定义域内,所以看上去很大的积分实际上还是在一定范围的
   实际的过程就是f(x)先做一个Y轴的反转,然后再沿X轴平移t就是f(t-x),然后再把g(x)拿来,两者乘积的值再积分.想象一下如果g(x)或者f(x)是个单位的阶越函数。那么就是f(t-x)与g(x)相交部分的面积。这就是卷积了。   

   把积分符号换成求和就是离散空间的卷积定义了。那么在图像中卷积卷积地是什么意思呢?就是图像就是图像f(x),模板是g(x),然后将模版g(x)在模版中移动,每到一个位置,就把f(x)与g(x)的定义域相交的元素进行乘积并且求和,得出新的图像一点,就是被卷积后的图像。模版又称为卷积核。卷积核做一个矩阵的形状。
   卷积定义上是线性系统分析经常用到的。线性系统就是一个系统的输入和输出的关系是线性关系,就是说整个系统可以分解成N多的无关独立变化,整个系统就是这些变化的累加。如 x1->y1, x2->y2;那么A*x1 + B*x2 -> A*y1 + B*y2 这就是线性系统。 表示一个线性系统可以用积分的形式,如Y=Sf(t,x)g(x)dt S表示积分符号,就是f(t,x)表示的是A,B之类的线性系数。
   看上去很像卷积呀。对!如果f(t,x) = F(t-x)不就是了吗。从f(t,x)变成F(t-x)实际上是说明f(t,x)是个线性移不变,就是说,变量的差不变化的时候,那么函数的值不变化。实际上说明一个事情就是说,线性移不变系统的输出可以通过输入和表示系统线性特征的函数卷积得到。


   卷积是图像处理常用的方法,给定输入图像,在输出图像中每一个像素是输入图像中一个小区域中像素的加权平均,其中权值由一个函数定义,这个函数称为卷积核。比如说卷积公式:R(u,v)=∑∑G(u-i,v-j)f(i,j),其中f为输入,G为卷积核。

 

OpenCV对图像做卷积cvFilter2D
voidcvFilter2D( const CvArr* src, CvArr* dst,
                const CvMat* kernel,
                CvPoint anchor=cvPoint(-1,-1));

 

5.OpenCV图像卷积(图像滤波)的程序代码

#include "cv.h"
#include "highgui.h"

int main(intargc,char**argv) 

  IplImage* src, *dst,src_f;  
 
  float low[9] ={ 1.0/16, 2.0/16, 1.0/16,2.0/16, 4.0/16, 2.0/16, 1.0/16, 2.0/16, 1.0/16 };//低通滤波核
  floathigh[9]={-1,-1,-1,-1,9,-1,-1,-1,-1};//高通滤波核

  CvMat km= cvMat( 3, 3, CV_32FC1, low); //构造单通道浮点矩阵,将图像IplImage结构转换为图像数组 

  src =cvLoadImage( "lena.jpg" ); 
  st = cvCreateImage( cvGetSize(src),IPL_DEPTH_8U, 3 );

 cvFilter2D( src, dst, &km, cvPoint( -1, -1 ));  //设参考点为核的中心

 cvNamedWindow( "src", 0 );
  cvNamedWindow( "filtering", 0);

 cvShowImage( "src", src);  
  cvShowImage( "filtering", dst); 

 cvWaitKey(0); 
  cvReleaseImage( &src); 
  cvReleaseImage( &dst); 

  return0; 

 

图像经过低通滤波的结果对比:
Opencv卷积滤波cvFilter2D-高通与低通

图像经过高通滤波的结果对比

Opencv卷积滤波cvFilter2D-高通与低通