opencv——非线性滤波原理及操作

opencv中最常用的两种非线性滤波为中值滤波和双边滤波

中值滤波——medianBulr

中值滤波很简单,就是某个区域里面的中值,将每一像素点的灰度值设置为该点某邻域窗口内的所有像素点灰度值的中值.。这个区域是一个正方形区域,并且正方形的边长即区域的行数和列数都为奇数。中值对椒盐噪声有很好的抑制作用。
在这里插入图片描述

API

void medianBlur(
    InputArray src,
    OutputArray dst, 
    int ksize
);

(1)InputArray类型的src,输入图像。输入1、3或4通道图像;当ksize为3或5时,图像深度应为 CV_8U、CV_16U或CV_32F,对于较大孔径,它只能是CV_8U。

(2)OutputArray类型的dst,即目标图像,与输入图像有相同的尺寸和类型。

(3)int类型的ksize,光圈线性大小;它必须是奇数且大于1,例如:3、5、7 …。

代码

#include<opencv2\opencv.hpp>
#include<iostream>

using namespace std;
using namespace cv;

int main()
{
    
    
	Mat src, dst;
	src = imread("C:/Users/86176/Pictures/pics/house.jpg");
	if (!src.data)
	{
    
    
		cout << "could not load image !";
		return -1;
	}
	imshow("src", src);

	//中值滤波
	medianBlur(src, dst, 7);
	imshow("medianBlur_src", dst);

	waitKey(0);
	return 0;
}

效果

在这里插入图片描述

双边滤波——bilateralFilter

双边滤波是结合图像的空间邻近度和像素值相似度的一种折中处理,同时考虑空域信息和灰度相似性,达到保边去噪的目的。具有简单、非迭代、局部的特点。双边滤波器的好处是可以做边缘保存,一般过去用的维纳滤波或者高斯滤波去降噪,都会较明显地模糊边缘,对于高频细节的保护效果并不明显。

双边滤波器比高斯滤波多了一个高斯方差sigma-d,它是基于空间分布的高斯滤波函数,所以在边缘附近,离的较远的像素不会太多影响到边缘上的像素值,这样就保证了边缘附近像素值的保存。
但是由于保存了过多的高频信息,对于彩色图像里的高频噪声,双边滤波器不能够干净的滤掉,只能够对于低频信息进行较好的滤波

在这里插入图片描述
中间是空间中图像权重的高斯分布
这幅图由空域核和值域核组成,作为双边滤波的算子

  • 空域核:在空间上来说,图像3 x 3或5 x 5,每个都有权重
  • 值域核:是对像素值来说的,像素值差值在一定范围之内就对他进行模糊,落差过大就不模糊,这样就能够做到保留边缘
  • 所以双边模糊要输入两个参数,一个是空域的窗口大小和值域的窗口大小

总结:

  • 均值模糊无法克服边缘像素信息丢失缺陷。原因是均值滤波是基于平均权重

  • 高斯模糊部分克服了该缺陷,但是无法完全避免,因为没有考虑像素值的不同(可能相邻像素值为0和255)

  • 高斯双边模糊 – 是边缘保留的滤波方法,避免了边缘信息丢失,保留了图像轮廓不变(考虑了相邻像素差值的阈值,就能保留边缘)

API

void bilateralFilter(
    InputArray src, 
    OutputArray dst, 
    int d,
    double sigmaColor, 
    double sigmaSpace,
    int borderType = BORDER_DEFAULT  
);

(1)InputArray类型的src,输入图像。该函数对通道是独立处理的,且可以处理任意通道数的图片,但需要注意,待处理的图片深度应该为CV_8U, CV_16U, CV_16S, CV_32F 以及 CV_64F之一。

(2)OutputArray类型的dst,即目标图像,与输入图像有相同的尺寸和类型。

(3)int类型的d,滤波过程中使用的每个像素邻域的直径。如果是非正的,则从sigmaSpace计算。

(4)double类型的sigmaColor
颜色空间中过滤器sigma。参数值越大,意味着像素邻域(参见sigmaSpace)中的更多颜色将混合在一起,从而产生更大的半等色区域。

(5)double类型的sigmaSpace,在坐标空间中过滤器sigma。参数值越大,意味着更远的像素将相互影响,只要它们的颜色足够接近(参见sigmaColor)。当d大于0时,它指定邻域大小,而不考虑sigmaSpace。否则,d与sigmaSpace成比例。

(6)int类型的borderType,用于在图像外部外推像素的边框模式,具体请参见cv::BorderTypes。

代码

#include<opencv2\opencv.hpp>
#include<iostream>

using namespace std;
using namespace cv;

int main()
{
    
    
	Mat src, dst;
	src = imread("C:/Users/86176/Pictures/pics/house1.jpg");
	if (!src.data)
	{
    
    
		cout << "could not load image !";
		return -1;
	}
	imshow("src", src);

	//双边滤波
	bilateralFilter(src, dst, 15, 150, 3);
	imshow("bilateralFilter_src", dst);


	waitKey(0);
	return 0;
}

效果

在这里插入图片描述
可以看到,对边缘的保留做得很好

猜你喜欢

转载自blog.csdn.net/qq_28258885/article/details/112647155