概念理解:对于传统的维纳滤波和高斯滤波,都只是在像素点邻域范围内进行卷积操作,而双边滤波又加入了像素点差值的限制,这样对于边缘点像素变化很大的地方,便不会受到滤波影响了,也就达到了保存边缘的滤波效果。
代码:
void bilateralBlur(IplImage* input_img, IplImage* output_img, int sigmaS, int sigmaR)
{
// Create Gaussian/Bilateral filter --- mask ---
int length = 9;
std::vector<float> mask(length);
for (int i = 0; i < length; i++)
{
mask[i] = exp(-0.5*((i*i)/(sigmaS*sigmaS)));
//fprintf( stderr, "i = %d, value= %f \n", i, mask[i]);
}
int m_width = input_img->width ;
int m_height= input_img->height ; //ImageData
uchar* src_img= (uchar*) input_img->imageData ; //Ausgangs bild ist genau so groß wie das Eingangsbild!
uchar* dst_img =(uchar*) output_img->imageData ;
double wp = 0.0, k = 0.0;
//evtl. mit y=-length/2; y<=m_height-length/2; y+=4
for(int y=0; y<m_height; y+=1)
{
for (int x=0; x<m_width; x+=1)
{
int centerPix =x + y*m_width;
for (int j=-length/2;j <=length/2;j+=1)
{
for (int i=-length/2;i<=length/2;i+=1)
{
int curPix = x+i+(y+j)*(m_width);
//spatial diff
double delta = sqrt(double(i*i+j*j));
double euklidDiff=exp(-0.5 * pow(delta/sigmaS,2));
double intens = src_img[centerPix]-src_img[curPix];
double factor = exp(-0.5 * pow(intens/sigmaR,2)) * euklidDiff;
wp += factor * src_img[curPix];
k += factor;
}
}
dst_img[centerPix] = wp/k;
wp=0.0;
k=0.0;
}
}
}