双边滤波
2015-05-19 22:15
696 查看
双边滤波是一种可以保边去噪的滤波器。之所以可以达到这样的效果,是因为该滤波器是由两个函数构成,一个函数是由几何空间距离决定滤波器系数,另外一个由像素差决定滤波器系数。
在前面几种讲述的滤波方法中,像素点的灰度值均是由该点邻域内其他点的灰度值决定的,比如高斯滤波和均值滤波都可看作是加权平均,中值滤波取的是邻域灰度中值。双边滤波则不但考虑邻域范围内点的灰度值,同样考虑这些点距离中心点的几何距离,这样可以得到滤波后的点的灰度值表达公式为:
其中k为归一化系数,其表达式为:
h和x分别为滤波后和滤波前对应点的灰度值;
c表示中心点与其邻域内点的空间相似度;
s表示中心点与其邻域内点的灰度相似度。
在实现过程中,c和s函数均可用高斯函数实现,即其定义如下:
可根据以上原理实现双边滤波如下。
Void BilateralFilter(CvMat *pGrayMat, CvMat *pFilterMat, int nWidth, int nHeight, double dSigma1, double dSigma2, int nWindows)
{
////////////////////////参数说明///////////////////////////////////
//pGrayMat:待处理图像数组
//pFilterMat:保存高斯滤波结果
//nWidth:图像宽度
//nHeight:图像高度
//dSigma1、dSigma2:分别为几何与灰度相关高斯函数的方差
double* dDistance = new double[nWindows*nWindows]; //计算距离中间点的几何距离
double* dGrayDiff = new double[nWindows*nWindows]; //定义中心点到当前点的灰度差
for(int i=0; i<nWindows*nWindows; i++)
{
int nNumX = i/nWindows;
int nNumY = i%nWindows;
dDistance[i] = ((nWindows-1)/2-nNumX)*((nWindows-1)/2-nNumX)+((nWindows-1)/2-nNumY)*((nWindows-1)/2-nNumY);
dDistance[i] = exp(-0.5*dDistance[i]/dSigma1/dSigma1); //C参数
}
//以下求解灰度值的差
for(i=0; i<nHeight; i++)
{
for(int j=0; j<nWidth; j++)
{
double dGray = cvmGet(pGrayMat, i, j); //当前点的灰度值
double dData = 0.0;
double dTotal = 0.0; //用于进行归一化
for(int m=0; m<nWindows*nWindows; m++)
{
int nNumX = m/nWindows; //行索引
int nNumY = m%nWindows; //列索引
int nX = i-(nWindows-1)/2+nNumX;
int nY = j-(nWindows-1)/2+nNumY;
if( (nY>=0) && (nY<nWidth) && (nX>=0) && (nX<nHeight))
{
double dGray1 = cvmGet(pGrayMat, nX, nY);
dGrayDiff[m] = fabs(dGray-dGray1);
dGrayDiff[m] = exp(-0.5*dGrayDiff[m]*dGrayDiff[m]/dSigma2/dSigma2); //S参数
if(m!=4)
{
dData += dGray1 * dGrayDiff[m] * dDistance[m]; //C和S参数综合
dTotal += dGrayDiff[m]*dDistance[m]; //加权系数求和,进行归一化
}
}
}
dData /=dTotal;
cvmSet(pFilterMat, i, j, dData);
}
}
delete[]dDistance;
delete[]dGrayDiff;
}
在前面几种讲述的滤波方法中,像素点的灰度值均是由该点邻域内其他点的灰度值决定的,比如高斯滤波和均值滤波都可看作是加权平均,中值滤波取的是邻域灰度中值。双边滤波则不但考虑邻域范围内点的灰度值,同样考虑这些点距离中心点的几何距离,这样可以得到滤波后的点的灰度值表达公式为:
其中k为归一化系数,其表达式为:
h和x分别为滤波后和滤波前对应点的灰度值;
c表示中心点与其邻域内点的空间相似度;
s表示中心点与其邻域内点的灰度相似度。
在实现过程中,c和s函数均可用高斯函数实现,即其定义如下:
可根据以上原理实现双边滤波如下。
Void BilateralFilter(CvMat *pGrayMat, CvMat *pFilterMat, int nWidth, int nHeight, double dSigma1, double dSigma2, int nWindows)
{
////////////////////////参数说明///////////////////////////////////
//pGrayMat:待处理图像数组
//pFilterMat:保存高斯滤波结果
//nWidth:图像宽度
//nHeight:图像高度
//dSigma1、dSigma2:分别为几何与灰度相关高斯函数的方差
double* dDistance = new double[nWindows*nWindows]; //计算距离中间点的几何距离
double* dGrayDiff = new double[nWindows*nWindows]; //定义中心点到当前点的灰度差
for(int i=0; i<nWindows*nWindows; i++)
{
int nNumX = i/nWindows;
int nNumY = i%nWindows;
dDistance[i] = ((nWindows-1)/2-nNumX)*((nWindows-1)/2-nNumX)+((nWindows-1)/2-nNumY)*((nWindows-1)/2-nNumY);
dDistance[i] = exp(-0.5*dDistance[i]/dSigma1/dSigma1); //C参数
}
//以下求解灰度值的差
for(i=0; i<nHeight; i++)
{
for(int j=0; j<nWidth; j++)
{
double dGray = cvmGet(pGrayMat, i, j); //当前点的灰度值
double dData = 0.0;
double dTotal = 0.0; //用于进行归一化
for(int m=0; m<nWindows*nWindows; m++)
{
int nNumX = m/nWindows; //行索引
int nNumY = m%nWindows; //列索引
int nX = i-(nWindows-1)/2+nNumX;
int nY = j-(nWindows-1)/2+nNumY;
if( (nY>=0) && (nY<nWidth) && (nX>=0) && (nX<nHeight))
{
double dGray1 = cvmGet(pGrayMat, nX, nY);
dGrayDiff[m] = fabs(dGray-dGray1);
dGrayDiff[m] = exp(-0.5*dGrayDiff[m]*dGrayDiff[m]/dSigma2/dSigma2); //S参数
if(m!=4)
{
dData += dGray1 * dGrayDiff[m] * dDistance[m]; //C和S参数综合
dTotal += dGrayDiff[m]*dDistance[m]; //加权系数求和,进行归一化
}
}
}
dData /=dTotal;
cvmSet(pFilterMat, i, j, dData);
}
}
delete[]dDistance;
delete[]dGrayDiff;
}
相关文章推荐
- 高斯(Gaussian)滤波、中值(Median)滤波与双边(Bilateral)滤波的特点
- opencv----滤波函数:方框滤波、均值滤波、高斯滤波、中值滤波、双边滤波
- 图像去噪之双边滤波(Bilateral filter)
- [学习opencv]高斯、中值、均值、双边滤波
- 双边滤波
- 【OpenCV】邻域滤波:方框、高斯、中值、双边滤波
- 高斯、中值、均值、双边滤波
- 【OpenCV】邻域滤波:方框、高斯、中值、双边滤波
- 【OpenCV】邻域滤波:方框、高斯、中值、双边滤波
- 非线性滤波:中值、双边滤波
- 双边滤波与引导滤波
- Bilateral Filtering(双边滤波)算法研究
- 双边滤波与引导滤波
- 方框滤波,高斯滤波,中值滤波,双边滤波,opencv实现
- 图像滤波---双边滤波和引导滤波的基本原理
- 双边滤波原理理解
- 数字图像处理之均值滤波,高斯滤波,中值滤波,双边滤波
- 双边滤波
- 【OpenCV】邻域滤波:方框、高斯、中值、双边滤波
- 【OpenCV】邻域滤波:方框、高斯、中值、双边滤波