/** * Creates a Gaussian kernel with the specified properties. * * @param DOF 1 for 1D kernel and 2 for 2D kernel. * @param isFloat True for F32 kernel and false for I32. * @param numBits Number of bits in each data element. 32 or 64 * @param sigma The distributions stdev. If <= 0 then the sigma will be computed from the radius. * @param radius Number of pixels in the kernel's radius. If <= 0 then the sigma will be computed * from the sigma. @return The computed Gaussian kernel. */ public static <T extends KernelBase> T gaussian( int DOF, boolean isFloat, int numBits, double sigma, int radius) { if (radius <= 0) radius = FactoryKernelGaussian.radiusForSigma(sigma, 0); else if (sigma <= 0) sigma = FactoryKernelGaussian.sigmaForRadius(radius, 0); if (DOF == 2) { if (numBits == 32) { Kernel2D_F32 k = gaussian2D_F32(sigma, radius, isFloat); if (isFloat) return (T) k; return (T) KernelMath.convert(k, MIN_FRAC); } else if (numBits == 64) { Kernel2D_F64 k = gaussian2D_F64(sigma, radius, isFloat); if (isFloat) return (T) k; else throw new IllegalArgumentException("64bit int kernels supported"); } else { throw new IllegalArgumentException("Bits must be 32 or 64"); } } else if (DOF == 1) { if (numBits == 32) { Kernel1D_F32 k = gaussian1D_F32(sigma, radius, isFloat); if (isFloat) return (T) k; return (T) KernelMath.convert(k, MIN_FRAC); } else { throw new IllegalArgumentException("Bits must be 32 "); } } else { throw new IllegalArgumentException("DOF not supported"); } }
protected static Kernel2D_F64 gaussian2D_F64(double sigma, int radius, boolean normalize) { Kernel1D_F64 kernel1D = gaussian1D_F64(sigma, radius, false); Kernel2D_F64 ret = KernelMath.convolve(kernel1D, kernel1D); if (normalize) { KernelMath.normalizeSumToOne(ret); } return ret; }
protected static Kernel1D_F64 gaussian1D_F64(double sigma, int radius, boolean normalize) { Kernel1D_F64 ret = new Kernel1D_F64(radius * 2 + 1); double[] gaussian = ret.data; int index = 0; for (int i = radius; i >= -radius; i--) { gaussian[index++] = UtilGaussian.computePDF(0, sigma, i); } if (normalize) { KernelMath.normalizeSumToOne(ret); } return ret; }
/** * Creates a 1D Gaussian kernel with the specified properties. * * @param order The order of the gaussian derivative. * @param isFloat True for F32 kernel and false for I32. * @param sigma The distributions stdev. If <= 0 then the sigma will be computed from the radius. * @param radius Number of pixels in the kernel's radius. If <= 0 then the sigma will be computed * from the sigma. * @return The computed Gaussian kernel. */ public static <T extends Kernel1D> T derivative( int order, boolean isFloat, double sigma, int radius) { // zero order is a regular gaussian if (order == 0) { return gaussian(1, isFloat, 32, sigma, radius); } if (radius <= 0) radius = FactoryKernelGaussian.radiusForSigma(sigma, order); else if (sigma <= 0) { sigma = FactoryKernelGaussian.sigmaForRadius(radius, order); } Kernel1D_F32 k = derivative1D_F32(order, sigma, radius, true); if (isFloat) return (T) k; return (T) KernelMath.convert(k, MIN_FRAC); }