项目源码见
https://download.csdn.net/download/apple_52030329/86795789
图像在生成和传输过程中常常因受到各种噪声的干扰和影响致使图像降质,这对后续图像的处理和图像视觉效应将产生不利影响。此,为了抑制噪声,改善图像质量,便于更高层次的处理,必须对图像进行去噪
处理。
在学习去噪处理前,我们先要了解图像噪声的产生。
图像噪声使得图像模糊,甚至埋没图像特征,给分析带来困难,图像噪声一般具有以下特点:
本文仅介绍椒盐噪声与高斯噪声
椒盐噪声又称为脉冲噪声,它是一种随机出现的白点或者黑点。 椒盐噪声 = 椒噪声 (pepper noise)+ 盐噪声(salt noise)。椒盐噪声的值为0(椒)或者255(盐),“椒”噪声是低灰度噪声,“盐”噪声属于高灰度噪声。一般两种噪声同时出现,呈现在图像上就是黑白杂点。对于彩色图像,也有可能表现为在单个像素BGR
三个通道随机出现的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);
}
}
实现效果如下:
高斯噪声(Gaussian noise)是指它的概率密度函数服从高斯分布的一类噪声。特别的,如果一个噪声,它的幅度分布服从高斯分布,而它的功率谱密度又是均匀分布的,则称它为高斯白噪声。
必须区分高斯噪声和白噪声两个不同的概念。高斯噪声是指噪声的概率密度函数服从高斯分布,白噪声是指噪声的任意两个采样样本之间不相关,两者描述的角度不同。白噪声不必服从高斯分布,高斯分布的噪声不一定是白噪声。
图像传感器在拍摄时不够明亮、亮度不够均匀;电路各元器件自身噪声和相互影响;图像传感器长期工作,温度过高。
一个正常的高斯采样分布公式G(d), 得到输出像素
*Pout. Pout = Pin + XMeans + sigma G(d)
其中d为一个线性的随机数,G(d)是随机数的高斯分布随机值。
给一张数字图像加上高斯噪声的方法大致如下:
核心代码如下
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);
}
}
实现效果如下
最大最小值滤波是一种比较保守的图像处理手段,首先要排序周围像素和中心像素值,然后将中心像素值与最小和最大像素值比较,如果比最小值小,则替换中心像素为最小值,如果中心像素比最大值大,则替换中心像素为最大值。一个Kernel矩阵为3X3的最大最小值滤波如下:
核心代码如下:
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;
}
灰度图像去噪效果如下
彩色图像去噪效果如下
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;
}
灰度图像去噪效果如下
彩色图像去噪效果如下
中值滤波是消除图像噪声最常见的手段之一,特别是消除椒盐噪声,中值滤波的效果要比均值滤波更好。中值滤波是跟均值滤波唯一不同是,不是用均值来替换中心每个像素,而是将周围像素和中心像素排序以后,取中值,一个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;
}
灰度图像去噪效果如下
彩色图像去噪效果如下
均值滤波,是图像处理中最常用的手段,从频率域观点来看均值滤波是一种低通滤波器,高频信号将会去掉,因此可以帮助消除图像尖锐噪声,实现图像平滑,模糊等功能。理想的均值滤波是用每个像素和它周围像素计算出来的平均值替换图像中每个像素。采样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;
}
灰度图像去噪效果如下
彩色图像去噪效果如下
对于最大值滤波
,由于是选择像素领域内的最大值代替该像素点的rgb值,结合使用各个图片进行实验,得出结论为最大值滤波器对“椒”噪声(灰度值为0)有较好效果。
对于最小值滤波
,其与最大值滤波实现方式差别不大,仅是改为选取最小值,类推也能得知最小值滤波更适合对盐噪声进行降噪处理,结合实验结果来看,证实了猜想。
对于中值滤波
,是将图像的每个像素用邻域 (以当前像素为中心的正方形区域)像素的中值代替,结合各个实验结果来看,椒盐噪声的消除效果最好,所以中值滤波更适用于消除图像中的椒盐噪声,对于其他噪声也有较好的处理效果。
从结果来看,中值滤波在消除噪声的同时,能够保护图像的边缘,使之不被模糊。
对于均值滤波
,对此进行了优化,消除了邻域中最大值和最小值,再进行对像素均值替换
从均值滤波结果来看,其不能很好地保护图像细节,在图像去噪地同时破坏了图像地细节部分,从而使图像变得模糊和暗淡,不能很好地去除噪声。