高斯滤波是图像处理中最常见的一种滤波方式,高斯滤波能够对图像起到平滑作用,去除部分噪声对图像进一步处理带来的影响,常见的高斯模板一般为3*3或者为5*5,高斯滤波除了模板的大小带来影响外,还有一个正态分布方差sigma也会对高斯滤波起到很大的作用,sigma越大图像越模糊。二维高斯核的表达式为:
/*功能: 二维高斯核生成
//kernel:存储生成的高斯核
//size: 核的大小
//sigma: 正态分布标准差
*/
void get_gau_kernel(float **kernel, int size, float sigma)
{
if (size <= 0 || sigma == 0)
return;
int x, y;
int m = size / 2;
float sum = 0;
//get kernel
for (y = 0; y < size; y++)
{
for (x = 0; x < size; x++)
{
kernel[y][x] = (1 / (2 * PI * sigma * sigma)) * exp(-((x - m) * (x - m) + (y - m) * (y - m)) / (2 * sigma * sigma));
sum += kernel[y][x];
}
}
//normal
for (y = 0; y < size; y++)
{
for (x = 0; x < size; x++)
{
kernel[y][x] /= sum;
}
}
}
/*功能: 高斯模糊
//src: 输入原图
//dst: 模糊图像
//size: 核的大小
//sigma:正态分布标准差
*/
void gaussian(image_t *src, image_t *dst, int size, float sigma)
{
if (src->w == 0 || src->h == 0)
return;
int y, x;
int i, j;
int m = size / 2;
float value;
float **kernel = (float**)malloc(size * sizeof(float*));
for (i = 0; i < size; i++)
kernel[i] = (float*)malloc(size * sizeof(float));
get_gau_kernel(kernel,size,sigma);
float *kernel_vec = (float*)malloc(size * size * sizeof(float));
//kernel二维转为一维
int k = 0;
for (j = 0; j < size; j++)
{
for (i = 0; i < size; i++)
{
kernel_vec[k++] = kernel[j][i];
}
}
uchar *src_ptr = src->data + m * src -> w;
uchar *dst_ptr = dst->data + m * dst -> w;
//gaussian卷积,此时边界没加处理
for (y = m; y < src -> h - m ; y++)
{
for (x = m; x < src->w - m; x++)
{
value = 0;
k = 0;
for (j = -m; j < m;j++)
{
for (i = -m; i < m; i++)
{
uchar temp = src_ptr[(y + j) * src->w + (x + i)];
float temp1 = kernel_vec[k++];
value += temp * temp1;
}
}
dst_ptr[x] = (uchar)(value);
}
dst_ptr += dst->w;
}
free(kernel_vec);
for (i = 0; i < size; i++)
free(kernel[i]);
free(kernel);
}
size = 5,sigma = 1时,实现的效果: