第二章 基本图像处理(Image Processing)

时间:2024-04-16 13:33:49

主要内容:

  1. 图像的表示----介绍图像是如何表示的,以及所有基本操作的作用对象
  2. 高斯滤波-----滤波操作的原理与应用
  3. 图像金字塔-----高斯和拉普拉斯
  4. 边缘检测-----Sobel算子和Laplace算子

 


1、图像的表示

       图像是由一个个的像素表示的,一个图像的像素点可以用 (x,y) 来表示位置,v来表示像素值(灰度图像的话表示一个0~255的值),因此整个图像的表示就是 {(x,y,v)} 像素点的集合。我在之前看很多图像处理的书,基本都是这样介绍的,但是CMU的课件上提出了一个我认为特别好的介绍,是把图像作为一个函数来介绍,f(x,y)=v,函数的自变量为像素点位置,函数值为像素值,画出来的函数图像如下(它把不同的像素值赋予了对应的颜色)。这个表示对后续的边缘检测、特征点获取理解帮助很大。

 

 

      图像的变换基本有两个方面,一是不改变大小,改变像素点的值(即改变函数f(x,y)的值),这个操作是基于像素点的(CMU课件2.0_Point_Processing这一节对此举了不少例子 )。第二种是改变大小和像素值,这种操作一般可以改成描述为两部,第一步更改特定像素的值,第二步,在集合中删除掉部分像素点。(比如高斯图像金字塔)

 

2、高斯滤波

      为什么需要滤波?我的理解是使图像更平滑(或者说更模糊),同时去除掉了一些噪声的干扰,为什么可以做到这样,我的理解是滤波本质上相当于把一个像素的值,跟他周围的像素值紧密联系起来,那么一个干扰点会把他的干扰分散到周围像素上,干扰强度缩小,而其本身受周围像素影响,包含了周围像素的特征,干扰强度更是大大减小,因此干扰项便不存在。

     OK,CMU的课件上来讲了一个均值滤波的例子(CMU课件2.0_Box_Filter)。均值滤波的滤波器是左下这种样子的,滤波操作的公式

               

      滤波操作的基本公式如下:h[m,n]是经过滤波操作之后,(m,n)位置处的像素值,相当于f(m+k,n+l)*g(k,l)的和,k,l是滤波器的大小,g(0,0)是中心位置。均值滤波其实就是把每个像素值,变成已它为中心,绘制1个3*3的矩形,矩形内的所有像素值的平均值。

                                    

 

     除了均值滤波,还有中值滤波比较常见(CMU课件上没写),而且我之前应用比较多,对其颇有好感,中值滤波的原理其实根均值滤波一样,画一个矩阵,但是中值滤波中取的的是像素的中位数,这其实更适合去噪,因为我们噪声一般都是像素值比周围突出的点(这样我们人眼才能看出来他是噪声,如果隐藏在周围像素点,隐藏的比较好,那就不是噪声了),这样中值化后,它就不存在了。然后就是CMU课件中疯狂介绍的高斯滤波。

     为什么是高斯滤波?首先需要明白高斯分布,高中和本科数学都学过正态分布,高斯分布其实就是正态分布,那么正态分布当初的那些性质就适合高斯分布(关于正态分布和高斯分布的介绍请移步  http://blog.****.net/rns521/article/details/6953591)。通过上面的介绍,其实滤波操作就是对像素进行取周围所有像素的加权和,根据经验我们知道距离该像素点越远的点对当前像素影响越小,但是无论中值滤波还是均值滤波均没考虑才到这一点,而一维高斯分布值是通过终将向两端不断减少的,二维高斯分布是向四面八方递减,那么把高斯分布作为滤波器,就可以实现不同距离的像素点的影响不同这一目的。下图左边是二维高斯分布,右边是一维高斯分布(两张图片来源于下述博客,此外关于高斯滤波的滤波矩阵推导见 http://blog.****.net/lonelyrains/article/details/46463987)。

   

    那么高斯滤波有什么作用呢?CMU的课件给出了一个特别有意思的例子,就是去实现一个简单的移轴摄影,就是怎么样把左边的图像变成右边的图像。其实很简单,把第二幅图像中跟第一幅图像一样清晰的像素块取出来,加上第一幅图像中剩余的像素点,做一次高斯滤波。

课件上给出的解决方案:

 

3、图像金字塔

      提出图像金字塔的主要目的是为了压缩图像。比如把一个图像压缩到1/2,可以怎么办?

      高斯金字塔解决方案:1、将原图做一次高斯滤波  2、把做完高斯滤波图像的所有偶数行列全去掉。

      整个方法看上去很不错,但是存在一个问题,怎么还原?我们先复原大小(位置值先用0表示,然后再做一次类似逆滤波的操作),但是这个时候还原回去之后,数据会存在误差。Laplacian金字塔就是把误差保存下来——其实是每次高斯滤波之后丢弃的数据。用代码去实现整个压缩过程如下:

 

for i from 0 to sacle:
     li=blur(fi) #对图像fi做一次滤波
     hi=li-fi #保存丢失信息,Laplacian金字塔
     fi+1=subSample(li)  #更改图像大小

######复原代码
for i for scale to 0:
     li=unSample(fi) #大小复原
     fi+1=li+hi #加上误差

 

4、边缘检测

      什么是边缘?从图像上来说是像素值的分解线,从第一小节中的二维函数图像中来看,就是周围函数值发生突然变化的像素点就是边缘。这样目的就明确了,找到附近函数值变化比较大的点,高中学的导数的定义就是函数的变化率,导数大的地方函数值变化大。问题在于图像函数是无法用表达式表达出来,因此不能用既定的求导公式去计算,在高等数学的极限和中学数学中,我们学过用下面这个公示去近似导数

                                                        

 

      CMU的课件(4.0_Image_Gradients_And_Gradient_Filtering)中列出了下面的一个例子,假设下面这一行数据是某个图像中的x方向一行的像素值,利用近似导数的方法求某个像素点附件的x导数,其实相当于乘以了右侧的过滤器。假设成了多个过滤器,即跟X在同一列上的相邻像素的近似梯度值,这样,如果这个梯度值比较大,其实就相当于这块有一条近似垂直的边界线(y方向)。

         

     图像都是二维的,因此求x方向梯度值大的求出来都是近似垂直的边界,同时需要再利用同样的方法在求一遍y方向的梯度值变化,最后把梯度值转换成灰度值。这就是Sobel算子的原理

     

      在CMU的课件中,还提到了一点,当然也是实际应用中非常重要的一点,Sobel算子对噪声比教敏感,因此需要在处理之前进行去噪(高斯滤波等)。

      在介绍完Sobel算子之后,CMU的课件又介绍了Laplace过滤器。Laplace的原理在于求像素点的二阶导数(实际上是二阶梯度,表达式没有,二阶导数求不出来o(╯□╰)o),二阶导数是对一阶导数求导的结果,二阶导数为0,意味着一阶导数再次取到了极值,一阶导数表示灰度值的变换情况,一阶导数取到了极值,也就是说原图在此灰度值变换巨大。下图是截取自CMU课件中关于Laplace过滤器推倒的过程。

     

  下面这张图展示了图像经过Sobel算子和Laplace过滤器之后的不同,可以看到利用Laplace过滤器的中间为0的这个特性,可以更好的定位边缘。