学习OpenCV 09 平滑/模糊处理

学习OpenCV 09 平滑/模糊处理

平滑(smoothing)也称模糊(blurring),是一种简单而又常用的图像处理操作。其目的有很多,但通常是为了减少噪声(noise)和伪影(camera artifacts)。在降低图像分辨率(resolution)时,平滑也是非常重要的。

预备知识

在阐明平滑操作前,需要阐明几个概念:

  1. 滤波器(filter)指的是一种由一幅图像I(x,y)根据像素点(x,y)附近的区域计算得到一幅新图像I'(x,y)的算法。其中模板(template)规定了滤波器的形状及这个区域内像素的组成规律。一般认为滤波器(filter)和核(kernel)描述的是同一个意思,信号处理领域通常用滤波器,数学领域通常用核。
  2. 卷积(convolution),上述滤波操作即I'(x,y)的像素的值由I(x,y)及其周围的像素值加权相加得来,及对于任意形状的核(比如5×5),需要对核内所有的点i.j做加权,然后相加,对于每一对(i,j),将其点乘原图像中相对于像素点(x,y)做一个偏移(i,j)后的像素点的值后相加,由I(x,y)计算I'(x,y)的过程即为卷积。
  3. 锚点(anchor point)定义了核与源图像的对齐关系,即下图加粗的点。
  4. 均值(mean):即数列的平均值。
  5. 中值(median):中值(又称中位数)是指将统计总体当中的各个变量值按大小顺序排列起来,形成一个数列,处于变量数列中间位置的变量值就称为中位数。中值的优点是不受偏大或偏小数据的影响,很多情况下用它代表全体数据的一般水平更合适。如果数列中存在极端变量值,用中位数做代表值就比平均数更好。
  6. cv::Size类,Size(width,height)定义范围大小。

以下是几种典型的核:(均为线性核,故能用如下表示方法)

学习OpenCV 09 平滑/模糊处理_第1张图片

A.5×5盒状盒;B.规范化的5×5盒状核;C.3×3Sobel核;D.5×5规范化高斯核

其中已D高斯核为例,用于计算I'(x,y)的累加项中,一个项就是(41/273)×I(x,y)的结果,同样,(26/273)×I(x-1,y)与(26/273)×I(x+1,y)是其中的另外两项。

经过上述阐述,便可理解卷积的过程可以用下面的方程表示:

 

平滑/模糊处理

OpenCV提供5种不同的平滑操作,这些操作平滑的结果有着细微的差别。

1.简单模糊Simple Blur  与  2.方框型滤波器the Box Filter

void cv::blur(
    cv::InputArray    src,                            //输入图像
    cv::OutputArray   dst,                            //输出图像
    cv::Size          ksize,                          //Kernel(核)的大小        
    cv::Point         anchor=cv::Point(-1,-1),        //锚点坐标
    int               borderType=cv::BORDER_DEFAULT   //使用的边界外推
)

cv::blur()实现简单模糊,目标图像中的每个值都是源图像中相应位置一个核(kernel)中像素的平均值(mean),核的大小尺寸由ksize声明。anchor指定计算时核与源图像的对齐方式,默认为cv::Point(-1,-1),表示核相对于滤波器居中。注:若源图像为多通道图像,则分别对每个通道进行计算。

预备知识中图A其实即为简单模糊,而图B的简单模糊便是方框型滤波器的一种特殊形式,及规范化方框型滤波器。

方框型滤波器(the Box Filter)是一种矩形的并且!滤波器中所有值K(i,j)全部相等的滤波器。通常,所有的K为1或1/A,A为核的面积,当取1/A时,及规范化(normalize)。

void cv::boxFilter(
    cv::InputArray    src,                    //输入图像
    cv::OutputArray   dst,                    //输出图像
    int               ddepth,                 //输出图像的深度,为-1则与源图像一致
    cv::Size          ksize,                  //核的大小尺寸
    cv::Point         anchor=cv::Point(-1,-1),//锚点坐标
    bool              normalize=true,         //如果true,则K=1/A
)

