Perimeter.java

package ac.essex.ooechs.imaging.commons.texture; 
 
import ac.essex.ooechs.imaging.commons.PixelLoader; 
import ac.essex.ooechs.imaging.commons.Pixel; 
import ac.essex.ooechs.imaging.commons.StatisticsSolver; 
import ac.essex.ooechs.imaging.commons.fast.FastStatistics; 
 
import java.util.Vector; 
import java.util.ArrayList; 
 
/** 
 * Provides statistics about a single-pixel-thickness set of pixels 
 * which are a certain radius from the central pixel. The statistics are: 
 * mean, standard deviation and edge count. Because this set of pixels 
 * is the circular, they will provide the same output even when the image 
 * is rotated, which makes it useful for detecting a set of objects which are not 
 * all facing the same way. 
 * <p/> 
 * <p/> 
 * This program is free software; you can redistribute it and/or 
 * modify it under the terms of the GNU General Public License 
 * as published by the Free Software Foundation; either version 2 
 * of the License, or (at your option) any later version, 
 * provided that any use properly credits the author. 
 * This program is distributed in the hope that it will be useful, 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
 * GNU General Public License for more details at http://www.gnu.org 
 * </p> 
 * 
 * // TODO - Also want to calculate edgecount 
 * 
 * @author Olly Oechsle, University of Essex, Date: 04-Jul-2007 
 * @version 1.0 
 */ 
public class Perimeter implements AbstractShape { 
 
    public double[][] mean; 
    public double[][] stddev; 
    public int[] edgeCount; 
 
    protected ArrayList<Pixel> mask; 
    protected int[] maskX, maskY; 
    protected int c; 
 
    public static void main(String[] args) throws Exception { 
        PixelLoader image = new PixelLoader("/home/ooechs/Desktop/Lenna.png"); 
        StatisticsSolver s = new StatisticsSolver(11); 
        for (int t = 0; t <= 10; t++) { 
            long start = System.currentTimeMillis(); 
            for (int y = 0; y < image.getHeight(); y++) 
            for (int x = 0; x < image.getHeight(); x++) { 
                //image.getPerimeter2().getStatistics(image, 50, 50).getMean(); 
                image.getPerimeter2().getMean(image, x, y); 
            } 
            long end = System.currentTimeMillis(); 
            long time = end - start; 
            if (t > 0) s.addData(time); 
            System.out.println(time); 
        } 
 
        System.out.println(s.getMean() + " | " + s.getStandardDeviation()); 
    } 
 
    public Perimeter(int radius) { 
 
        // calculate masks for each radius 
        int size = radius + radius + 1; 
        maskX = new int[6 * radius]; 
        maskY = maskX.clone(); 
        c = 0; 
 
        for (int y = 0; y < size; y++) { 
            for (int x = 0; x < size; x++) { 
 
                int dx = x - radius; 
                int dy = y - radius; 
 
                double dist = Math.sqrt((dx * dx) + (dy * dy)); 
 
                double diff = dist - radius; 
 
                double T = 0.5; 
 
                if (diff < T && diff > -T) { 
                    maskX[c] = dx; 
                    maskY[c] = dy; 
                    c++; 
                } 
 
            } 
        } 
 
    } 
 
    public FastStatistics getStatistics(PixelLoader image, int x, int y) { 
 
        FastStatistics solver = new FastStatistics(); 
 
        for (int i = 0; i < c; i++) { 
            try { 
                solver.addData(image.getGreyValue(x + maskX[i], y + maskY[i])); 
            } catch (Exception e) { 
            } 
        } 
 
        return solver; 
 
    } 
 
    public float getMean(PixelLoader image, int x, int y) { 
 
        float total = 0; 
        int n = 0; 
 
        for (int i = 0; i < c; i++) { 
            try { 
                total += image.getGreyValue(x + maskX[i], y + maskY[i]); 
                n++; 
            } catch (Exception e) { 
            } 
        } 
 
        return total / n; 
 
    } 
 
 
}