package edu.oregonstate.cartography.grid; import java.util.ArrayList; /** * Gaussian pyramid. * * @author Bernhard Jenny, Institute of Cartography, ETH Zurich. */ public class GaussianPyramid { private static int MIN_SIDE_LENGTH = 2; private final Grid[] pyramid; public static Grid[] createPyramid(Grid geoGrid, int maxLevelsCount) { return GaussianPyramid.createPyramid(geoGrid, maxLevelsCount, MIN_SIDE_LENGTH * MIN_SIDE_LENGTH); } public static Grid[] createPyramid(Grid geoGrid, int maxLevelsCount, int minCellCount) { ArrayList<Grid> pyramid = new ArrayList<>(); pyramid.add(geoGrid); Convolution5x5 conv = new Convolution5x5(); for (;;) { if (geoGrid == null) { break; } int newCols = geoGrid.getCols() / 2; int newRows = geoGrid.getRows() / 2; if (newCols <= MIN_SIDE_LENGTH || newRows <= MIN_SIDE_LENGTH || newCols * newRows < minCellCount || pyramid.size() == maxLevelsCount) { break; } geoGrid = conv.convolveToHalfSize(geoGrid); pyramid.add(geoGrid); } return pyramid.toArray(new Grid[pyramid.size()]); } public GaussianPyramid(Grid geoGrid) { this.pyramid = GaussianPyramid.createPyramid(geoGrid, 9999); } public GaussianPyramid(Grid geoGrid, int maxLevelsCount) { this.pyramid = GaussianPyramid.createPyramid(geoGrid, maxLevelsCount); } public GaussianPyramid(Grid geoGrid, int maxLevelsCount, int minCellCount) { this.pyramid = GaussianPyramid.createPyramid(geoGrid, maxLevelsCount, minCellCount); } public Grid[] getPyramid() { return this.pyramid; } public Grid[] getExpandedPyramid() { Grid[] expandedPyramid = new Grid[pyramid.length]; for (int i = 0; i < pyramid.length; i++) { expandedPyramid[i] = pyramid[i]; for (int k = 0; k < i; k++) { expandedPyramid[i] = LaplacianPyramid.expand(expandedPyramid[i], expandedPyramid[i].getCols() * 2, expandedPyramid[i].getRows() * 2); } } return expandedPyramid; } public Grid getFullResolutionLevel() { return this.pyramid[0]; } /** * Returns a grid at a specified pyramid level. The full resolution grid has * level 0, the lowest resolution grid has level getLevelsCount() - 1 * * @param level * @return Grid at requested level */ public Grid getLevel(int level) { return this.pyramid[level]; } public int getLevelsCount() { return this.pyramid.length; } public float getValue(int col, int row, int pyramidLevel) { return this.pyramid[pyramidLevel].getValue(col, row); } }