高斯模糊,见 百度百科。
也使用卷积来实现,每个卷积元素的公式为:
其中б是标准方差,一般取值为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 }