c#中实现图像图像卷积与滤波-高斯平滑
使用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;
? ? ? ? }
?
總結
以上是生活随笔為你收集整理的c#中实现图像图像卷积与滤波-高斯平滑的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JAVA 内存模型 (Java Mem
- 下一篇: C# 中Bitmap图像处理含增强对比度