/* * Copyright 2010, 2011 Institut Pasteur. * * This file is part of NHerve Main Toolbox, which is an ICY plugin. * * NHerve Main Toolbox 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 3 of the License, or * (at your option) any later version. * * NHerve Main Toolbox 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. * * You should have received a copy of the GNU General Public License * along with NHerve Main Toolbox. If not, see <http://www.gnu.org/licenses/>. */ package plugins.nherve.toolbox.image.feature.region; import java.util.ArrayList; import java.util.List; import plugins.nherve.toolbox.Algorithm; import plugins.nherve.toolbox.image.BinaryIcyBufferedImage; import plugins.nherve.toolbox.image.feature.IcySupportRegion; import plugins.nherve.toolbox.image.feature.IcySupportRegionFactory; import plugins.nherve.toolbox.image.feature.Segmentable; import plugins.nherve.toolbox.image.mask.Mask; /** * The Class GridFactory. * * @author Nicolas HERVE - nicolas.herve@pasteur.fr */ public class GridFactory extends Algorithm implements IcySupportRegionFactory { /** The Constant ALGO_FIXED_SIZE. */ public final static int ALGO_FIXED_SIZE = 1; /** The Constant ALGO_FIXED_NB_SQUARE. */ public final static int ALGO_FIXED_NB_SQUARE = 2; /** The Constant ALGO_ON_ALL_PIXELS. */ public final static int ALGO_ON_ALL_PIXELS = 3; /** The Constant ALGO_ONLY_PIXELS. */ public final static int ALGO_ONLY_PIXELS = 4; /** The algorithm. */ private int algorithm; /** The length. */ private int length; /** The overlap. */ private int overlap; /** The center. */ private boolean center; /** * Instantiates a new grid factory. * * @param algo * the algo */ public GridFactory(int algo) { super(); this.algorithm = algo; setCenter(false); setLength(1); setOverlap(0); } /** * Extract regions all pixels. * * @param img * the img * @return the list * @throws SupportRegionException * the support region exception */ private List<IcySupportRegion> extractRegionsAllPixels(Segmentable img) throws SupportRegionException { if (length <= 0) { throw new SupportRegionException("Invalid region length (" + length + ")"); } int nbCol = img.getWidth(); int nbRow = img.getHeight(); ArrayList<IcySupportRegion> result = new ArrayList<IcySupportRegion>(); int x = 0; int y = 0; for (int i = 0; i < nbCol; i++) { y = 0; for (int j = 0; j < nbRow; j++) { result.add(new RectangleSupportRegion(img, x, y, length)); y += 1; } x += 1; } return result; } /** * Extract all pixels. * * @param img * the img * @return the list * @throws SupportRegionException * the support region exception */ private List<IcySupportRegion> extractAllPixels(Segmentable img) throws SupportRegionException { int nbCol = img.getWidth(); int nbRow = img.getHeight(); ArrayList<IcySupportRegion> result = new ArrayList<IcySupportRegion>(); for (int i = 0; i < nbCol; i+=length) { for (int j = 0; j < nbRow; j+=length) { result.add(new IcyPixel(i, j)); } } return result; } /** * Extract regions fixed size. * * @param img * the img * @return the list * @throws SupportRegionException * the support region exception */ private List<IcySupportRegion> extractRegionsFixedSize(Segmentable img) throws SupportRegionException { if (length <= 0) { throw new SupportRegionException("Invalid region length (" + length + ")"); } if (overlap >= length) { throw new SupportRegionException("Invalid overlap (" + overlap + " / " + length + ")"); } int uniqueLength = length - overlap; int nbCol = (int) Math.floor((float) img.getWidth() / (float) uniqueLength); int nbRow = (int) Math.floor((float) img.getHeight() / (float) uniqueLength); int xOffset = length / 2; int yOffset = length / 2; if (center) { xOffset += (img.getWidth() - nbCol * uniqueLength) / 2; yOffset += (img.getHeight() - nbRow * uniqueLength) / 2; } ArrayList<IcySupportRegion> result = new ArrayList<IcySupportRegion>(); int x = xOffset; int y = yOffset; for (int i = 0; i < nbCol; i++) { y = yOffset; for (int j = 0; j < nbRow; j++) { result.add(new RectangleSupportRegion(img, x, y, length)); y += uniqueLength; } x += uniqueLength; } return result; } /* (non-Javadoc) * @see plugins.nherve.toolbox.image.feature.SupportRegionFactory#extractRegions(plugins.nherve.toolbox.image.feature.Segmentable) */ @Override public List<IcySupportRegion> extractRegions(Segmentable img) throws SupportRegionException { log("Launching regions extraction ..."); List<IcySupportRegion> res = null; switch (algorithm) { case ALGO_FIXED_SIZE: res = extractRegionsFixedSize(img); break; case ALGO_ON_ALL_PIXELS: res = extractRegionsAllPixels(img); break; case ALGO_ONLY_PIXELS: res = extractAllPixels(img); break; case ALGO_FIXED_NB_SQUARE: default: throw new SupportRegionException("Algorithm(" + algorithm + ") not yet implemented"); } log("... " + res.size() + " regions found"); return res; } /** * Gets the length. * * @return the length */ public float getLength() { return length; } /** * Sets the length. * * @param length * the new length */ public void setLength(int length) { this.length = length; } /** * Checks if is center. * * @return true, if is center */ public boolean isCenter() { return center; } /** * Sets the center. * * @param center * the new center */ public void setCenter(boolean center) { this.center = center; } /* (non-Javadoc) * @see plugins.nherve.toolbox.image.feature.SupportRegionFactory#extractRegions(plugins.nherve.toolbox.image.feature.Segmentable, plugins.nherve.toolbox.image.mask.Mask) */ @Override public List<IcySupportRegion> extractRegions(Segmentable img, Mask mask) throws SupportRegionException { log("Launching regions extraction ..."); List<IcySupportRegion> allRegions = extractRegions(img); List<IcySupportRegion> filteredRegions = new ArrayList<IcySupportRegion>(); for (IcySupportRegion sr : allRegions) { if (sr.intersects(mask)) { filteredRegions.add(sr); } } log("... " + filteredRegions.size() + " regions found"); return filteredRegions; } /** * Gets the mask as pixels. * * @param m * the m * @return the mask as pixels */ public static List<IcyPixel> getMaskAsPixels(Mask m) { byte[] b = m.getBinaryData().getRawData(); int w = m.getWidth(); int h = m.getHeight(); ArrayList<IcyPixel> result = new ArrayList<IcyPixel>(); int idx = 0; for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { if (b[idx] == BinaryIcyBufferedImage.TRUE) { result.add(new IcyPixel(x, y)); } idx++; } } return result; } public static List<IcyPixel> getAllPixels(Segmentable img) { int w = img.getWidth(); int h = img.getHeight(); ArrayList<IcyPixel> result = new ArrayList<IcyPixel>(); for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { result.add(new IcyPixel(x, y)); } } return result; } /** * Gets the overlap. * * @return the overlap */ public int getOverlap() { return overlap; } /** * Sets the overlap. * * @param overlap * the new overlap */ public void setOverlap(int overlap) { this.overlap = overlap; } }