/// <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 = Vector.Interval(-xMax, xMax); int[] yValues = Vector.Interval(-yMax, yMax); Accord.Diagnostics.Debug.Assert(xValues.Length == (2 * xMax + 1)); Accord.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++) { double v = Gabor.Function2D( xValues[i], yValues[j], lambda, theta, psi, sigma, gamma).Magnitude; sum += kernel[i, j] = v * v; } } break; } if (normalized) { kernel.Divide(sum, result: kernel); } return(kernel); }