1. #region 灰阶
2. /// <summary>
3. /// 灰阶
4. /// </summary>
5. /// <param name="b">Bitmap对象</param>
6. /// <returns></returns>
7. public Bitmap Gray(Bitmap b)
8. {
9. BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height),
10. ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
11. int stride = bmData.Stride;
12. System.IntPtr Scan0 = bmData.Scan0;
13. unsafe
14. {
15. byte* p = (byte*)(void*)Scan0;
16. int nOffset = stride - b.Width * 3;
17. byte red, green, blue;
18. for (int y = 0; y < b.Height; ++y)
19. {
20. for (int x = 0; x < b.Width; ++x)
21. {
22. blue = p[0];
23. green = p[1];
24. red = p[2];
25. p[0] = p[1] = p[2] = (byte)(.299 * red + .587 * green + .114 * blue);
26. p += 3;
27. }
28. p += nOffset;
29. }
30. }
31. b.UnlockBits(bmData);
32. return b;
33. }
34. #endregion
35.
36. #region 固定阈值法二值化模块
37.
38. public Bitmap Threshoding(Bitmap b, byte threshold)
39. {
40. int width = b.Width;
41. int height = b.Height;
42. BitmapData data = b.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
43. unsafe
44. {
45. byte* p = (byte*)data.Scan0;
46. int offset = data.Stride - width * 4;
47. byte R, G, B, gray;
48. for (int y = 0; y < height; y++)
49. {
50. for (int x = 0; x < width; x++)
51. {
52. R = p[2];
53. G = p[1];
54. B = p[0];
55. gray = (byte)((R * 19595 + G * 38469 + B * 7472) >> 16);
56. if (gray >= threshold)
57. {
58. p[0] = p[1] = p[2] = 255;
59. }
60. else
61. {
62. p[0] = p[1] = p[2] = 0;
63. }
64. p += 4;
65. }
66. p += offset;
67. }
68. b.UnlockBits(data);
69. return b;
70. }
71.
72. }
73. #endregion
74.
75. #region Otsu阈值法二值化模块
76. /// <summary>
77. /// Otsu阈值
78. /// </summary>
79. /// <param name="b">位图流</param>
80. /// <returns></returns>
81. public Bitmap OtsuThreshold(Bitmap b)
82. {
83. // 图像灰度化
84. // b = Gray(b);
85. int width = b.Width;
86. int height = b.Height;
87. byte threshold = 0;
88. int[] hist = new int[256];
89.
90. int AllPixelNumber = 0, PixelNumberSmall = 0, PixelNumberBig = 0;
91. double MaxValue, AllSum = 0, SumSmall = 0, SumBig, ProbabilitySmall, ProbabilityBig, Probability;
92.
93. BitmapData data = b.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
94. unsafe
95. {
96. byte* p = (byte*)data.Scan0;
97. int offset = data.Stride - width * 4;
98.
99. for (int j = 0; j < height; j++)
100. {
101. for (int i = 0; i < width; i++)
102. {
103. hist[p[0]]++;
104.
105.
106. p += 4;
107. }
108. p += offset;
109. }
110. b.UnlockBits(data);
111.
112. }
113. //计算灰度为I的像素出现的概率
114. for (int i = 0; i < 256; i++)
115. {
116.
117. AllSum += i * hist[i]; // 质量矩
118. AllPixelNumber += hist[i]; // 质量
119.
120. }
121.
122. MaxValue = -1.0;
123. for (int i = 0; i < 256; i++)
124. {
125. PixelNumberSmall += hist[i];
126. PixelNumberBig = AllPixelNumber - PixelNumberSmall;
127. if (PixelNumberBig == 0)
128. {
129. break;
130. }
131.
132. SumSmall += i * hist[i];
133. SumBig = AllSum - SumSmall;
134. ProbabilitySmall = SumSmall / PixelNumberSmall;
135. ProbabilityBig = SumBig / PixelNumberBig;
136. Probability = PixelNumberSmall * ProbabilitySmall * ProbabilitySmall + PixelNumberBig * ProbabilityBig * ProbabilityBig;
137. if (Probability > MaxValue)
138. {
139. MaxValue = Probability;
140. threshold = (byte)i;
141. }
142.
143. }
144.
145. return this.Threshoding(b, threshold);
146. } // end of OtsuThreshold 2
147. #endregion