在图像处理或者计算机视觉应用中,在正式对图像进行分析处理前一般需要一个预处理的过程。预处理是对图像作一些诸如降维、降噪的操作,主要是为后续处理提供一个体积合适的、只包含所需信息的图像。这里通常会用到一些滤波处理手法。滤波,实际上是信号处理里的一个概念,而图像本身也可以看成是一个二维的信号,其中像素点灰度值的高低代表信号的强弱。对应的高低频的意义:
高频:图像中灰度变化剧烈的点,一般是图像轮廓或者是噪声。
低频:图像中平坦的,灰度变化不大的点,图像中的大部分区域。
根据图像的高频与低频的特征,我们可以设计相应的高通与低通滤波器,高通滤波可以检测图像中尖锐、变化明显的地方;低通滤波可以让图像变得光滑,滤除图像中的噪声。OpenCV中提供的低通滤波有:线性的均值滤波器、高斯滤波器,非线性的双边滤波器、中值滤波器;高通滤波有基于Canny,Sobel等各种边缘滤波。这里大家可以看到低通滤波和高通滤波其实是相互矛盾的,但很多时候在做边缘检测前我们又需要进行低通滤波来降噪,这里就需要调节参数在保证高频的边缘不丢失的前提下尽可能的多去除图片的噪点。
线性滤波器
线性滤波器可以看做是用一个矩阵(滤波器的核)完整扫过源图片得到新图像,其中扫描的方式称为卷积。这里先介绍下核和卷积这两个概念。
核 说白了就是一个固定大小的数值矩阵。该数组带有一个锚点 ,一般位于矩阵中央,如下图的-4。核可以是OpenCV已经定义好的均值滤波器核和高斯滤波器核,也可以自定义核。
卷积 的计算方法其实也很简单:
用公式表示上述过程如下:
下图为例,核锚点在中央,锚点放在源图红色区96的位置,分别相乘后求和,得到92为滤波后图像的值。这里对比结果图和源图,可以发现源图四周一圈的像素点已经丢失了,这里OpenCV提供的函数会自动帮我们补齐周围一圈使得源图和结果图尺寸一样。
知道原理之后,再来看看常用的滤波和如何自定义线性滤波器吧。
均值滤波
blur( src, dst, size, anchor = Point(-1,-1), borderType);
这个滤波是一个平滑图像的滤波器,它用一个点邻域内像素的平均灰度值来代替该点的灰度,看它的核就很容易理解了:
高斯滤波
cv::GaussianBlur(src, dst, cv::Size(5,5), 1.5);
上面的均值滤波的平滑原理是用邻域内的平均值来代替当前的灰度值,但是我们往往希望越靠近该像素的点提供越高的权重,这样就产生了高斯模糊滤波。它的核是一个高斯分布的二维矩阵,中间大,向四周逐渐减小。
自定义线性滤波器
我们还可以自己设计核来完成个性化的滤波需求,根据原理我们也可以自己编程遍历图像像素做卷积求得结果,但更安全方便的方法是使用OpenCV函数 filter2D 创建自己的线性滤波器。
filter2D(src, dst, ddepth , kernel, anchor, delta, BORDER_DEFAULT );
前面的滤波都是模糊处理的,比如现在需要锐化图像,那可以很简单的设置一个核为即可。
非线性滤波
中值滤波
中值滤波将图像的每个像素用邻域 (以当前像素为中心的正方形区域)像素的中值代替。比如上图源图的红色区域里,中值是96,所以结果图中该点的值为96。
非双边滤波
双边滤波是结合图像的空间邻近度和像素值相似度的一种折衷处理,同时考虑空域信息和灰度相似性,达到保边去噪的目的。具有简单、非迭代、局部的特点。这个滤波器相对复杂,具体原理可以看这位学姐的解释。http://blog.csdn.net/abcjennifer/article/details/7616663