图像加噪与滤波【C#】

文章目录

  • 前言
  • 1 图像噪声的成因
  • 2 图像噪声的特征
  • 3 图像的加噪
    • 3.1 椒盐噪声
      • 3.1.1 什么是椒盐噪声
      • 3.1.2 椒盐噪声的产生
      • 3.1.3 实现方法
    • 3.2 高斯噪声
      • 3.2.1 什么是高斯噪声
      • 3.2.2 产生原因
      • 3.2.3 实现方法
  • 4 图像的降噪
    • 4.1 最大最小值滤波
    • 4.2 中值滤波
    • 4.3 均值滤波
  • 5 结果及分析

前言

项目源码见
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);
                    }
                }

实现效果如下:

图像加噪与滤波【C#】_第1张图片

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);
                    }
                }

实现效果如下

图像加噪与滤波【C#】_第2张图片
图像加噪与滤波【C#】_第3张图片

4 图像的降噪

4.1 最大最小值滤波

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

图像加噪与滤波【C#】_第4张图片

核心代码如下:

  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;
            }

灰度图像去噪效果如下

图像加噪与滤波【C#】_第5张图片

彩色图像去噪效果如下

图像加噪与滤波【C#】_第6张图片

  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;
            }

灰度图像去噪效果如下

图像加噪与滤波【C#】_第7张图片

彩色图像去噪效果如下

图像加噪与滤波【C#】_第8张图片

4.2 中值滤波

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

图像加噪与滤波【C#】_第9张图片

核心代码

			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;
            }

灰度图像去噪效果如下

图像加噪与滤波【C#】_第10张图片

彩色图像去噪效果如下

图像加噪与滤波【C#】_第11张图片
图像加噪与滤波【C#】_第12张图片

4.3 均值滤波

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

图像加噪与滤波【C#】_第13张图片

从左到右从上到下计算图像中的每个像素,最终得到处理后的图像。均值滤波可以加上两个参数,即迭代次数,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;
            }

灰度图像去噪效果如下

图像加噪与滤波【C#】_第14张图片

彩色图像去噪效果如下

图像加噪与滤波【C#】_第15张图片

5 结果及分析

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

图像加噪与滤波【C#】_第16张图片
图像加噪与滤波【C#】_第17张图片

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

图像加噪与滤波【C#】_第18张图片
图像加噪与滤波【C#】_第19张图片

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

图像加噪与滤波【C#】_第20张图片
图像加噪与滤波【C#】_第21张图片

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

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

图像加噪与滤波【C#】_第22张图片
图像加噪与滤波【C#】_第23张图片

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

你可能感兴趣的:(c#,计算机视觉,图像处理)