《OpenCV3编程入门》学习笔记6 图像处理(二)非线性滤波:中值滤波、双边滤波

第6章 图像处理

6.2 非线性滤波:中值滤波、双边滤波

6.2.1 非线性滤波

很多情况下,使用领域像素的非线性滤波会得到更好的效果,如在噪声是散粒噪声而不是高斯噪声,即图像偶尔会出现很大值时,高斯滤波效果不如中值滤波

6.2.2 中值滤波(medianBlur)

1.滤波原理:基于排序统计理论的一种能有效抑制噪声的非线性信号处理技术,用像素点邻域灰度值的中值替代像素点的灰度值,让周围的像素值接近真实值,从而消除孤立的噪声点,该方法在去除脉冲噪声、斑点噪声(speckle noise)、椒盐噪声(salt-and-pepper noise)的同时又能保留图像的边缘细节。
2.优点:在均值滤波中,由于噪声成份被放入平均计算中,所以输出受到了影响,但在中值滤波中,由于噪声成分很难选上,所以几乎不会影响输出。可克服线性滤波的细节模糊。
3.缺点:中值滤波是均值滤波的5倍以上时间,且不适合细节多的图像
4.取3*3函数窗,计算以点[i,j]为中心的函数窗像素中值,步骤
(1)按强度值大小排列像素点
(2)选择排序像素集的中间值作为点[i,j]的值
5.封装函数:medianBlur函数
6.函数原型

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

7.参数说明
(1)Mat类型输入图像(1/3/4通道),ksize为3或5时,图像深度应为CV_8U、CV_16U、CV_32F之一
(2)目标图像,与输入图像尺寸类型一致,可用srcImage.clone()初始化目标图像
(3)ksize,孔径的线性尺寸(aperture linear size),必须是大于1的奇数

6.2.3 双边滤波(bilateralFilter)

1.双边滤波:一种非线性滤波方法,图像的空间邻近度和像素值相似度的折中,同时考虑空域信息和灰度相似性,达到保边去噪的目的,具有简单、非迭代、局部特点
2.优点:基于空间分布的高斯滤波函数,较远像素不会太影响边缘像素,保证了边缘保存(edge-preserving)
3.缺点:由于保存了过多高频信息,对彩色图像里的高频噪声不能很好过滤,只能对低频信息较好滤波
4.滤波原理:输出像素依赖于邻域像素值的加权值组合:
                在这里插入图片描述
加权系数w(i,j,k,l)取决于定义域核和值域核乘积
定义域核:
                在这里插入图片描述
值域核:
                在这里插入图片描述
           《OpenCV3编程入门》学习笔记6 图像处理(二)非线性滤波:中值滤波、双边滤波_第1张图片
两者相乘后,会产生依赖于数据的双边滤波权重函数
            在这里插入图片描述
5.封装函数:bilateralFilter函数
6.函数原型

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

7.参数说明
(1)输入图像,8位或浮点型单通道、三通道图像
(2)目标图像,与输入图像尺寸类型一致
(3)过滤过程中每个像素邻域的直径,为非正数时,从参数sigmaSpace计算它
(4)颜色空间滤波器的sigma值,值越大表明像素邻域内有越宽广的颜色会被混合到一起,产生较大的半相等颜色区域
(5)坐标空间中滤波器的sigma值,坐标空间的标注方差,值越大,表明越远的像素会相互影响,使更大的区域中足够相似的颜色获取相同颜色。d>0时,d指定了领域大小且与sigmaSpace无关,否则d正比于sigmaSpace
(6)用于推断图像外部像素的某种边界模式

6.2.4 非线性滤波示例

1.两种非线性滤波

#include
#include
#include
#include
using namespace cv;

int main()
{
	//载入原图
	Mat srcImage = imread("love.jpg");

	//显示原图
	namedWindow("中值滤波【原图】");
	imshow("中值滤波【原图】", srcImage);

	//中值滤波
	Mat dstImage1;
	medianBlur(srcImage, dstImage1, 7);
	namedWindow("中值滤波【效果图】");
	imshow("中值滤波【效果图】", dstImage1);

	//双边滤波
	Mat dstImage2;
	bilateralFilter(srcImage, dstImage2, 25, 25 * 2, 25 / 2);
	namedWindow("双边滤波【效果图】");
	imshow("双边滤波【效果图】", dstImage2);

	waitKey(0);
	return 0;
}

2.滑动条控制滤波模糊度

#include
#include
#include
#include
using namespace cv;
using namespace std;
//全局变量
Mat g_srcImage, g_dstImage1, g_dstImage2;
int g_nMedianBlurValue;
int g_nBilateralFilterValue;

//全局函数
static void on_MedianBlur(int, void*);
static void on_BilateralFilter(int, void*);

int main()
{
	//改变控制台字体颜色
	system("color 5E");

	//载入原图
	g_srcImage = imread("love.jpg");
	if (!g_srcImage.data)
	{
		printf("载入原图像失败~!\n");
		return false;
	}

	//复制原图到目标图像
	g_dstImage1 = g_srcImage.clone();
	g_dstImage2 = g_srcImage.clone();
	
	//初始化内核值
	g_nMedianBlurValue = 7;
	g_nBilateralFilterValue = 10;
	
	//显示原图
	namedWindow("非线性滤波【原图】",1);
	imshow("非线性滤波【原图】", g_srcImage);


	//========================【<1>中值滤波】=======================
	//创建窗口
	namedWindow("中值滤波【效果图】",1);
	//创建滑动条
	createTrackbar("内核值:", "中值滤波【效果图】", &g_nMedianBlurValue, 50, on_MedianBlur);
	on_MedianBlur(g_nMedianBlurValue, 0);
	//===============================================================

	//========================【<2>双边滤波】========================
	//创建窗口
	namedWindow("双边滤波【效果图】",1);
	//创建滑动条
	createTrackbar("内核值:", "双边滤波【效果图】", &g_nBilateralFilterValue, 50, on_BilateralFilter);
	on_BilateralFilter(g_nBilateralFilterValue, 0);
	//===============================================================
	
	waitKey(0);
	return 0;
}
static void on_MedianBlur(int, void*)
{
	medianBlur(g_srcImage, g_dstImage1, g_nMedianBlurValue*2+1);
	imshow("中值滤波【效果图】", g_dstImage1);
}
static void on_BilateralFilter(int, void*)
{
	bilateralFilter(g_srcImage, g_dstImage2, g_nBilateralFilterValue, g_nBilateralFilterValue * 2, g_nBilateralFilterValue / 2);
	imshow("双边滤波【效果图】", g_dstImage2);
}

你可能感兴趣的:(OpenCV)