您的位置:首页 > 编程语言 > C#

c#实现图像图像卷积与滤波——高斯平滑

2016-11-01 19:00 806 查看
使用C#语言编写高斯平滑。


一、线性滤波与卷积的基本概念

2D卷积需要4个嵌套循环4-double loop,所以它并不快,除非我们使用很小的卷积核。这里一般使用3×3或者5×5。而且,对于滤波器,也有一定的规则要求:

1)滤波器的大小应该是奇数,这样它才有一个中心,例如3×3,5×5或者7×7。有中心了,也有了半径的称呼,例如5×5大小的核的半径就是2。

2)滤波器矩阵所有的元素之和应该要等于1,这是为了保证滤波前后图像的亮度保持不变。当然了,这不是硬性要求了。

3)如果滤波器矩阵所有元素之和大于1,那么滤波后的图像就会比原图像更亮,反之,如果小于1,那么得到的图像就会变暗。如果和为0,图像不会变黑,但也会非常暗。

4)对于滤波后的结构,可能会出现负数或者大于255的数值。对这种情况,我们将他们直接截断到0和255之间即可。对于负数,也可以取绝对值。


二、卷积核

private double[,] GaussianBlur;//声明私有的高斯模糊卷积核函数

/// <summary>
/// 构造卷积(Convolution)类函数
/// </summary>
public Convolution()
{
//初始化高斯模糊卷积核
int k=273;
GaussianBlur = new double[5, 5]{{(double)1/k,(double)4/k,(double)7/k,(double)4/k,(double)1/k},
{(double)4/k,(double)16/k,(double)26/k,(double)16/k,(double)4/k},
{(double)7/k,(double)26/k,(double)41/k,(double)26/k,(double)7/k},
{(double)4/k,(double)16/k,(double)26/k,(double)16/k,(double)4/k},
{(double)1/k,(double)4/k,(double)7/k,(double)4/k,(double)1/k}};
}

三、对图像进行卷积平滑

/// <summary>
/// 对图像进行平滑处理(利用高斯平滑Gaussian Blur)
/// </summary>
/// <param name="bitmap">要处理的位图</param>
/// <returns>返回平滑处理后的位图</returns>
public Bitmap Smooth(Bitmap bitmap)
{
int[, ,] InputPicture = new int[3, bitmap.Width, bitmap.Height];//以GRB以及位图的长宽建立整数输入的位图的数组

Color color = new Color();//储存某一像素的颜色
//循环使得InputPicture数组得到位图的RGB
for (int i = 0; i < bitmap.Width; i++)
{
for (int j = 0; j < bitmap.Height; j++)
{
color = bitmap.GetPixel(i, j);
InputPicture[0, i, j] = color.R;
InputPicture[1, i, j] = color.G;
InputPicture[2, i, j] = color.B;
}
}

int[, ,] OutputPicture = new int[3, bitmap.Width, bitmap.Height];//以GRB以及位图的长宽建立整数输出的位图的数组
Bitmap smooth = new Bitmap(bitmap.Width, bitmap.Height);//创建新位图
//循环计算使得OutputPicture数组得到计算后位图的RGB
for (int i = 0; i < bitmap.Width; i++)
{
for (int j = 0; j < bitmap.Height; j++)
{
int R=0;
int G=0;
int B=0;

//每一个像素计算使用高斯模糊卷积核进行计算
for (int r = 0; r < 5; r++)//循环卷积核的每一行
{
for (int f = 0; f < 5; f++)//循环卷积核的每一列
{
//控制与卷积核相乘的元素
int row = i - 2 + r;
int index = j - 2 + f;

//当超出位图的大小范围时,选择最边缘的像素值作为该点的像素值
row = row < 0 ? 0 : row;
index = index < 0 ? 0 : index;
row = row >= bitmap.Width ? bitmap.Width - 1 : row;
index = index >= bitmap.Height ? bitmap.Height - 1 : index;

//输出得到像素的RGB值
R += (int)(GaussianBlur[r, f] * InputPicture[0, row, index]);
G += (int)(GaussianBlur[r, f] * InputPicture[1, row, index]);
B += (int)(GaussianBlur[r, f] * InputPicture[2, row, index]);
}
}
color = Color.FromArgb(R,G,B);//颜色结构储存该点RGB
smooth.SetPixel(i, j, color);//位图存储该点像素值
}
}
return smooth;
}


参考文章:图像卷积与滤波的一些知识点 - zouxy09的专栏 - 博客频道 - CSDN.NET 作者:zouxy09
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C# 图像 卷积滤波