1 /** 2 * Copyright (c) 2011, The University of Southampton and the individual contributors. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without modification, 6 * are permitted provided that the following conditions are met: 7 * 8 * * Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 11 * * Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 15 * * Neither the name of the University of Southampton nor the names of its 16 * contributors may be used to endorse or promote products derived from this 17 * software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 package org.openimaj.image.processing.convolution; 31 32 import org.openimaj.image.FImage; 33 import org.openimaj.image.processor.SinglebandImageProcessor; 34 35 /** 36 * Image processor for FImage capable of performing convolutions with Gaussians. 37 * 38 * @author Jonathon Hare (jsh2@ecs.soton.ac.uk) 39 */ 40 public class FGaussianConvolve implements SinglebandImageProcessor<Float, FImage> { 41 /** 42 * The default number of sigmas at which the Gaussian function is truncated 43 * when building a kernel 44 */ 45 public static final float DEFAULT_GAUSS_TRUNCATE = 4.0f; 46 47 protected float[] kernel; 48 49 /** 50 * Construct an {@link FGaussianConvolve} with a Gaussian of standard 51 * deviation sigma. 52 * 53 * @param sigma 54 * Gaussian kernel standard deviation 55 */ 56 public FGaussianConvolve(float sigma) { 57 this(sigma, DEFAULT_GAUSS_TRUNCATE); 58 } 59 60 /** 61 * Construct an {@link FGaussianConvolve} with a Gaussian of standard 62 * deviation sigma. The truncate parameter defines how many sigmas wide the 63 * kernel is. 64 * 65 * @param sigma 66 * @param truncate 67 */ 68 public FGaussianConvolve(float sigma, float truncate) { 69 kernel = makeKernel(sigma, truncate); 70 } 71 72 /** 73 * Construct a zero-mean Gaussian with the specified standard deviation. 74 * 75 * @param sigma 76 * the standard deviation of the Gaussian 77 * @return an array representing a Gaussian function 78 */ 79 public static float[] makeKernel(float sigma) { 80 return makeKernel(sigma, DEFAULT_GAUSS_TRUNCATE); 81 } 82 83 /** 84 * Construct a zero-mean Gaussian with the specified standard deviation. 85 * 86 * @param sigma 87 * the standard deviation of the Gaussian 88 * @param truncate 89 * the number of sigmas from the centre at which to truncate the 90 * Gaussian 91 * @return an array representing a Gaussian function 92 */ 93 public static float[] makeKernel(float sigma, float truncate) { 94 if (sigma == 0) 95 return new float[] { 1f }; 96 // The kernel is truncated at truncate sigmas from center. 97 int ksize = (int) (2.0f * truncate * sigma + 1.0f); 98 // ksize = Math.max(1, ksize); // size must be at least 3 99 if (ksize % 2 == 0) 100 ksize++; // size must be odd 101 102 final float[] kernel = new float[ksize]; 103 104 // build kernel 105 float sum = 0.0f; 106 for (int i = 0; i < ksize; i++) { 107 final float x = i - ksize / 2; 108 kernel[i] = (float) Math.exp(-x * x / (2.0 * sigma * sigma)); 109 sum += kernel[i]; 110 } 111 112 // normalise area to 1 113 for (int i = 0; i < ksize; i++) { 114 kernel[i] /= sum; 115 } 116 117 return kernel; 118 } 119 120 /* 121 * (non-Javadoc) 122 * 123 * @see 124 * org.openimaj.image.processor.ImageProcessor#processImage(org.openimaj 125 * .image.Image) 126 */ 127 @Override 128 public void processImage(FImage image) { 129 FImageConvolveSeparable.convolveHorizontal(image, kernel); 130 FImageConvolveSeparable.convolveVertical(image, kernel); 131 } 132 }