很多情况下,使用领域像素的非线性滤波会得到更好的效果,如在噪声是散粒噪声而不是高斯噪声,即图像偶尔会出现很大值时,高斯滤波效果不如中值滤波
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的奇数
1.双边滤波:一种非线性滤波方法,图像的空间邻近度和像素值相似度的折中,同时考虑空域信息和灰度相似性,达到保边去噪的目的,具有简单、非迭代、局部特点
2.优点:基于空间分布的高斯滤波函数,较远像素不会太影响边缘像素,保证了边缘保存(edge-preserving)
3.缺点:由于保存了过多高频信息,对彩色图像里的高频噪声不能很好过滤,只能对低频信息较好滤波
4.滤波原理:输出像素依赖于邻域像素值的加权值组合:
加权系数w(i,j,k,l)取决于定义域核和值域核乘积
定义域核:
值域核:
两者相乘后,会产生依赖于数据的双边滤波权重函数
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)用于推断图像外部像素的某种边界模式
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);
}