图像算法之双边滤波器(灰度图像)

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、效果图

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值