图像处理-高斯滤波和升级版Side Window版高斯滤波(C++实现,无需opencv)

图像处理绕不开的一个环节就是去燥,去掉各式各样的噪声来保证图像的质量。今天将高斯滤波实现了下,在此稍作记录。以往惯例,先上图:

原图:

高斯滤波:

 

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

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值