1、函数定义
// 双边滤波器
struct stPGMImage* BilateralFilter(struct stPGMImage* image, int filterSize, double sigmaD, double sigmaR);
2、函数实现
double** get_space_Array(int _size, int channels, double sigmas)
{
int i, j;
double** _spaceArray = (double**)malloc(sizeof(double*) * (_size + 1));
for (i = 0; i < _size + 1; i++)
_spaceArray[i] = (double*)malloc(sizeof(double) * (_size + 1));
int center_i, center_j;
center_i = center_j = _size / 2;
_spaceArray[_size][0] = 0.0f;
for (i = 0; i < _size; i++)
{
for (j = 0; j < _size; j++)
{
_spaceArray[i][j] =
exp(-(1.0f) * (((i - center_i) * (i - center_i) + (j - center_j) * (j - center_j)) /
(2.0f * sigmas * sigmas)));
_spaceArray[_size][0] += _spaceArray[i][j];
}
}
return _spaceArray;
}
double* get_color_Array(int _size, int channels, double sigmar)
{
int n;
double* _colorArray = (double*)malloc(sizeof(double) * (255 * channels + 2));
double wr = 0.0f;
_colorArray[255 * channels + 1] = 0.0f;
for (n = 0; n < 255 * channels + 1; n++)
{
_colorArray[n] = exp((-1.0f * (n * n)) / (2.0f * sigmar * sigmar));
_colorArray[255 * channels + 1] += _colorArray[n];
}
return _colorArray;
}
struct stPGMImage* Bialteral(struct stPGMImage* image, int _size, double* _colorArray, double** _spaceArray)
{
unsigned int channels = 1;
struct stPGMImage* result = (struct stPGMImage*)malloc(sizeof(struct stPGMImage));
result->height = image->height;
result->width = image->width;
result->maxraw = image->maxraw;
result->data = (unsigned char*)malloc(sizeof(unsigned char) * result->width * result->height * channels);
memcpy(result->data, image->data, image->height * image->width * channels);
for (int i = 0; i < image->height; i++)
{
for (int j = 0; j < image->width; j++)
{
if (i > (_size / 2) - 1 && j > (_size / 2) - 1 &&
i < image->height - (_size / 2) && j < image->width - (_size / 2))
{
double sum = 0.0;
int x, y, values;
double space_color_sum = 0.0f;
for (int k = 0; k < _size; k++)
{
for (int l = 0; l < _size; l++)
{
x = i - k + (_size / 2);
y = j - l + (_size / 2);
values = abs(image->data[i * image->width + j] - image->data[x * image->width + y]);
space_color_sum += (_colorArray[values] * _spaceArray[k][l]);
}
}
for (int k = 0; k < _size; k++)
{
for (int l = 0; l < _size; l++)
{
x = i - k + (_size / 2);
y = j - l + (_size / 2);
values = abs(image->data[i * image->width + j] - image->data[x * image->width + y]);
sum += (image->data[x * image->width + y]
* _colorArray[values]
* _spaceArray[k][l])
/ space_color_sum;
}
}
result->data[i * image->width + j] = (unsigned char)sum;
}
}
}
return result;
}
struct stPGMImage* BilateralFilter(struct stPGMImage* image, int N, double sigmas, double sigmar)
{
unsigned int channels = 1;
struct stPGMImage* result = NULL;
int _size = 2 * N + 1;
double* _colorArray = NULL;
double** _spaceArray = NULL;
_colorArray = get_color_Array(_size, channels, sigmar);
_spaceArray = get_space_Array(_size, channels, sigmas);
result = Bialteral(image, _size, _colorArray, _spaceArray);
for (int i = 0; i < _size; i++)
free((double*)_spaceArray[i]);
free(_colorArray);
free(_spaceArray);
return result;
}
3、效果图