zoukankan      html  css  js  c++  java
  • 双边滤波器、高斯滤波

    双边滤波(Bilateral filter)是一种非线性的滤波方法,是结合图像的空间邻近度和像素值相似度的一种折衷处理,同时考虑空域信息和灰度相似性,达到保边去噪的目的。普通的高斯滤波会将图像的边缘模糊掉,而双边滤波器具有保边特性。

    一般的高斯模糊在进行采样时主要考虑了像素间的空间距离关系,但是却并没有考虑像素值之间的相似程度,因此这样我们得到的模糊结果通常是整张图片一团模糊。Bilateral blur的改进就在于在采样时不仅考虑像素在空间距离上的关系,同时加入了像素间的相似程度考虑,因而可以保持原始图像的大体分块进而保持边缘。

    下面先讲高斯滤波,明白的同学请直接跳过。

    高斯滤波

    在2D高斯滤波中的具体实现就是对周围的一定范围内的像素值分别赋以不同的高斯权重值,并在加权平均后得到当前点的最终结果。而这里的高斯权重因子是利用两个像素之间的空间距离(在图像中为2D)关系来生成。通过高斯分布的曲线可以发现,离目标像素越近的点对最终结果的贡献越大,反之则越小。

    高斯核函数一种最常用的径向基函数,形式为



    其中xc为核函数中心,σ为函数的宽度参数 , 控制了函数的径向作用范围。所谓径向基函数 (Radial Basis Function 简称 RBF), 就是某种沿径向对称的标量函数 通常定义为空间中任一点x到某一中心xc之间欧氏距离的单调函数 , 可记作 k(||x-xc||), 其作用往往是局部的 , 即当x远离xc时函数取值很小。
        高斯函数具有五个重要的性质,这些性质使得它在早期图像处理中特别有用.这些性质表明,高斯平滑滤波器无论在空间域还是在频率域都是十分有效的低通滤波器,且在实际图像处理中得到了工程人员的有效使用.高斯函数具有五个十分重要的性质,它们是:
    (1)二维高斯函数具有旋转对称性,即滤波器在各个方向上的平滑程度是相同的.一般来说,一幅图像的边缘方向是事先不知道的,因此,在滤波前是无法确定一个方向上比另一方向上需要更多的平滑.旋转对称性意味着高斯平滑滤波器在后续边缘检测中不会偏向任一方向.
    (2)高斯函数是单值函数.这表明,高斯滤波器用像素邻域的加权均值来

    代替该点的像素值,而每一邻域像素点权值是随该点与中心点的距离单调增减的.这一性质是很重要的,因为边缘是一种图像局部特征,如果平滑运算对离算子中心很远的像素点仍然有很大作用,则平滑运算会使图像失真.

    (3)高斯函数的付立叶变换频谱是单瓣的.正如下面所示,这一性质是高斯函数付立叶变换等于高斯函数本身这一事实的直接推论.图像常被不希望的高频信号所污染(噪声和细纹理).而所希望的图像特征(如边缘),既含有低频分量,又含有高频分量.高斯函数付立叶变换的单瓣意味着平滑图像不会被不需要的高频信号所污染,同时保留了大部分所需信号.

    (4)高斯滤波器宽度(决定着平滑程度)是由参数σ表征的,而且σ和平滑程度的关系是非常简单的.σ越大,高斯滤波器的频带就越宽,平滑程度就越好.通过调节平滑程度参数σ,可在图像特征过分模糊(过平滑)与平滑图像中由于噪声和细纹理所引起的过多的不希望突变量(欠平滑)之间取得折衷.

    (5)由于高斯函数的可分离性,大高斯滤波器可以得以有效地实现.二维高斯函数卷积可以分两步来进行,首先将图像与一维高斯函数进行卷积,然后将卷积结果与方向垂直的相同一维高斯函数卷积.因此,二维高斯滤波的计算量随滤波模板宽度成线性增长而不是成平方增长.

    高斯滤波的问题

    高斯滤波没有考虑图像的边缘,会将边缘模糊掉。因为高斯核只考虑了空间分布,没有考虑到像素值的差异。图像的边缘往往是图像灰度剧烈变化的地方。所以可以综合考虑图像灰度因素。

    双边滤波器原理

    双边滤波方法(Bilateral filtering)是基于Gauss 滤波方法提出的,主要是针对Gauss 滤波中将Gauss 权系数直接与图像信息作卷积运算进行图像滤波的原理,将滤波权系数优化成Gauss 函数和图像亮度信息的乘积,优化后的权系数再与图像信息作卷积运算,这样就能在滤波的同时考虑到图像信息中的图像边缘信息,使图像在正常Gauss 滤波后很模糊的边缘信息得以保持清晰,并且图像边缘更加平滑。此方法对于彩色和灰度图像的滤波均适用,具有很强的实用性。
    设原图为f(x,y),(x,y)为像素的坐标,双边滤波后(x,y)点的像素值变为

    公式中Sx,y 表示中心点(x,y)的(2N+1)*(2N+1)大小的领域。实际上,公式右边就是中心像素点邻域内像素亮度值的加权平均。
    权值W由两部分组成


    W(i,j)=Ws(i,j)*Wr(i,j)
    双边滤波器的加权系数是这两部分因子的非线性组合,空间邻近度因子Ws和亮度相似度因子Wr的乘积。前者随着像素点与中心点之间欧几里德距离的增加而减小,后者随着两像素亮度值之差的增大而减小。在图像变化平缓的区域,邻域内像素亮度值相差不大,双边滤波转化为高斯低通滤波器;在图像变化剧烈的区域,滤波器利用边缘点附近亮度值相近的像素点的亮度值平均代替原亮度值。因此,双边滤波器既平滑滤波了图像,又保持了图像的边缘。双边滤波器受3个参数的控制:滤波器半宽N、参数δs和δr。N越大,平滑作用越强;δs和δr分别控制着空间邻近度因子Ws和亮度像似度因子Wr的衰减程度。


    #define  MAX_IMAGE_SIZE 1024
    double d[MAX_IMAGE_SIZE][MAX_IMAGE_SIZE];//d[i][j]表示入图像,fi][j]表示出图像。
    double f[MAX_IMAGE_SIZE][MAX_IMAGE_SIZE];
    void CImageColorProcess::Bilateral(LPBYTE lpSrc, LPBYTE lpDst, int nSrcCount, int nW, int nH)
    {
    	int i, j, k, l;
    	int p = 5;//p决定模板大小。当p=1时,模板为3*3;当p=2时,模板为5*5;当p=n时,模板为(2n+1)*(2n+1)。
    	short m, n;
    	double a1 = 0.02, b1 = 0.002;
    	double aa1, bb1;//aa1,bb1为滤波模板中的各权重。
    	//gguiyi高斯滤波的归一化系数,bguiyi双边滤波的归一化系数,gsum高斯滤波像素的加权和,bsum双边滤波像素的加权和。
    	double gguiyi = 0.0, bguiyi = 0.0, gsum = 0.0, bsum = 0.0;
    	int x_size2 = nW;//x_size1;
    	int y_size2 = nH;//y_size1;
    	LPBYTE lpSrc1 = new byte[nW*nH];
    	RGB2Gray(lpSrc, lpSrc1, 24, nW, nH);
    	//将读取的噪声图像赋给入力图像
    	for (i = 0; i < nH; i++)
    	{
    		for (j = 0; j < nW; j++)
    		{
    			d[i][j] = lpSrc1[i*nW + j];
    		}
    	}
    	//高斯滤波,双边滤波处理噪声图像
    	for (i = 0; i < nH; i++)
    	{
    		for (j = 0; j < nW; j++)
    		{
    			for (k = -p; k <= p; k++)
    			{
    				for (l = -p; l <= p; l++)
    				{
    					m = i + k; n = j + l;
    					//abs()返回指定数字的绝对值
    					if (m<0)  { m = abs(i + k) - 1; }   	   
    <span style="font-size: 12px;">                                        </span><span style="font-family: Arial, Helvetica, sans-serif; font-size: 12px;"> if (m>nH - 1) { m = 2 * nH - i - k - 1; }</span>
    					if (n<0)  { n = abs(j + l) - 1; }	  if (n>nW - 1) { n = 2 * nW - j - l - 1; }
    					aa1 = exp(-a1*(l*l + k*k));
    					bb1 = exp(-b1*(d[i][j] - d[m][n])*(d[i][j] - d[m][n]));
    					bsum += aa1*bb1*d[m][n];
    					bguiyi += aa1*bb1;
    				}
    			}
    			f[i][j] = bsum / bguiyi;
    			gguiyi = 0.0, bguiyi = 0.0, gsum = 0.0, bsum = 0.0;
    		}
    	}
    	//将滤波后的像素赋给新的图像
    	for (i = 0; i < nH; i++)
    	{
    		for (j = 0; j < nW; j++)
    		{
    			lpDst[i*nW + j] = (unsigned char)(f[i][j] + 0.5);
    		}
    	}
    
    }

    效果








    以上三图从上到下分别为原图,高斯模糊和双边滤波后的效果图,双边滤波的保边效果还是很明显的。

    版权声明:

  • 相关阅读:
    【转载wpf命令】
    【转载WPF资源】
    【转载MVVM模式的简介】
    【转载有关XmlAttribute的知识】
    【test7】stream、用于输入和输出的类、特性
    【补充作业】XML和LINQ
    CodeVS 1084 乒乓球
    android开发之屏幕旋转
    Android开发之新建项目报错的问题
    Android 开发获取用户权限
  • 原文地址:https://www.cnblogs.com/walccott/p/4957108.html
Copyright © 2011-2022 走看看