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}};
}
参考文章:图像卷积与滤波的一些知识点 - zouxy09的专栏 - 博客频道 - CSDN.NET 作者:zouxy09
一、线性滤波与卷积的基本概念
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++实现
- 高斯平滑滤波的实现与图像内存之间值的复制
- opencv for python (13) 图像卷积及图像平滑(平均、高斯模糊、中值模糊、双边滤波)
- 高斯图像滤波原理及其编程离散化实现方法
- matlab 图像高斯平滑滤波处理(转载)
- 高斯图像滤波原理及其编程离散化实现方法
- 图像处理基本概念——卷积,滤波,平滑
- 高斯图像滤波原理及其编程离散化实现方法
- 图像处理基本概念——卷积,滤波,平滑
- 图像处理之基础---卷积,滤波,平滑
- 高斯图像滤波原理及其编程离散化实现方法
- opencv的图像卷积、图像滤波、图像平滑的解析
- 图像处理基本概念——卷积,滤波,平滑
- 高斯图像滤波原理及其编程离散化实现方法
- Opencv 实现图像的离散傅里叶变换(DFT)、卷积运算(相关滤波)
- 高斯图像滤波原理及其编程离散化实现方法
- 高斯图像滤波原理及其编程离散化实现方法
- 【Matlab学习笔记】【图像滤波去噪】高斯平滑滤波
- 图像处理基本概念——卷积,滤波,平滑
- 图像处理基本概念——卷积,滤波,平滑