代码是我从VC代码中转译过来的,注释都沿用了原作者的文字(别说是剽窃,^_^)。唯一改进的地方是,原代码功能只能处理0和255的二值灰度(搞不懂为什么这样,对于250、128这样的都不行,还不如弄成二值灰度,别弄256灰度了),我将之改成了能根据0~255中任意灰度划界的256灰度图像!
以下是C#代码:
1
/**/
/// <summary>
2
/// 该函数用于对图像进行腐蚀运算。结构元素为水平方向或垂直方向的三个点,
3
/// 中间点位于原点;或者由用户自己定义3×3的结构元素。
4
/// </summary>
5
/// <param name="dgGrayValue">前后景临界值</param>
6
/// <param name="nMode">腐蚀方式:0表示水平方向,1垂直方向,2自定义结构元素。</param>
7
/// <param name="structure"> 自定义的3×3结构元素</param>
8
public
void
ErosionPic(
int
dgGrayValue,
int
nMode,
bool
[,] structure)
9
{
10
int lWidth = bmpobj.Width;
11
int lHeight = bmpobj.Height;
12
Bitmap newBmp = new Bitmap(lWidth, lHeight);
13
14
int i, j, n, m; //循环变量
15
Color pixel; //像素颜色值
16
17
if (nMode == 0)
18
{
19
//使用水平方向的结构元素进行腐蚀
20
// 由于使用1×3的结构元素,为防止越界,所以不处理最左边和最右边
21
// 的两列像素
22
for (j = 0; j < lHeight; j++)
23
{
24
for (i = 1; i < lWidth - 1; i++)
25
{
26
//目标图像中的当前点先赋成黑色
27
newBmp.SetPixel(i, j, Color.Black);
28
29
//如果源图像中当前点自身或者左右有一个点不是黑色,
30
//则将目标图像中的当前点赋成白色
31
if (bmpobj.GetPixel(i - 1, j).R > dgGrayValue ||
32
bmpobj.GetPixel(i, j).R > dgGrayValue ||
33
bmpobj.GetPixel(i + 1, j).R > dgGrayValue)
34
newBmp.SetPixel(i, j, Color.White);
35
}
36
}
37
}
38
else if (nMode == 1)
39
{
40
//使用垂真方向的结构元素进行腐蚀
41
// 由于使用3×1的结构元素,为防止越界,所以不处理最上边和最下边
42
// 的两行像素
43
for (j = 1; j < lHeight - 1; j++)
44
{
45
for (i = 0; i < lWidth; i++)
46
{
47
//目标图像中的当前点先赋成黑色
48
newBmp.SetPixel(i, j, Color.Black);
49
50
//如果源图像中当前点自身或者左右有一个点不是黑色,
51
//则将目标图像中的当前点赋成白色
52
if (bmpobj.GetPixel(i, j - 1).R > dgGrayValue ||
53
bmpobj.GetPixel(i, j).R > dgGrayValue ||
54
bmpobj.GetPixel(i, j + 1).R > dgGrayValue)
55
newBmp.SetPixel(i, j, Color.White);
56
}
57
}
58
}
59
else
60
{
61
if (structure.Length != 9) //检查自定义结构
62
return;
63
//使用自定义的结构元素进行腐蚀
64
// 由于使用3×3的结构元素,为防止越界,所以不处理最左边和最右边
65
// 的两列像素和最上边和最下边的两列像素
66
for (j = 1; j < lHeight - 1; j++)
67
{
68
for (i = 1; i < lWidth - 1; i++)
69
{
70
//目标图像中的当前点先赋成黑色
71
newBmp.SetPixel(i, j, Color.Black);
72
//如果原图像中对应结构元素中为黑色的那些点中有一个不是黑色,
73
//则将目标图像中的当前点赋成白色
74
for (m = 0; m < 3; m++)
75
{
76
for (n = 0; n < 3; n++)
77
{
78
if (!structure[m, n])
79
continue;
80
if (bmpobj.GetPixel(i + m - 1, j + n - 1).R > dgGrayValue)
81
{
82
newBmp.SetPixel(i, j, Color.White);
83
break;
84
}
85
}
86
}
87
}
88
}
89
}
90
91
bmpobj = newBmp;
92
}
93
94
95
/**/
/// <summary>
96
/// 该函数用于对图像进行细化运算。要求目标图像为灰度图像
97
/// </summary>
98
/// <param name="dgGrayValue"></param>
99
public
void
ThiningPic(
int
dgGrayValue)
100
{
101
int lWidth = bmpobj.Width;
102
int lHeight = bmpobj.Height;
103
// Bitmap newBmp = new Bitmap(lWidth, lHeight);
104
105
bool bModified; //脏标记
106
int i, j, n, m; //循环变量
107
Color pixel; //像素颜色值
108
109
//四个条件
110
bool bCondition1;
111
bool bCondition2;
112
bool bCondition3;
113
bool bCondition4;
114
115
int nCount; //计数器
116
int[,] neighbour = new int[5, 5]; //5×5相邻区域像素值
117
118
119
120
bModified = true;
121
while (bModified)
122
{
123
bModified = false;
124
125
//由于使用5×5的结构元素,为防止越界,所以不处理外围的几行和几列像素
126
for (j = 2; j < lHeight - 2; j++)
127
{
128
for (i = 2; i < lWidth - 2; i++)
129
{
130
bCondition1 = false;
131
bCondition2 = false;
132
bCondition3 = false;
133
bCondition4 = false;
134
135
if (bmpobj.GetPixel(i, j).R > dgGrayValue)
136
{
137
if(bmpobj.GetPixel(i, j).R<255)
138
bmpobj.SetPixel(i, j, Color.White);
139
continue;
140
}
141
142
//获得当前点相邻的5×5区域内像素值,白色用0代表,黑色用1代表
143
for (m = 0; m < 5; m++)
144
{
145
for (n = 0; n < 5; n++)
146
{
147
neighbour[m, n] = bmpobj.GetPixel(i + m - 2, j + n - 2).R < dgGrayValue ? 1 : 0;
148
}
149
}
150
151
//逐个判断条件。
152
//判断2<=NZ(P1)<=6
153
nCount = neighbour[1, 1] + neighbour[1, 2] + neighbour[1, 3]
154
+ neighbour[2, 1] + neighbour[2, 3] +
155
+neighbour[3, 1] + neighbour[3, 2] + neighbour[3, 3];
156
if (nCount >= 2 && nCount <= 6)
157
{
158
bCondition1 = true;
159
}
160
161
//判断Z0(P1)=1
162
nCount = 0;
163
if (neighbour[1, 2] == 0 && neighbour[1, 1] == 1)
164
nCount++;
165
if (neighbour[1, 1] == 0 && neighbour[2, 1] == 1)
166
nCount++;
167
if (neighbour[2, 1] == 0 && neighbour[3, 1] == 1)
168
nCount++;
169
if (neighbour[3, 1] == 0 && neighbour[3, 2] == 1)
170
nCount++;
171
if (neighbour[3, 2] == 0 && neighbour[3, 3] == 1)
172
nCount++;
173
if (neighbour[3, 3] == 0 && neighbour[2, 3] == 1)
174
nCount++;
175
if (neighbour[2, 3] == 0 && neighbour[1, 3] == 1)
176
nCount++;
177
if (neighbour[1, 3] == 0 && neighbour[1, 2] == 1)
178
nCount++;
179
if (nCount == 1)
180
bCondition2 = true;
181
182
//判断P2*P4*P8=0 or Z0(p2)!=1
183
if (neighbour[1, 2] * neighbour[2, 1] * neighbour[2, 3] == 0)
184
{
185
bCondition3 = true;
186
}
187
else
188
{
189
nCount = 0;
190
if (neighbour[0, 2] == 0 && neighbour[0, 1] == 1)
191
nCount++;
192
if (neighbour[0, 1] == 0 && neighbour[1, 1] == 1)
193
nCount++;
194
if (neighbour[1, 1] == 0 && neighbour[2, 1] == 1)
195
nCount++;
196
if (neighbour[2, 1] == 0 && neighbour[2, 2] == 1)
197
nCount++;
198
if (neighbour[2, 2] == 0 && neighbour[2, 3] == 1)
199
nCount++;
200
if (neighbour[2, 3] == 0 && neighbour[1, 3] == 1)
201
nCount++;
202
if (neighbour[1, 3] == 0 && neighbour[0, 3] == 1)
203
nCount++;
204
if (neighbour[0, 3] == 0 && neighbour[0, 2] == 1)
205
nCount++;
206
if (nCount != 1)
207
bCondition3 = true;
208
}
209
210
//判断P2*P4*P6=0 or Z0(p4)!=1
211
if (neighbour[1, 2] * neighbour[2, 1] * neighbour[3, 2] == 0)
212
{
213
bCondition4 = true;
214
}
215
else
216
{
217
nCount = 0;
218
if (neighbour[1, 1] == 0 && neighbour[1, 0] == 1)
219
nCount++;
220
if (neighbour[1, 0] == 0 && neighbour[2, 0] == 1)
221
nCount++;
222
if (neighbour[2, 0] == 0 && neighbour[3, 0] == 1)
223
nCount++;
224
if (neighbour[3, 0] == 0 && neighbour[3, 1] == 1)
225
nCount++;
226
if (neighbour[3, 1] == 0 && neighbour[3, 2] == 1)
227
nCount++;
228
if (neighbour[3, 2] == 0 && neighbour[2, 2] == 1)
229
nCount++;
230
if (neighbour[2, 2] == 0 && neighbour[1, 2] == 1)
231
nCount++;
232
if (neighbour[1, 2] == 0 && neighbour[1, 1] == 1)
233
nCount++;
234
if (nCount != 1)
235
bCondition4 = true;
236
}
237
238
if (bCondition1 && bCondition2 && bCondition3 && bCondition4)
239
{
240
bmpobj.SetPixel(i, j, Color.White);
241
bModified = true;
242
}
243
else
244
{
245
bmpobj.SetPixel(i, j, Color.Black);
246
}
247
}
248
}
249
}
250
// 复制细化后的图像
251
// bmpobj = newBmp;
252
}
253


2

3

4

5

6

7

8

9



10

11

12

13

14

15

16

17

18



19

20

21

22

23



24

25



26

27

28

29

30

31

32

33

34

35

36

37

38

39



40

41

42

43

44



45

46



47

48

49

50

51

52

53

54

55

56

57

58

59

60



61

62

63

64

65

66

67



68

69



70

71

72

73

74

75



76

77



78

79

80

81



82

83

84

85

86

87

88

89

90

91

92

93

94

95


96

97

98

99

100



101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122



123

124

125

126

127



128

129



130

131

132

133

134

135

136



137

138

139

140

141

142

143

144



145

146



147

148

149

150

151

152

153

154

155

156

157



158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184



185

186

187

188



189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212



213

214

215

216



217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239



240

241

242

243

244



245

246

247

248

249

250

251

252

253
