给图像加噪声

 图像中的噪声就是图像中的杂点或者干扰成分,噪声主要产生于图像的获取和传输过程中。噪声一般分为分为加性噪声和乘性噪声。

                                    

其中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.

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

[csharp]  view plain  copy
  1. /// <summary>  
  2.     /// 给图像添加噪声  
  3.     /// </summary>  
  4.     /// <param name="srcBmp">原始图像</param>  
  5.     /// <param name="noiseType">噪声类型</param>  
  6.     /// <param name="para">噪声类型参数(2个)</param>  
  7.     /// <param name="dstBmp">目标图像</param>  
  8.     /// <returns>处理成功 true 失败 false</returns>  
  9.     public static bool AddNoise(Bitmap srcBmp, NoiseType noiseType, double[] para, out Bitmap dstBmp) {//NoiseType 为自定义噪声枚举类型  
  10.         dstBmp = null;  
  11.         if (srcBmp == null) { return false; }  
  12.         dstBmp = new Bitmap(srcBmp);  
  13.         BitmapData bmpData = dstBmp.LockBits(new Rectangle(0, 0, dstBmp.Width, dstBmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);  
  14.         Random r1 = new Random(unchecked((int)DateTime.Now.Ticks));  
  15.         Random r2 = new Random(~unchecked((int)DateTime.Now.Ticks));  
  16.         double temp, tempR, tempG, tempB, v1, v2;  
  17.   
  18.         unsafe {  
  19.             byte* ptr = (byte*)bmpData.Scan0;  
  20.             switch (noiseType) {  
  21.                 case NoiseType.GAUSSIAN://高斯噪声para[0]为μ  para[1]为σ  
  22.                     for (int i = 0; i < bmpData.Height; i++) {  
  23.                         for (int j = 0; j < bmpData.Width; j++) {  
  24.                             do {  
  25.                                 v1 = r1.NextDouble();  
  26.                             } while (v1 <= 0.00000000001);  
  27.                             v2 = r2.NextDouble();  
  28.                             //应用雅克比变换直接生成正态分布  
  29.                             temp = Math.Sqrt(-2 * Math.Log(v1)) * Math.Cos(2 * Math.PI * v2) * para[1] + para[0];  
  30.                             tempB = temp + ptr[i * bmpData.Stride + j * 3];  
  31.                             tempG = temp + ptr[i * bmpData.Stride + j * 3 + 1];  
  32.                             tempR = temp + ptr[i * bmpData.Stride + j * 3 + 2];  
  33.                             tempB = tempB > 255 ? 255 : tempB; tempB = tempB < 0 ? 0 : tempB;  
  34.                             tempG = tempG > 255 ? 255 : tempG; tempG = tempG < 0 ? 0 : tempG;  
  35.                             tempR = tempR > 255 ? 255 : tempR; tempR = tempR < 0 ? 0 : tempR;  
  36.                             ptr[i * bmpData.Stride + j * 3] = (byte)tempB;  
  37.                             ptr[i * bmpData.Stride + j * 3 + 1] = (byte)tempG;  
  38.                             ptr[i * bmpData.Stride + j * 3 + 2] = (byte)tempR;  
  39.                         }  
  40.                     }  
  41.                     break;  
  42.                 case NoiseType.SALTPEPPER://椒盐噪声para[0]为椒含量 para[1]为盐含量  
  43.                     for (int i = 0; i < bmpData.Height; i++) {  
  44.                         for (int j = 0; j < bmpData.Width; j++) {  
  45.                             v1 = r1.NextDouble();  
  46.                             if (v1 <= para[0]) {  
  47.                                 temp = -500;  
  48.                             }  
  49.                             else {  
  50.                                 if (v1 >= 1 - para[1]) {  
  51.                                     temp = 500;  
  52.                                 }  
  53.                                 else {  
  54.                                     temp = 0;  
  55.                                 }  
  56.                             }  
  57.                             tempB = temp + ptr[i * bmpData.Stride + j * 3];  
  58.                             tempG = temp + ptr[i * bmpData.Stride + j * 3 + 1];  
  59.                             tempR = temp + ptr[i * bmpData.Stride + j * 3 + 2];  
  60.                             tempB = tempB > 255 ? 255 : tempB; tempB = tempB < 0 ? 0 : tempB;  
  61.                             tempG = tempG > 255 ? 255 : tempG; tempG = tempG < 0 ? 0 : tempG;  
  62.                             tempR = tempR > 255 ? 255 : tempR; tempR = tempR < 0 ? 0 : tempR;  
  63.                             ptr[i * bmpData.Stride + j * 3] = (byte)tempB;  
  64.                             ptr[i * bmpData.Stride + j * 3 + 1] = (byte)tempG;  
  65.                             ptr[i * bmpData.Stride + j * 3 + 2] = (byte)tempR;  
  66.                         }  
  67.                     }  
  68.                     break;  
  69.                 default:  
  70.                     break;  
  71.             }  
  72.         }  
  73.         dstBmp.UnlockBits(bmpData);  
  74.         return true;  
  75.     }  
效果图:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值