package org.jgrasstools.lesto.modules.vegetation.watershed;
/*
* Watershed algorithm
*
* Copyright (c) 2003 by Christopher Mei (christopher.mei@sophia.inria.fr)
*
* This plugin is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this plugin; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.jgrasstools.gears.libs.monitor.IJGTProgressMonitor;
/**
* WatershedStructure contains the pixels
* of the image ordered according to their
* grayscale value with a direct access to their
* neighbours.
*
**/
public class WatershedStructure {
private List<WatershedPixel> watershedStructure;
public WatershedStructure( byte[] pixels, int cols, int rows, IJGTProgressMonitor pm ) {
int offset, topOffset, bottomOffset, i;
watershedStructure = new ArrayList<WatershedPixel>(cols * rows);
/** The structure is filled with the pixels of the image. **/
pm.beginTask("Fill Watershed structure...", rows);
for( int r = 0; r < rows; r++ ) {
offset = r * cols;
for( int c = 0; c < cols; c++ ) {
i = offset + c;
int indiceY = r;
int indiceX = c;
watershedStructure.add(new WatershedPixel(indiceX, indiceY, pixels[i]));
}
pm.worked(1);
}
pm.done();
/** The WatershedPixels are then filled with the reference to their neighbours. **/
pm.beginTask("Add neighbours references...", rows);
for( int r = 0; r < rows; r++ ) {
offset = r * cols;
topOffset = offset + cols;
bottomOffset = offset - cols;
for( int c = 0; c < cols; c++ ) {
WatershedPixel currentPixel = (WatershedPixel) watershedStructure.get(c + offset);
if (c + 1 < cols) {
currentPixel.addNeighbour((WatershedPixel) watershedStructure.get(c + 1 + offset));
if (r - 1 >= 0)
currentPixel.addNeighbour((WatershedPixel) watershedStructure.get(c + 1 + bottomOffset));
if (r + 1 < rows)
currentPixel.addNeighbour((WatershedPixel) watershedStructure.get(c + 1 + topOffset));
}
if (c - 1 >= 0) {
currentPixel.addNeighbour((WatershedPixel) watershedStructure.get(c - 1 + offset));
if (r - 1 >= 0)
currentPixel.addNeighbour((WatershedPixel) watershedStructure.get(c - 1 + bottomOffset));
if (r + 1 < rows)
currentPixel.addNeighbour((WatershedPixel) watershedStructure.get(c - 1 + topOffset));
}
if (r - 1 >= 0)
currentPixel.addNeighbour((WatershedPixel) watershedStructure.get(c + bottomOffset));
if (r + 1 < rows)
currentPixel.addNeighbour((WatershedPixel) watershedStructure.get(c + topOffset));
}
pm.worked(1);
}
pm.done();
Collections.sort(watershedStructure);
}
public String toString() {
StringBuffer ret = new StringBuffer();
for( int i = 0; i < watershedStructure.size(); i++ ) {
ret.append(((WatershedPixel) watershedStructure.get(i)).toString());
ret.append("\n");
ret.append("Neighbours :\n");
List<WatershedPixel> neighbours = watershedStructure.get(i).getNeighbours();
for( int j = 0; j < neighbours.size(); j++ ) {
ret.append(neighbours.get(j).toString());
ret.append("\n");
}
ret.append("\n");
}
return ret.toString();
}
public int size() {
return watershedStructure.size();
}
public WatershedPixel get( int i ) {
return (WatershedPixel) watershedStructure.get(i);
}
}