OpenCV | 图像滤波

版权声明:文章为博主原创,未经同意禁止转载 https://blog.csdn.net/Hello_Peter_Chan/article/details/82121002

总述

图像滤波,即在尽量保留图像细节特征的条件下对目标图像的噪声进行抑制,是图像预处理中不可缺少的操作,其处理效果的好坏将直接影响到后续图像处理和分析的有效性和可靠性。

我们可以通过低通滤波器(LPF),对图像进行模糊处理,去除图像中的高频含量,比如边界和噪声。

OpenCV中有四个主要的图像滤波器,分别是:averaging,Gaussian,median filtering,bilateral filtering,即平均,高斯,中值滤波,双边滤波。

平均

通过二维卷积可以达到平均的目的,我们先给出这样一个核算子:

这里写图片描述

将核算子放在图像的一个像素 A 上,求与核对应的图像上 9(3×3)个像素的和,再取平均数,用这个平均数替代像素 A 的值。重复以上操作直到将图像的每一个像素值都更新一边。

有个很方便的函数可以实现,Imgproc.blur(Mat src, Mat dst, Size ksize),其中src是读取的图像,dst是处理后的图像,ksize是核大小。代码如下:

import org.opencv.imgproc.Imgproc;

Mat src = Imgcodecs.imread("D:\\spiderman.jpg");
if(src.empty()) {
  System.out.println("empty");
  return;
}else {
  System.out.println("Notempty");

  //均值模糊
  Mat aDst = new Mat();
  Imgproc.blur(src,aDst,new Size(15,15));
  Imgcodecs.imwrite("D:\\average.jpg", aDst); 

  return;
}

我们可以看看效果(原图)和(平均):

原图

平均

高斯

把卷积核换成高斯核,方框不变,原来每个方框的值是相等的,现在里面的值是符合高斯分布的,方框中心的值最大,其余方框根据距离中心元素的距离递减,构成一个高斯小山包。

这里写图片描述

这就是说,高斯模糊相对均值模糊的差别就是进行了加权,离中心点越近权重越大。

需要用到一个方法:void GaussianBlur(Mat src, Mat dst, Size ksize, double sigmaX, double sigmaY=0, int borderType=BORDER_DEFAULT ) ;

其中,sigmaX表示高斯核函数在X方向的标准偏差;double sigmaY表示高斯核函数在Y方向的标准偏差。当sigmaY为0时,就将其设为sigmaX;如果两者均为0,则由ksize.withksize.height计算出来。

因此在高斯滤波函数中,ksize.withksize.height均必须是正数和奇数,或0,两者可以不同。

代码如下:

// 高斯模糊
Mat gDst = new Mat();
Imgproc.GaussianBlur(src, gDst, new Size(15,15), 0, 0);
Imgcodecs.imwrite("D:\\gaussian.jpg", gDst); 

需要注意的是,高斯模糊中的Size(width, height)宽度和高度要求为奇数。

效果如下(高斯):

这里写图片描述

我们再对比一下均值模糊跟高斯模糊:

这里写图片描述

这里写图片描述

均值模糊是整体均匀模糊,高斯模糊是中间较周边清晰。

中值滤波

中值使用这个方法:public static void medianBlur(Mat src, Mat dst, int ksize),其中ksize必须是奇数且大于1。

代码如下:

//中值滤波
Mat mDst = new Mat();
Imgproc.medianBlur(src, mDst, 9);
Imgcodecs.imwrite("D:\\median.jpg", mDst); 

结果为:

这里写图片描述

双边滤波

双边滤波能在保持边界清晰的情况下去除噪声,不过速度比较慢。

方法为:public static void bilateralFilter(Mat src, Mat dst, int d, double sigmaColor, double sigmaSpace, [int borderType])

其中,d为过滤过程中每个像素邻域的直径,如果它是负值,则由sigmaSpace参数计算得到。
sigmaColor为颜色空间滤波器的sigma值,这个参数的值越大,就表明该像素邻域内有越宽广的颜色会被混合到一起,产生较大的半相等颜色区域。
sigmaSpace为坐标空间中滤波器的sigma值,坐标空间的标注方差。它的数值越大,意味着越远的像素会相互影响,从而使更大的区域中足够相似的颜色获取相同的颜色;当d>0时,d制定了邻域大小与sigmaSpace无关。否则,d正比于sigmaSpace。

代码如下:

//双边滤波
Mat dDst = new Mat();
Imgproc.bilateralFilter(src, dDst, 15, 15, 15);
Imgcodecs.imwrite("D:\\double.jpg", dDst); 

结果如下:

这里写图片描述

总结

通过上面各个图片的观察,可以知道,均值是模糊得很均匀的;高斯的话则是中间部分比较清晰,周围比较模糊;中值看上去就是一种涂抹的感觉;而双边的话则和原图很接近了,我是没看出来有多大区别的。

猜你喜欢

转载自blog.csdn.net/Hello_Peter_Chan/article/details/82121002