图像加噪与滤波【C#】

前言

项目源码见
https://download.csdn.net/download/apple_52030329/86795789


1 图像噪声的成因

图像在生成和传输过程中常常因受到各种噪声的干扰和影响致使图像降质,这对后续图像的处理和图像视觉效应将产生不利影响。此,为了抑制噪声,改善图像质量,便于更高层次的处理,必须对图像进行去噪处理。
在学习去噪处理前,我们先要了解图像噪声的产生。

2 图像噪声的特征

图像噪声使得图像模糊,甚至埋没图像特征,给分析带来困难,图像噪声一般具有以下特点:

  1. 噪声在图像中的分布和大小不规则,即具有随机性。
  2. 噪声与图像之间一般具有相关性。
  3. 噪声具有叠加性

3 图像的加噪

本文仅介绍椒盐噪声与高斯噪声

3.1 椒盐噪声

3.1.1 什么是椒盐噪声

椒盐噪声又称为脉冲噪声,它是一种随机出现的白点或者黑点。 椒盐噪声 = 椒噪声 (pepper noise)+ 盐噪声(salt noise)。椒盐噪声的值为0(椒)或者255(盐),“椒”噪声是低灰度噪声,“盐”噪声属于高灰度噪声。一般两种噪声同时出现,呈现在图像上就是黑白杂点。对于彩色图像,也有可能表现为在单个像素BGR三个通道随机出现的255或0。

3.1.2 椒盐噪声的产生

如果通信时出错,部分像素的值在传输时丢失,就会发生这种噪声;盐和椒噪声的成因可能是影像讯号受到突如其来的强烈干扰而产生等。例如失效的感应器导致像 素值为最小值,饱和的感应器导致像素值为最大值。

3.1.3 实现方法

给一张数字图像加上椒盐噪声的方法大致如下:

  • 指定信噪比SNR,取值在[0,1]之间
  • 计算总像素数目 SP, 得到要加噪的像素数目 NP = SP * (1-SNR)
  • 随机获取要加噪的每个像素位置P(i, j)
  • 指定像素值为255或者0
  • 重复上述两个步骤完成对所有像素的加噪

核心代码如下

				for (int i = 0; i < height; i++)
                {
                    for (int j = 0; j < width; j++)
                    {
                        int gray;
                        int noise = 1;
                        double probility = rand.NextDouble();
                        if (probility < Pa)
                        {
                            noise = 255;//有Pa概率 噪声设为最大值
                        }
                        else
                        {
                            double temp = rand.NextDouble();
                            if (temp < P)//有1 - Pa的几率到达这里,再乘以 P ,刚好等于Pb
                                noise = 0;
                        }
                        if (noise != 1)
                        {
                            gray = noise;
                        }
                        else gray = pic.GetPixel(j, i).R;
                        Color color = Color.FromArgb(gray, gray, gray);
                        pic.SetPixel(j, i, color);
                    }
                }

实现效果如下:

在这里插入图片描述

3.2 高斯噪声

3.2.1 什么是高斯噪声

高斯噪声(Gaussian noise)是指它的概率密度函数服从高斯分布的一类噪声。特别的,如果一个噪声,它的幅度分布服从高斯分布,而它的功率谱密度又是均匀分布的,则称它为高斯白噪声。
必须区分高斯噪声和白噪声两个不同的概念。高斯噪声是指噪声的概率密度函数服从高斯分布,白噪声是指噪声的任意两个采样样本之间不相关,两者描述的角度不同。白噪声不必服从高斯分布,高斯分布的噪声不一定是白噪声。

3.2.2 产生原因

图像传感器在拍摄时不够明亮、亮度不够均匀;电路各元器件自身噪声和相互影响;图像传感器长期工作,温度过高。

3.2.3 实现方法

一个正常的高斯采样分布公式G(d), 得到输出像素
*Pout. Pout = Pin + XMeans + sigma G(d)
其中d为一个线性的随机数,G(d)是随机数的高斯分布随机值。
给一张数字图像加上高斯噪声的方法大致如下:

  • 输入参数方差和均值
  • 以系统时间为种子产生一个伪随机数
  • 将伪随机数带入G(d)得到高斯随机数
  • 根据输入像素计算出输出像素
  • 重新将像素值放缩在[0 ~ 255]之间 f. 循环所有像素

核心代码如下

				double mean = Convert.ToDouble(textBox10.Text);//均值
                double variance = Convert.ToDouble(textBox11.Text);//方差
                int width = pic.Width;
                int height = pic.Height;
                double noise;
                double temp;
               
                for (int i = 0; i < height; i++)
                {
                    for (int j = 0; j < width; j++)
                    {
                        temp = GaussNiose1();
                        noise = mean + temp * variance;
                        int gray = (int)(pic.GetPixel(j, i).R + noise);//给图像添加高斯噪声噪声
                        if (gray > 255) gray = 255;
                        if (gray < 0) gray = 0;
                        Color color = Color.FromArgb(gray, gray, gray);
                        pic.SetPixel(j, i, color);
                    }
                }

实现效果如下

在这里插入图片描述
在这里插入图片描述

4 图像的降噪

4.1 最大最小值滤波

最大最小值滤波是一种比较保守的图像处理手段,首先要排序周围像素和中心像素值,然后将中心像素值与最小和最大像素值比较,如果比最小值小,则替换中心像素为最小值,如果中心像素比最大值大,则替换中心像素为最大值。一个Kernel矩阵为3X3的最大最小值滤波如下:

在这里插入图片描述

核心代码如下:

  1. 最大值滤波
			for(int i = 1; i < bt1.Width-1; i++)
            {
                for(int j = 1; j < bt1.Height - 1; j++)
                {
                    int rm = 0, r1, gm = 0, g1, bm = 0, b1;
                    for(int m = -1; m < 2; m++)
                    {
                        for(int n = -1; n < 2; n++)
                        {
                            color = bt1.GetPixel(i + m, j + n);
                            r1 = color.R;
                            if (r1 > rm)
                                rm = r1;
                            g1 = color.G;
                            if (g1 > gm)
                                gm = g1;
                            b1 = color.B;
                            if (b1 > bm)
                                bm = b1;
                        }
                    }

                    bt2.SetPixel(i, j, Color.FromArgb(rm, gm, bm));
                }
                pictureBox2.Refresh();
                pictureBox2.Image = bt2;
            }

灰度图像去噪效果如下

在这里插入图片描述

彩色图像去噪效果如下

在这里插入图片描述

  1. 最小值滤波
			for (int i = 1; i < bt1.Width - 1; i++)
            {
                for (int j = 1; j < bt1.Height - 1; j++)
                {
                    int rm = 255, gm = 255, bm = 255;
                    int r, g, b;
                    for(int m = -1; m < 2; m++)
                    {
                        for(int n = -1; n < 2; n++)
                        {
                            color = bt1.GetPixel(i + m, j + n);
                            r = color.R;
                            if (r < rm)
                                rm = r;
                            g = color.G;
                            if (g < gm)
                                gm = g;
                            b = color.B;
                            if (b < bm)
                                bm = b;
                        }
                    }
                    bt2.SetPixel(i, j, Color.FromArgb(rm, gm, bm));
                }
                pictureBox2.Refresh();
                pictureBox2.Image = bt2;
            }

灰度图像去噪效果如下

在这里插入图片描述

彩色图像去噪效果如下

在这里插入图片描述

4.2 中值滤波

中值滤波是消除图像噪声最常见的手段之一,特别是消除椒盐噪声,中值滤波的效果要比均值滤波更好。中值滤波是跟均值滤波唯一不同是,不是用均值来替换中心每个像素,而是将周围像素和中心像素排序以后,取中值,一个3X3大小的中值滤波如下:

在这里插入图片描述

核心代码

			int[] dtr = new int[40];
            int[] dtg = new int[40];
            int[] dtb = new int[40];
            for (int i = 1; i < bt1.Width - 1; i++)
            {
                for (int j = 1; j < bt1.Height - 1; j++)
                {
                    int rr = 0, m = 0, gg = 0, bb = 0;
                    int r, g, b;
                    for(int k = -1; k < 2; k++)
                    {
                        for(int n = -1; n < 2; n++)
                        {
                            color = bt1.GetPixel(i + k, j + n);
                            r = color.R;g = color.G;b = color.B;
                            dtr[m++] = r;
                            dtg[m++] = g;
                            dtb[m++] = b;
                        }
                    }
                    for(int p = 0; p < m - 1; p++)
                    {
                        for(int q = p + 1; q < m; q++)
                        {
                            if (dtr[p] > dtr[q])
                            {
                                int bmp = dtr[p];
                                dtr[p] = dtr[q];
                                dtr[q] = bmp;
                            }
                            if (dtg[p] > dtg[q])
                            {
                                int bmp = dtg[p];
                                dtg[p] = dtg[q];
                                dtg[q] = bmp;
                            }
                            if (dtb[p] > dtb[q])
                            {
                                int bmp = dtb[p];
                                dtb[p] = dtb[q];
                                dtb[q] = bmp;
                            }
                        }
                    }
                    rr = dtr[(int)(m / 2)];
                    gg = dtg[(int)(m / 2)];
                    bb = dtb[(int)(m / 2)];
                    bt2.SetPixel(i, j, Color.FromArgb(rr, gg, bb));
                }
                pictureBox2.Refresh();
                pictureBox2.Image = bt2;
            }

