图像处理绕不开的一个环节就是去燥,去掉各式各样的噪声来保证图像的质量。今天将高斯滤波实现了下,在此稍作记录。以往惯例,先上图:
原图:
高斯滤波:
Side Window版高斯滤波:
仔细看蓝色的山,和图像右侧下中部的倒影,还是能看出些许增强的,在一些特别注重细节的领域或应用中,可能就会发挥很大的作用。
滤波原理简单的理解就是通过一个模板,去与图像的每一个像素进行卷积,通过控制权值,利用周围像素重新计算改变中间像素的值,来减小噪声,达到平滑的目的。
还不理解的可以去看下这个:高斯模糊的原理
Side Window算法原理:Side Window 算法原理详解
代码:
#include <iostream>
#define IMAGE_WIDTH 1920
#define IMAGE_HEIGHT 1080
#define SIDE_WINDOW_ENHANCE
int main()
{
FILE* fp = fopen("D:/test/3_noise.yuv", "rb");
if (NULL == fp)
{
printf("Can not open file!\n");
return -1;
}
fseek(fp, 0, SEEK_END);
int len = ftell(fp);
fseek(fp, 0, SEEK_SET);
unsigned char* input = new unsigned char[len]();
fread(input, 1, len, fp);
fclose(fp);
#ifndef SIDE_WINDOW_ENHANCE
//3x3的高斯核
float gaussKernel[9] = {
0.075114, 0.123841, 0.075114,
0.123841, 0.204180, 0.123841,
0.075114, 0.123841, 0.075114
};
unsigned imageKernel[9] = { 0 };
for (int i = 1; i < IMAGE_HEIGHT - 1; i++)
{
for (int j = 1; j < IMAGE_WIDTH - 1; j++)
{
//还是习惯性的先取出要处理的像素,也可以直接带入原像素计算
imageKernel[0] = input[(i - 1)*IMAGE_WIDTH + j - 1];
imageKernel[1] = input[(i - 1)*IMAGE_WIDTH + j];
imageKernel[2] = input[(i - 1)*IMAGE_WIDTH + j + 1];
imageKernel[3] = input[(i)*IMAGE_WIDTH + j - 1];
imageKernel[4] = input[(i)*IMAGE_WIDTH + j];
imageKernel[5] = input[(i)*IMAGE_WIDTH + j + 1];
imageKernel[6] = input[(i + 1)*IMAGE_WIDTH + j - 1];
imageKernel[7] = input[(i + 1)*IMAGE_WIDTH + j];
imageKernel[8] = input[(i + 1)*IMAGE_WIDTH + j + 1];
float sum = 0.0;
for (int k = 0; k < 9; k++)
{
sum += imageKernel[k] * gaussKernel[k];
}
input[(i)*IMAGE_WIDTH + j] = (sum + 0.5);
}
}
#else
//Side Window增强版 3x3高斯核
float filter_kernel[8][9] = {
{ 0.142538, 0.235003, 0, 0.235003, 0.387456, 0, 0, 0, 0 },
{ 0, 0.235003, 0.142538, 0, 0.387456, 0.235003, 0, 0, 0 },
{ 0 ,0, 0, 0.235003, 0.387456, 0, 0.142538, 0.235003, 0 },
{ 0, 0, 0, 0, 0.387456, 0.235003, 0, 0.235003, 0.142538 },
{ 0.103473, 0.170596, 0.103473, 0.170596, 0.281266, 0.170596, 0, 0, 0 },
{ 0, 0, 0, 0.170596, 0.281266, 0.170596, 0.103473, 0.170596, 0.103473 },
{ 0, 0.170596, 0.103473, 0, 0.281266, 0.170596, 0, 0.170596, 0.103473 },
{ 0.103473, 0.170596, 0, 0.170596, 0.281266, 0, 0.103473, 0.170596, 0 } };
int imageKernel[9] = { 0 };
for (int i = 1; i < IMAGE_HEIGHT - 1; i++)
{
for (int j = 1; j < IMAGE_WIDTH - 1; j++)
{
float min_sum = 255.0;
imageKernel[0] = input[(i - 1)*IMAGE_WIDTH + j - 1];
imageKernel[1] = input[(i - 1)*IMAGE_WIDTH + j];
imageKernel[2] = input[(i - 1)*IMAGE_WIDTH + j + 1];
imageKernel[3] = input[(i)*IMAGE_WIDTH + j - 1];
imageKernel[4] = input[(i)*IMAGE_WIDTH + j];
imageKernel[5] = input[(i)*IMAGE_WIDTH + j + 1];
imageKernel[6] = input[(i + 1)*IMAGE_WIDTH + j - 1];
imageKernel[7] = input[(i + 1)*IMAGE_WIDTH + j];
imageKernel[8] = input[(i + 1)*IMAGE_WIDTH + j + 1];
for (size_t m = 0; m < 8; m++)
{
float sum = 0.0;
for (int k = 0; k < 9; k++)
{
sum += imageKernel[k] * filter_kernel[m][k];
}
if (sum < min_sum)
min_sum = sum;
}
input[(i)*IMAGE_WIDTH + j] = (min_sum + 0.5);
}
}
#endif
fp = fopen("D:/test/out.yuv","wb");
if (NULL == fp)
{
printf("Can not open file!\n");
return -1;
}
fwrite(input, 1, len, fp);
fclose(fp);
delete[] input;
return 0;
}
图片链接: 百度网盘链接 提取码: w3af