图像处理:C代码实现 椒盐噪声的添加和中值滤波去除椒盐噪声

  • 椒盐噪声简介:椒(pepper)即表示图像中某像素处的值为0(黑色),盐(salt)即表示图像中某像素处的值为255(白色);
  • 产生椒盐噪声的思路:
    1. 产生两个随机数(xPosition和yPosition),用来在图像中该坐标处添加椒盐点;
    2. 产生一个随机数,用来决定在1中的坐标点上添加椒点还是盐点;
    3. 注意事项:产生椒盐噪声的椒盐个数和椒盐颗粒的大小均需要通过参数设置,并且本程序是给灰度图片添加噪声。

代码如下:

int peppersalt(unsigned char* buffer, int w, int h, int count, int size)
{
	int xPosition;
	int yPosition;
	int psNoise;
	if (count == 0)
		count = w*h;
	if (size == 0)
		size = 1;
	while (count)
	{
		xPosition = rand() % (w - size + 1);//产生随机的要设置噪声的像素点x坐标
		yPosition = rand() % (h - size + 1);//产生随机的要设置噪声的像素点y坐标
		psNoise = rand() % 2;//随机设置该点作为盐点或椒点
		if (psNoise)
		{// 产生盐点
			for (int i = 0; i < size; i++)
			{
				for (int j = 0; j < size; j++)
				{
					buffer[(yPosition+i)*w + xPosition+j] = 255;
				}
			}
		}
		else
		{// 产生椒点
			for (int i = 0; i < size; i++)
			{
				for (int j = 0; j < size; j++)
				{
					buffer[(yPosition+i)*w + xPosition+j] = 0;
				}
			}
		}
		count = count - 1;
	}
	return 0;
}

处理效果:

中值滤波去除椒盐噪声:

原理简介:

1:通过从 图像中的某个 采样窗口取出奇数个数据进行排序

2: 用排序后的中值取代要处理的数据即可

中值滤波的算法实现过程,重点是排序,最常用的冒泡排序

把滤波区间的数据从小到大进行排序,然后取中值,(如果是奇数个数据,那么中值就只有一个了,如果偶数个数据,中值有两个,可以对两个数据再求平均)

int GetMedianNum(int* buf, int num)
{
	int i, j;// 循环变量
	unsigned char bTemp;

	// 用冒泡法对数组进行排序
	for (j = 0; j < num - 1; j++)
	{
		for (i = 0; i < num - j - 1; i++)
		{
			if (buf[i] > buf[i + 1])
			{
				// 互换
				bTemp = buf[i];
				buf[i] = buf[i + 1];
				buf[i + 1] = bTemp;
			}
		}
	}

	// 计算中值
	if ((num & 1) > 0)
	{
		// 数组有奇数个元素,返回中间一个元素
		bTemp = buf[((num + 1) / 2)-1];
	}
	else
	{
		// 数组有偶数个元素,返回中间两个元素平均值
		bTemp = (buf[(num / 2)-1] + buf[(num / 2 + 1)-1]) / 2;
	}

	return bTemp;
}


int image_medianfilter(unsigned char* buffer, int w, int h, int size)
{
	int rows2 = size / 2;
	int cols2 = size / 2;
	int index = 0;
	int index2 = 0;
	int total = size * size;
	int* matrix = (int*)malloc(sizeof(int)*total);
	unsigned char* tmp_buf = (unsigned char*)malloc(sizeof(unsigned char)*w*h);
	for (int y = 0; y < h; y++) 
	{
		for (int x = 0; x < w; x++) 
		{
			int count = 0;
			for (int row = -rows2; row <= rows2; row++) 
			{
				int rowoffset = y + row;
				if (rowoffset < 0 || rowoffset >= h) //边缘扩充用最近的像素值代替
				{
					rowoffset = y;
				}

				for (int col = -cols2; col <= cols2; col++) 
				{
					int coloffset = col + x;
					if (coloffset < 0 || coloffset >= w) //边缘扩充用最近的像素值代替
					{
						coloffset = x;
					}
					index2 = rowoffset * w + coloffset;
					matrix[count] = buffer[index2];
					count++;
				}
			}
			tmp_buf[index++] = GetMedianNum(matrix, count);
		}
	}
	memcpy(buffer, tmp_buf, sizeof(unsigned char)*w*h);
	free(matrix);
	free(tmp_buf);
	return 0;
}

处理效果对比:

 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值