如果使用高斯滤波器,如何实现双边滤波器?
答案 0 :(得分:10)
简单的双边滤波器可以定义为
Inew(x,y)=求和(j = yn / 2; j&lt; = y + n / 2)求和(i = xm / 2; j <= x + m / 2)w(i,j,的x,y)I(I,J)
其中常见的低通滤波器,如高斯滤波器,具有权重w(i,j,x,y),基于从内核中心(x,y)到每个像素的距离(i, j)的。对于双边滤波器,权重基于两个距离确定:图像空间距离和颜色空间距离。
下面是一个简单的C实现
void convolution(uchar4 *_in, uchar4 *_out, int width, int height, int ~ halfkernelsize, float id, float cd)
{
int kernelDim = 2*halfkernelsize+1;
for(int y=0; y
float sumWeight = 0;
unsigned int ctrIdx = y*width + x;
float ctrPix[3];
ctrPix[0] = _in[ctrIdx].x;
ctrPix[1] = _in[ctrIdx].y;
ctrPix[2] = _in[ctrIdx].z;
// neighborhood of current pixel
int kernelStartX, kernelEndX, kernelStartY, kernelEndY;
kernelStartX = x-halfkernelsize;
kernelEndX = x+halfkernelsize;
kernelStartY = y-halfkernelsize;
kernelEndY = y+halfkernelsize;
for(int j= kernelStartY; j<= kernelEndY; j++)
{
for(int i= kernelStartX; i<= kernelEndX; i++)
{
unsigned int idx = max(0, min(j, height-1))*width + max(0, min(i,width-1));
float curPix[3];
curPix[0] = _in[idx].x;
curPix[1] = _in[idx].y;
curPix[2] = _in[idx].z;
float currWeight;
// define bilateral filter kernel weights
float imageDist = sqrt( (float)((i-x)*(i-x) + (j-y)*(j-y)) );
float colorDist = sqrt( (float)( (curPix[0] - ctrPix[0])*(curPix[0] - ctrPix[0]) +
(curPix[1] - ctrPix[1])*(curPix[1] - ctrPix[1]) +
(curPix[2] - ctrPix[2])*(curPix[2] - ctrPix[2]) ) );
currWeight = 1.0f/(exp((imageDist/id)*(imageDist/id)*0.5)*exp((colorDist/cd)*(colorDist/cd)*0.5));
sumWeight += currWeight;
_sum[0] += currWeight*curPix[0];
_sum[1] += currWeight*curPix[1];
_sum[2] += currWeight*curPix[2];
}
}
_sum[0] /= sumWeight;
_sum[1] /= sumWeight;
_sum[2] /= sumWeight;
_out[ctrIdx].x = (int)(floor(_sum[0]));
_out[ctrIdx].y = (int)(floor(_sum[1]));
_out[ctrIdx].z = (int)(floor(_sum[2]));
_out[ctrIdx].w = _in[ctrIdx].w;
}
}
}