非线性滤波
图像处理中滤波分线性滤波和非线性滤波两种,其中常见的线性滤波有:方框滤波,中值滤波,高斯滤波等,其主要原理就是每个像素的输出值是输入像素的加权和,所以像素的输入与输出成线性关系。线性滤波器易于构造,并且易于从频域响应角度进行分析。
但很多中情况下,图像的噪声并不是理想状态下的,比如高斯噪声。多数情况下会有散粒噪声的出现,而一般的线性滤波对这种散粒噪声不能剔除,而是将其转化成更为柔和可见的噪声颗粒,但是仍然可见。此时,就需要使用邻近像素的非线性滤波器,来剔除这种非线性噪声。
典型的非线性滤波有中值滤波,双边滤波等。
中值滤波
中值滤波的基本思想是将目标像素点周围的邻域像素的灰度值排序,取中值,然后用该中值替换掉目标像素的灰度值,让目标像素更加接近真实值,该方法在去除椒盐噪声以及脉冲噪声时有很好的表现,同时又能保留图像细节。若目标像素为噪点,其灰度值肯定和其邻域像素的灰度值有很大差别,经过排序后,取到的邻域中值替换掉原像素点,故使原像素点更加接近真实值。但由于中值滤波需要对邻域像素的灰度值进行排序,所以其效率不高,通常是均值滤波所消耗时间的5倍以上。
双边滤波
双边滤波是另一种典型的非线性滤波方法,顾名思义,是双边考虑的一种滤波方式,结合了图像的空间邻近度和像素相似度的一种折中处理,同时考虑空域信息和灰度形似性,达到保边去噪的目的,具有简单、非迭代、局部的特点。
双边滤波器的好处是可以做边缘保存。以往常用维纳滤波或者高斯滤波去噪,但二者都会较明显地模糊边缘,对于高频细节的保护效果并不明显。双边滤波器顾名思义,比高斯滤波多了一个高斯方差simge-d,它是居于空间分布的高斯滤波函数,所以在边缘附近,离得较远的像素不会对边缘上像素影响太多,这样就保证了边缘附近像素值的保存。但是由于保存了过多的高频信息,对彩色图像里的高频噪声,双边滤波器不能够很好的滤掉,只能对低频信息进行较好的滤波。
OpenCV代码实现:
//头文件以及命名空间
#include<opencv2\imgproc\imgproc.hpp>
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\core\core.hpp>
#include<iostream>
using namespace cv;
using namespace std;
//全局函数声明部分
static void g_medianBlur(int, void *);
static void g_bilateralFilter(int, void *);
//全局变量声明部分
Mat srcImage, dstImage4, dstImage5;
int g_nmedianBlurValue = 10;
int g_nbilateralFilterValue = 10;
void main11()
{
system("color 9F");
//读取原始图像
srcImage = imread("1.jpg");
if (!(srcImage.data))
{
cout << "读取图片错误,请检查图片是否存在"<<endl;
return;
}
//创建窗口并显示
namedWindow("【原始图像】");
imshow("【原始图像】", srcImage);
//中值滤波函数
namedWindow("【中值滤波函数】");
createTrackbar("参数值", "【中值滤波函数】", &g_nmedianBlurValue, 50, g_medianBlur); //创建轨迹条
g_medianBlur(g_nmedianBlurValue,0);
//双边滤波
namedWindow("【双边滤波函数】");
createTrackbar("参数值", "【双边滤波函数】", &g_nbilateralFilterValue, 50, g_bilateralFilter);
g_bilateralFilter(g_nbilateralFilterValue,0);
waitKey(0);
}
//中值滤波
static void g_medianBlur(int, void *)
{
dstImage4 = srcImage.clone();
medianBlur(dstImage4, dstImage4, g_nmedianBlurValue*2+1);
imshow("【中值滤波函数】", dstImage4);
}
//双边滤波
static void g_bilateralFilter(int, void *)
{
bilateralFilter(srcImage, dstImage5, g_nbilateralFilterValue, g_nbilateralFilterValue * 2, g_nbilateralFilterValue / 2);
imshow("【双边滤波函数】", dstImage5);
}
本文参考 毛星云《OpenCV3编程入门》