本文转自: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
/**/
///<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
else60


{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)<=6153
nCount=neighbour[1,1]+neighbour[1,2]+neighbour[1,3]154
本文介绍了一种基于C#的图像腐蚀算法实现方法,并提供了详细的代码示例。腐蚀算法通过对图像像素及其周围像素的分析,实现图像的去噪处理。
612

被折叠的 条评论
为什么被折叠?



