圖像噪聲是影響人們接受圖像信息的因素,常見的噪聲有高斯噪聲和椒鹽噪聲。因為最近課程要求,做一個圖像恢復的Project,所以掌握了給圖像添加噪聲以及去除噪聲的方法。
給圖像添加高斯噪聲
高斯噪聲是大量具有正太分布的隨機變量性質的值加到原圖像造成的,要給圖像添加高斯噪聲,其實問題就是怎麼產生正太分布隨機變量。首先用Randdom對象的NextDouble產生兩個0-1之間的隨機變量r1,r2,計算
double result = Math.Sqrt((-2) * Math.Log(r2)) * Math.Sin(2 * Math.PI * r1);
得到的result就是具有均值0,方差1的正太分布隨機變量。這是box-muller方法,算法推導很復雜,但實現卻很方便。因為對圖像添加高斯噪聲的時候,對於每一個像素都需要產生r1,r2以便得到噪聲,這就需要快速大量地產生隨機變量,一開始我發現產生的隨機變量總是連續相同,也就是說在很短的時間內產生的隨機數是相同的,因為畢竟C#Random產生的是偽隨機數,是通過一定的算法算出來的,而且有依據“種子”來計算,默認情況下是依據電腦此時時間來計算,但是當快速大量此類的隨機數時,會出現連續產生相同隨機數的情況,因為電腦時間不是一個很好的“種子”。
C++ Primer Plus 第6版 中文版 清晰有書簽PDF+源代碼 http://www.linuxidc.com/Linux/2014-05/101227.htm
讀C++ Primer 之構造函數陷阱 http://www.linuxidc.com/Linux/2011-08/40176.htm
讀C++ Primer 之智能指針 http://www.linuxidc.com/Linux/2011-08/40177.htm
讀C++ Primer 之句柄類 http://www.linuxidc.com/Linux/2011-08/40175.htm
C++11 獲取系統時間庫函數 time since epoch http://www.linuxidc.com/Linux/2014-03/97446.htm
C++11中正則表達式測試 http://www.linuxidc.com/Linux/2012-08/69086.htm
所以我的程序裡用了這樣的辦法:
static int GetRandomSeed( ) //產生隨機種子
{
byte[] bytes = new byte[4];
System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider( );
rng.GetBytes( bytes );
return BitConverter.ToInt32( bytes , 0 );
}
public double GaussNiose1()//用box muller的方法產生均值為0,方差為1的正太分布隨機數
{
// Random ro = new Random(10);
// long tick = DateTime.Now.Ticks;
Random ran = new Random(GetRandomSeed());
// Random rand = new Random();
double r1 = ran.NextDouble();
double r2 = ran.NextDouble();
double result = Math.Sqrt((-2) * Math.Log(r2)) * Math.Sin(2 * Math.PI * r1);
return result;//返回隨機數
}
這樣問題就解決了,可以短時間快速產生隨機數。
給圖像添加椒鹽噪聲
添加椒鹽噪聲的方法如下:
private void AddSalt(object sender, EventArgs e)
02. {
03. if (textBox12.Text != "" && textBox13.Text != "")
04. {
05. // Bitmap pic = (Bitmap)Bitmap.FromFile(filename, false);
06. Bitmap pic = new Bitmap(pictureBox2.Image, WI, HE);
07. double Pa = Convert.ToDouble(textBox12.Text);//接受輸入的Pa
08. double Pb = Convert.ToDouble(textBox13.Text);//接受輸入的Pb
09. double P = Pb / (1 - Pa);//程序要,為了得到一個概率Pb事件
10. int width = pic.Width;
11. int height = pic.Height;
12. Random rand = new Random();
13. for (int i = 0; i < height; i++)
14. {
15. for (int j = 0; j < width; j++)
16. {
17. int gray;
18. int noise = 1;
19. double probility = rand.NextDouble();
20. if (probility < Pa)
21. {
22. noise = 255;//有Pa概率 噪聲設為最大值
23. }
24. else
25. {
26. double temp = rand.NextDouble();
27. if (temp < P)//有1 - Pa的幾率到達這裡,再乘以 P ,剛好等於Pb
28. noise = 0;
29. }
30. if (noise != 1)
31. {
32. gray = noise;
33. }
34. else gray = pic.GetPixel(j, i).R;
35. Color color = Color.FromArgb(gray, gray, gray);
36. pic.SetPixel(j, i, color);
37. }
38. }
39. Form2 f2 = new Form2();
40. f2.change_size(pic);
41. f2.Setname("圖像添加椒鹽噪聲之後的圖像,需要還原的話請先保存然後再打開^_^");
42. f2.Show();
43. }
44. else
45. {
46. MessageBox.Show("請先輸入Pa和Pb^_^");
47. }
48. }
更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2014-06/103012p2.htm