注:简单模糊与方框型滤波器的区别

  1. 简单模糊必须以规范化调用,而方框型滤波器可以非规范化形式调用 
  2. 简单模糊输出图像的深度与源图像保持一致,而方框型滤波器输出图像深度可以控制

3.中值滤波器Median Filter 

中值滤波器将每个像素替换为围绕这个像素的矩形领域内的中值(相对于平均值)或“中值”像素(相对于平均像素)。基于预备知识中均值与中值的理解,不难得出,通过平均的简单模糊或方框型滤波器对噪声图像,尤其是有较大孤立的异常值非常敏感,少量具有较大偏差的点就会严重影响到均值滤波。而中值滤波可以采取中值/中位数的方式来消除异常值。

void cv::medianBlur(
    cv::InputArray    src,     //输入图像
    cv::OutputArray   dst,     //输出图像
    cv::Size          ksize,   //核尺寸
);

注:中值滤波器是一种非线性核,无法用方块图形式表示。

4.高斯滤波器Gaussian Filter

高斯滤波器应该是最有用的一种滤波器。

void cv::GaussianBlur(
    cv::InputArray  src,                          //输入图像
    cv::OutputArray dst,                          //输出图像
    cv::Size        ksize,                        //核大小
    double          sigmaX,                       //高斯核在X方向的sigma值
    double          sigmaY=0.0,                   //高斯核在Y方向的sigma值,默认为0表示与X相等
    int             borderType=cv::BORDER_DEFAULT //边界外扩方式
);

 如果sigmaX和sigmaY都设为0,则高斯参数将根据下列公式确定:

学习OpenCV 09 平滑/模糊处理_第2张图片

注:OpenCV实现的高斯平滑还为几个常用的内核提供性能上的优化。3×3、5×5、7×7的标准sigma核(sigmaX=0.0)相对其他核性能更优。

5.双边滤波器Bilateral Filter

可以把双边滤波当作是高斯平滑,只是相似程序更高的像素权值更高,边缘更明显,对比度更高。

双边滤波的效果就是将源图像变成一幅水彩画,这种效果在多次迭代后更加显著,因此这种方法在图像分割领域十分有用。

void cv::bilateralFilter(
    cv::InputArray    src,                          //输入图像
    cv::OutputArray   dst,                          //输出图像
    int               d,                            //像素邻域的直径
    double            sigmaColor,                   //颜色空间滤波器的sigma值
    double            sigmaSpace,                   //坐标空间滤波器的sigma值
    int               borderType=cv::BORDER_DEFAULT //边界外扩方式
);

其中颜色空间滤波器的sigmaColor值与高斯滤波器中的sigma类似,该值越大,则平滑时所包括的强度(色彩)越大,则图像的不连续性将会更显著。小的sigmaSpace值比如10会带来一个轻微的但也明显的效果,而大的sigmaSpace值比如150会对图像产生非常显著的影响,使图像有种卡通的效果。 

各种滤波及其效果

int main(int argc, char**argv) {
	Size size;
	size.width = 3;
	size.height = 3;
	Point p;
	p.x = -1;
	p.y = -1;
	Mat src = imread("D://somephotos//001.jpg"), dst1, dst2, dst3, dst4, dst5;
	imshow("input", src);
	blur(src, dst1, size, p, BORDER_DEFAULT);
	boxFilter(src, dst2, -1, size, p, true, BORDER_DEFAULT);
	medianBlur(src, dst3, (3,3));
	GaussianBlur(src, dst4, size, 0.0, 0.0, BORDER_DEFAULT);
	bilateralFilter(src, dst5, 3, 0.0, 10);
	imshow("普通模糊", dst1);
	imshow("方框型滤波器", dst2);
	imshow("中值滤波器", dst3);
	imshow("高斯滤波器", dst4);
	imshow("双边滤波器", dst5);
	waitKey(0);
	return 0;
}

 学习OpenCV 09 平滑/模糊处理_第3张图片

 

 

 

 


 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(OpenCV)