/* * Copyright (C) 2014 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package interactivespaces.util.sampling; /** * A collection of useful utilities for working with samples. * * @author Keith M. Hughes */ public class SamplingUtils { /** * Apply a kernel filter to the samples. * * <p> * The edges are ignored. * * <p> * Kernels give a sequence of offsets in the sample data from the current * sample point to say what to put into the computation. * * @param samples * the samples to run the filter on * @param kernel * the kernel representing the filter * @param numRows * the number of rows in the samples * @param numCols * the number of columns in the samples * * @return a new array with the filtered data */ public static int[] applyFilter(int[] samples, int[] kernel, int numRows, int numCols) { int[] newSamples = new int[samples.length]; for (int col = 1; col < numCols - 1; col++) { int rowStart = 0; for (int row = 1; row < numRows - 1; row++) { rowStart += numCols; int sum = 0; int pos = col + rowStart; for (int i = 0; i < kernel.length; i++) { sum += samples[pos + kernel[i]]; } newSamples[pos] = sum / kernel.length; } } return newSamples; } /** * Apply a kernel filter to the samples. * * <p> * The edges are taken into account and the kernel is truncated if it extends * outside of the grid for a given point. * * <p> * Kernels give a sequence of offsets in the sample data from the current * sample point to say what to put into the computation. * * @param samples * the samples to run the filter on * @param kernel * the kernel representing the filter * @param numRows * the number of rows in the samples * @param numCols * the number of columns in the samples * * @return a new array with the filtered data */ public static int[] applyFilter2(int[] samples, int[] kernel, int numRows, int numCols) { int numSamples = numRows * numCols; int[] newSamples = new int[samples.length]; for (int col = 0; col < numCols; col++) { int rowStart = -numCols; for (int row = 0; row < numRows; row++) { rowStart += numCols; int sum = 0; int pos = col + rowStart; int count = 0; for (int i = 0; i < kernel.length; i++) { int samplePosition = pos + kernel[i]; if (0 <= samplePosition && samplePosition < numSamples) { count++; sum += samples[samplePosition]; } } newSamples[pos] = sum / count; } } return newSamples; } /** * Generate a Gaussian kernel. * * @param numRows * the number of rows in the data * @param numCols * the number of columns in the data * @param weightCenter * the weight the center of the kernel should have * * @return the Gaussian kernel */ public static int[] generateGaussianKernel(int numRows, int numCols, int weightCenter) { int[] kernel = new int[8 + weightCenter]; kernel[0] = -numCols - 1; kernel[1] = -numCols; kernel[2] = -numCols + 1; kernel[3] = -1; int pos = 4 + weightCenter; kernel[pos++] = 1; kernel[pos++] = numCols - 1; kernel[pos++] = numCols; kernel[pos] = numCols + 1; return kernel; } }