本文转自:http://www.cnblogs.com/yuanbao/archive/2008/04/12/1149923.html
最近做一些图像处理,需要将图像中的一些像素过滤一下,有网友给提了个名词:腐蚀算法。我不是学图像学的,乍一听,觉得很神奇。后来从网上收集了一些VC代码,研究了一下,发现其它也就是那么回事。尤其是腐蚀算法,我在以前的验证码图片去噪声的文章中提到过,只是那是我不知叫什么名词,就从用途出发,叫做“根据周边点数去噪”。腐蚀的原理也一样,就是根据当前点的周边点数(如3X3的,周边就有8个点)来修改当前点的状态的。
代码是我从VC代码中转译过来的,注释都沿用了原作者的文字(别说是剽窃,^_^)。唯一改进的地方是,原代码功能只能处理0和255的二值灰度(搞不懂为什么这样,对于250、128这样的都不行,还不如弄成二值灰度,别弄256灰度了),我将之改成了能根据0~255中任意灰度划界的256灰度图像!
以下是C#代码:
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->
1
/**/
///<summary>
2
///该函数用于对图像进行腐蚀运算。结构元素为水平方向或垂直方向的三个点,
3
///中间点位于原点;或者由用户自己定义3×3的结构元素。
4
///</summary>
5
///<paramname="dgGrayValue">前后景临界值</param>
6
///<paramname="nMode">腐蚀方式:0表示水平方向,1垂直方向,2自定义结构元素。</param>
7
///<paramname="structure">自定义的3×3结构元素</param>
8
public
void
ErosionPic(
int
dgGrayValue,
int
nMode,
bool
[,]structure)
9
{
10
intlWidth=bmpobj.Width;
11
intlHeight=bmpobj.Height;
12
BitmapnewBmp=newBitmap(lWidth,lHeight);
13
14
inti,j,n,m;//循环变量
15
Colorpixel;//像素颜色值
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
elseif(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
///<paramname="dgGrayValue"></param>
99
public
void
ThiningPic(
int
dgGrayValue)
100
{
101
intlWidth=bmpobj.Width;
102
intlHeight=bmpobj.Height;
103
//BitmapnewBmp=newBitmap(lWidth,lHeight);
104
105
boolbModified;//脏标记
106
inti,j,n,m;//循环变量
107
Colorpixel;//像素颜色值
108
109
//四个条件
110
boolbCondition1;
111
boolbCondition2;
112
boolbCondition3;
113
boolbCondition4;
114
115
intnCount;//计数器
116
int[,]neighbour=newint[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


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