高斯模糊,见 百度百科

也使用卷积来实现,每个卷积元素的公式为:Unity shader学习之屏幕后期处理效果之高斯模糊

其中б是标准方差,一般取值为1。

x和y分别对应当前位置到卷积中心的整数距离。

由于需要对高斯核中的权重进行归一化,即使所有权重相加为1,因此e前面的系数实际不会对结果产生任何影响。

转载请注明出处:http://www.cnblogs.com/jietian331/p/7238032.html

综上,公式简化为:

G(x,y) = e-(x*x+y*y)/2

 

因此,高斯核计算代码如下:

  1 using System;
  2 
  3 namespace TestShell
  4 {
  5     class Program
  6     {
  7         static void Main(string[] args)
  8         {
  9             Console.WriteLine("输入需要得到的高斯卷积核的维数(如3,5,7...):");
 10 
 11             string input = Console.ReadLine();
 12             int size;
 13 
 14             if (!int.TryParse(input, out size))
 15             {
 16                 Console.WriteLine("不是数字...");
 17                 return;
 18             }
 19 
 20             // 计算
 21             double[] r2 = null;
 22             double[,] r = null;
 23             try
 24             {
 25                 r = CalcGaussianBlur(size, out r2);
 26             }
 27             catch (Exception ex)
 28             {
 29                 Console.WriteLine("错误: " + ex.Message);
 30             }
 31 
 32             if (r != null && r2 != null)
 33             {
 34                 // 卷积如下:
 35                 Console.WriteLine();
 36                 Console.WriteLine("{0}x{0}的高斯卷积核如下:", size);
 37                 for (int i = 0; i < r.GetLongLength(0); i++)
 38                 {
 39                     for (int j = 0; j < r.GetLongLength(1); j++)
 40                     {
 41                         Console.Write("{0:f4}\t", r[i, j]);
 42                     }
 43                     Console.WriteLine();
 44                 }
 45                 Console.WriteLine();
 46 
 47                 Console.WriteLine("可拆成2个一维的数组:");
 48                 for (int i = 0; i < r2.Length; i++)
 49                 {
 50                     Console.Write("{0:f4}\t", r2[i]);
 51                 }
 52                 Console.WriteLine();
 53                 Console.WriteLine();
 54 
 55                 Console.WriteLine("验证,使用这2个一维的数组也可以得到同样的结果:");
 56                 for (int i = 0; i < size; i++)
 57                 {
 58                     for (int j = 0; j < size; j++)
 59                     {
 60                         Console.Write("{0:f4}\t", r2[i] * r2[j]);
 61 
 62                     }
 63                     Console.WriteLine();
 64                 }
 65             }
 66 
 67             Console.WriteLine();
 68             Console.WriteLine("按任意键结束...");
 69             Console.ReadKey();
 70         }
 71 
 72         static double[,] CalcGaussianBlur(int size, out double[] r2)
 73         {
 74             if (size < 3)
 75                 throw new ArgumentException("size < 3");
 76             if (size % 2 != 1)
 77                 throw new ArgumentException("size % 2 != 1");
 78 
 79             double[,] r = new double[size, size];
 80             r2 = new double[size];
 81             int center = (int)Math.Floor(size / 2f);
 82             double sum = 0;
 83 
 84             for (int i = 0; i < size; i++)
 85             {
 86                 for (int j = 0; j < size; j++)
 87                 {
 88                     int x = Math.Abs(i - center);
 89                     int y = Math.Abs(j - center);
 90                     double d = CalcItem(x, y);
 91                     r[i, j] = d;
 92                     sum += d;
 93                 }
 94             }
 95 
 96             for (int i = 0; i < size; i++)
 97             {
 98                 for (int j = 0; j < size; j++)
 99                 {
100                     r[i, j] /= sum;
101                     if (i == j)
102                         r2[i] = Math.Sqrt(r[i, i]);
103                 }
104             }
105 
106             return r;
107         }
108 
109         static double CalcItem(int x, int y)
110         {
111             return Math.Pow(Math.E, -(x * x + y * y) / 2d);
112         }
113     }
114 }
View Code

相关文章: