/// <summary> /// Computes the 2-D Gabor kernel. /// </summary> /// public static double[,] Kernel2D(int size, double lambda, double theta, double psi, double sigma, double gamma, bool normalized, GaborKernelKind function) { double sigmaX = sigma; double sigmaY = sigma / gamma; double a = Math.Max( Math.Abs(size * sigmaX * Math.Cos(theta)), Math.Abs(size * sigmaY * Math.Sin(theta))); int xMax = (int)Math.Ceiling(Math.Max(1, a)); double b = Math.Max( Math.Abs(size * sigmaX * Math.Sin(theta)), Math.Abs(size * sigmaY * Math.Cos(theta))); int yMax = (int)Math.Ceiling(Math.Max(1, b)); int[] xValues = Matrix.Vector(-xMax, xMax, increment: 1); int[] yValues = Matrix.Vector(-yMax, yMax, increment: 1); System.Diagnostics.Debug.Assert(xValues.Length == (2 * xMax + 1)); System.Diagnostics.Debug.Assert(yValues.Length == (2 * yMax + 1)); double[,] kernel = new double[xValues.Length, yValues.Length]; double sum = 0; switch (function) { case GaborKernelKind.Real: for (int i = 0; i < xValues.Length; i++) { for (int j = 0; j < yValues.Length; j++) { sum += kernel[i, j] = Gabor.RealFunction2D( xValues[i], yValues[j], lambda, theta, psi, sigma, gamma); } } break; case GaborKernelKind.Imaginary: for (int i = 0; i < xValues.Length; i++) { for (int j = 0; j < yValues.Length; j++) { sum += kernel[i, j] = Gabor.ImaginaryFunction2D( xValues[i], yValues[j], lambda, theta, psi, sigma, gamma); } } break; case GaborKernelKind.Magnitude: for (int i = 0; i < xValues.Length; i++) { for (int j = 0; j < yValues.Length; j++) { sum += kernel[i, j] = Gabor.Function2D( xValues[i], yValues[j], lambda, theta, psi, sigma, gamma).Magnitude; } } break; case GaborKernelKind.SquaredMagnitude: for (int i = 0; i < xValues.Length; i++) { for (int j = 0; j < yValues.Length; j++) { sum += kernel[i, j] = Gabor.Function2D( xValues[i], yValues[j], lambda, theta, psi, sigma, gamma).SquaredMagnitude; } } break; } if (normalized) { kernel.Divide(sum, inPlace: true); } return(kernel); }