灰度图像去噪效果如下

在这里插入图片描述

彩色图像去噪效果如下

在这里插入图片描述
在这里插入图片描述

4.3 均值滤波

均值滤波,是图像处理中最常用的手段,从频率域观点来看均值滤波是一种低通滤波器,高频信号将会去掉,因此可以帮助消除图像尖锐噪声,实现图像平滑,模糊等功能。理想的均值滤波是用每个像素和它周围像素计算出来的平均值替换图像中每个像素。采样Kernel数据通常是3X3的矩阵,如下表示:

在这里插入图片描述

从左到右从上到下计算图像中的每个像素,最终得到处理后的图像。均值滤波可以加上两个参数,即迭代次数,Kernel数据大小。一个相同的Kernel,但是多次迭代就会效果越来越好。
同样,迭代次数相同,Kernel矩阵越大,均值滤波的效果就越明显。

对于均值滤波,对此进行了优化,消除了邻域中最大值和最小值,再进行对像素均值替换

核心代码

			for (int i = 1; i < bt1.Width - 1; i++)
            {
                for (int j = 1; j < bt1.Height - 1; j++)
                {
                    int rr = 0, m = 0,gg=0,bb=0;
                    int r, g, b;
                    for(int k = -1; k < 2; k++)
                    {
                        for(int n = -1; n < 2; n++)
                        {
                            color = bt1.GetPixel(i + k, j + n);
                            r = color.R; g = color.G; b = color.B;
                            dtr[m++] = r;
                            dtg[m++] = g;
                            dtb[m++] = b;
                            m++;
                        }
                    }
                    for (int p = 0; p < m - 1; p++)
                    {
                        for (int q = p + 1; q < m; q++)
                        {
                            if (dtr[p] > dtr[q])
                            {
                                int bmp = dtr[p];
                                dtr[p] = dtr[q];
                                dtr[q] = bmp;
                            }
                            if (dtg[p] > dtg[q])
                            {
                                int bmp = dtg[p];
                                dtg[p] = dtg[q];
                                dtg[q] = bmp;
                            }
                            if (dtb[p] > dtb[q])
                            {
                                int bmp = dtb[p];
                                dtb[p] = dtb[q];
                                dtb[q] = bmp;
                            }
                        }
                    }
                    //相比中值滤波,去除最大值和最小值
                    for(int l = 1; l < m - 1; l++)
                    {
                        rr += dtr[l];
                        gg += dtg[l];
                        bb += dtb[l];
                    }
                    rr = (int)(rr / (m - 2));
                    gg = (int)(gg / (m - 2));
                    bb = (int)(bb / (m - 2));
                    bt2.SetPixel(i, j, Color.FromArgb(rr, gg, bb));
                }
                pictureBox2.Refresh();
                pictureBox2.Image = bt2;
            }

灰度图像去噪效果如下

在这里插入图片描述

彩色图像去噪效果如下

在这里插入图片描述

5 结果及分析

对于最大值滤波,由于是选择像素领域内的最大值代替该像素点的rgb值,结合使用各个图片进行实验,得出结论为最大值滤波器对“椒”噪声(灰度值为0)有较好效果。

在这里插入图片描述
在这里插入图片描述

对于最小值滤波,其与最大值滤波实现方式差别不大,仅是改为选取最小值,类推也能得知最小值滤波更适合对盐噪声进行降噪处理,结合实验结果来看,证实了猜想。

在这里插入图片描述
在这里插入图片描述

对于中值滤波,是将图像的每个像素用邻域 (以当前像素为中心的正方形区域)像素的中值代替,结合各个实验结果来看,椒盐噪声的消除效果最好,所以中值滤波更适用于消除图像中的椒盐噪声,对于其他噪声也有较好的处理效果。

在这里插入图片描述
在这里插入图片描述

从结果来看,中值滤波在消除噪声的同时,能够保护图像的边缘,使之不被模糊。

对于均值滤波,对此进行了优化,消除了邻域中最大值和最小值,再进行对像素均值替换

在这里插入图片描述
在这里插入图片描述

从均值滤波结果来看,其不能很好地保护图像细节,在图像去噪地同时破坏了图像地细节部分,从而使图像变得模糊和暗淡,不能很好地去除噪声。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

日常脱发的小迈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值