您的位置:首页 > 其它

图像处理(七)给图像添加噪声

2012-11-01 20:40 288 查看
图像中的噪声就是图像中的杂点或者干扰成分,噪声主要产生于图像的获取和传输过程中。噪声一般分为分为加性噪声和乘性噪声。



其中f(x,y)表示图像,g(x,y)表示没有噪声的图像部分,q表示噪声。这两种噪声可以通过取对数和指数相互转换:



常见的几种噪声有,高斯噪声、瑞利噪声、指数噪声和椒盐噪声。除椒盐噪声以外其他三种均属于加性噪声。椒盐噪声既不属于加性噪声也不属于乘性噪声。

噪声是有噪声分量灰度值的统计特性来描述的,它们可以被认为是由概率密度函数(PDF)表示的随机变量,下面是几种噪声的概率密度函数。

高斯随机变量z的概率密度函数为:



μ表示z的期望值,σ表示z的方差。

瑞利噪声的概率密度函数为:



它的均值和方差分别为a+√(πb)/4和b(4-π)/4。

指数分布噪声的概率密度函数为:



它的均值和方差分别为1/a和1/a2,其中a>0。

椒盐噪声又称双击脉冲噪声,它类似于随机分布在图像上的胡椒(黑色)和盐粒(白色)。它的概率密度函数为:



对于一个8位深度图像,a=0,b=255.

下面仅将添加高斯噪声和椒盐噪声的代码贴出:

/// <summary>
/// 给图像添加噪声
/// </summary>
/// <param name="srcBmp">原始图像</param>
/// <param name="noiseType">噪声类型</param>
/// <param name="para">噪声类型参数(2个)</param>
/// <param name="dstBmp">目标图像</param>
/// <returns>处理成功 true 失败 false</returns>
public static bool AddNoise(Bitmap srcBmp, NoiseType noiseType, double[] para, out Bitmap dstBmp) {//NoiseType 为自定义噪声枚举类型
dstBmp = null;
if (srcBmp == null) { return false; }
dstBmp = new Bitmap(srcBmp);
BitmapData bmpData = dstBmp.LockBits(new Rectangle(0, 0, dstBmp.Width, dstBmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
Random r1 = new Random(unchecked((int)DateTime.Now.Ticks));
Random r2 = new Random(~unchecked((int)DateTime.Now.Ticks));
double temp, tempR, tempG, tempB, v1, v2;

unsafe {
byte* ptr = (byte*)bmpData.Scan0;
switch (noiseType) {
case NoiseType.GAUSSIAN://高斯噪声para[0]为μ  para[1]为σ
for (int i = 0; i < bmpData.Height; i++) {
for (int j = 0; j < bmpData.Width; j++) {
do {
v1 = r1.NextDouble();
} while (v1 <= 0.00000000001);
v2 = r2.NextDouble();
//应用雅克比变换直接生成正态分布
temp = Math.Sqrt(-2 * Math.Log(v1)) * Math.Cos(2 * Math.PI * v2) * para[1] + para[0];
tempB = temp + ptr[i * bmpData.Stride + j * 3];
tempG = temp + ptr[i * bmpData.Stride + j * 3 + 1];
tempR = temp + ptr[i * bmpData.Stride + j * 3 + 2];
tempB = tempB > 255 ? 255 : tempB; tempB = tempB < 0 ? 0 : tempB;
tempG = tempG > 255 ? 255 : tempG; tempG = tempG < 0 ? 0 : tempG;
tempR = tempR > 255 ? 255 : tempR; tempR = tempR < 0 ? 0 : tempR;
ptr[i * bmpData.Stride + j * 3] = (byte)tempB;
ptr[i * bmpData.Stride + j * 3 + 1] = (byte)tempG;
ptr[i * bmpData.Stride + j * 3 + 2] = (byte)tempR;
}
}
break;
case NoiseType.SALTPEPPER://椒盐噪声para[0]为椒含量 para[1]为盐含量
for (int i = 0; i < bmpData.Height; i++) {
for (int j = 0; j < bmpData.Width; j++) {
v1 = r1.NextDouble();
if (v1 <= para[0]) {
temp = -500;
}
else {
if (v1 >= 1 - para[1]) {
temp = 500;
}
else {
temp = 0;
}
}
tempB = temp + ptr[i * bmpData.Stride + j * 3];
tempG = temp + ptr[i * bmpData.Stride + j * 3 + 1];
tempR = temp + ptr[i * bmpData.Stride + j * 3 + 2];
tempB = tempB > 255 ? 255 : tempB; tempB = tempB < 0 ? 0 : tempB;
tempG = tempG > 255 ? 255 : tempG; tempG = tempG < 0 ? 0 : tempG;
tempR = tempR > 255 ? 255 : tempR; tempR = tempR < 0 ? 0 : tempR;
ptr[i * bmpData.Stride + j * 3] = (byte)tempB;
ptr[i * bmpData.Stride + j * 3 + 1] = (byte)tempG;
ptr[i * bmpData.Stride + j * 3 + 2] = (byte)tempR;
}
}
break;
default:
break;
}
}
dstBmp.UnlockBits(bmpData);
return true;
}
效果图:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: