1.效果图:
2.算法说明:
柔化(平滑)处理是将原图像的每个像素的颜色值用与其相邻的n*n个像素的平均值来代替,
可利用算术平均值或加权平均值来计算。
例如3*3的点阵,设源图像某像素的值为f(i,j):
f(i-1,j-1)
|
f(i-1,j)
|
f(i-1,j+1)
|
f(i,j-1)
|
f(i,j)
|
f(i,j+1)
|
f(i+1,j-1)
|
f(i+1,j)
|
f(i+1,j+1)
|
3.实现代码:
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
算术平均值实现方法
1![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**//// <summary>
2
/// 算术平均值实现柔化
3
/// </summary>
4
/// <param name="img">原始图像</param>
5
/// <returns></returns>
6
public static Image SmoothImage(Image img)
7![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
8
int width = img.Width;
9
int height = img.Height;
10![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
11
Bitmap oldImg = (Bitmap)img;
12
Bitmap newImg = new Bitmap(width, height); //实例一个与原图像一样大小的对象
13![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
14
Color color = new Color();
15
int r, g, b; //存放图像颜色点的R、G、B值
16
int rAvg, gAvg, bAvg; //存放某一点与相邻点平均值后的R、G、B值
17![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
18
//循环得到图像的每一个像素点
19
for (int i = 1; i < width - 1; i++)
20![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
21
for (int j = 1; j < height - 1; j++)
22![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
23
int rSum = 0, gSum = 0, bSum = 0; //存放3*3点阵R、G、B值的和
24![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
25
//取得与某一点相邻的3*3个像素点
26
for (int row = -1; row <= 1; row++)
27![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
28
for (int col = -1; col <= 1; col++)
29![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
30
color = oldImg.GetPixel(i + row, j + col);
31
r = color.R;
32
g = color.G;
33
b = color.B;
34
35
rSum += r;
36
gSum += g;
37
bSum += b;
38
}
39
}
40
//相邻点的算术平均值
41
rAvg = (int)(rSum / 9);
42
gAvg = (int)(gSum / 9);
43
bAvg = (int)(bSum / 9);
44![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
45
//处理颜色值得溢出
46
rAvg = rAvg < 0 ? 0 : rAvg;
47
rAvg = rAvg > 255 ? 255 : rAvg;
48
gAvg = gAvg < 0 ? 0 : gAvg;
49
gAvg = gAvg > 255 ? 255 : gAvg;
50
bAvg = bAvg < 0 ? 0 : bAvg;
51
bAvg = bAvg > 255 ? 255 : bAvg;
52![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
53
//设置新对象的每一点的颜色值
54
newImg.SetPixel(i,j,Color.FromArgb(rAvg,gAvg,bAvg));
55
}
56
}
57
return newImg;
58
}
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
加权平均值实现方法
1![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**//// <summary>
2
/// 加权平均值实现柔化
3
/// </summary>
4
/// <param name="img">原始图像</param>
5
/// <returns></returns>
6
public static Image SmoothImageWeight(Image img)
7![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
8
int width = img.Width;
9
int height = img.Height;
10![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
11
Bitmap oldImg = (Bitmap)img;
12
Bitmap newImg = new Bitmap(width, height); //实例一个与原图像一样大小的对象
13![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
14
Color color = new Color();
15
int r, g, b; //存放图像颜色点的R、G、B值
16
int rAvg, gAvg, bAvg; //存放某一点与相邻点平均值后的R、G、B值
17![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
int[] gauss =
{ 1, 2, 1, 2, 4, 2, 1, 2, 1 }; //高斯模版
18![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
19
//循环得到图像的每一个像素点
20
for (int i = 1; i < width - 1; i++)
21![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
22
for (int j = 1; j < height - 1; j++)
23![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
24
int index = 0; //高斯模版数组的索引
25
int rSum = 0, gSum = 0, bSum = 0; //存放按高斯模版所得点阵R、G、B值的和
26
for (int row = -1; row <= 1; row++)
27![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
28
for (int col = -1; col <= 1; col++)
29![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
30
color = oldImg.GetPixel(i + row, j + col);
31
r = color.R;
32
g = color.G;
33
b = color.B;
34![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
35
rSum += r * gauss[index];
36
gSum += g * gauss[index];
37
bSum += b * gauss[index];
38![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
39
index++;
40
}
41
}
42
//相邻点的加权平均值,"16" 为3*3高斯模版权重的总和
43
rAvg = rSum / 16;
44
gAvg = gSum / 16;
45
bAvg = bSum / 16;
46![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
47
//处理颜色值得溢出
48
rAvg = rAvg < 0 ? 0 : rAvg;
49
rAvg = rAvg > 255 ? 255 : rAvg;
50
gAvg = gAvg < 0 ? 0 : gAvg;
51
gAvg = gAvg > 255 ? 255 : gAvg;
52
bAvg = bAvg < 0 ? 0 : bAvg;
53
bAvg = bAvg > 255 ? 255 : bAvg;
54![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
55
//设置新对象的每一点的颜色值
56
newImg.SetPixel(i, j, Color.FromArgb(rAvg, gAvg, bAvg));
57
}
58
}
59
return newImg;
60
}
61
}
4.知识点说明:
a.加权平均值与算术平均值:
**加权平均值:
将各数值乘以相应的单位数,然后加总求和得到总体值,再除以总的单位数;
平均数的大小不仅取决于总体中各单位的标志值(变量值)的大小,而且取决于各标志值出现的次数(频数);
由于各标志值出现的次数对其在平均数中的影响起着权衡轻重的作用,因此叫做权数或权重。
**算术平均值:
(a1+a2+……an)/n为这几个数的算术平均值
**举例:
下面是一个同学的某一科的考试成绩:平时测验 80, 期中 90, 期末 95 。
学校规定的科目成绩的计算方式是:平时测验占 20%;期中成绩占 30%;期末成绩占 50%;
加权平均值 = (80*20% + 90*30% + 95*50%)/(20%+30%+50%) = 90.5
算数平均值 = (80 + 90 + 95)/3 = 88.3
b.高斯模版:
3*3高斯模版:
1 2 1
2 4 2 *(1/16)
1 2 1
详细参见:http://www.cnblogs.com/hoodlum1980/articles/1088567.html
注意:以上算法不能平滑图像边界的像素