use of org.hortonmachine.lesto.modules.vegetation.watershed.WatershedFIFO in project hortonmachine by TheHortonMachine.
the class WatershedAlgorithm method process.
@Execute
public void process() throws Exception {
checkNull(inRaster, outRaster);
GridCoverage2D inRasterGC = getRaster(inRaster);
RegionMap regionMap = CoverageUtilities.getRegionParamsFromGridCoverage(inRasterGC);
int nCols = regionMap.getCols();
int nRows = regionMap.getRows();
byte[] input = CoverageUtilities.renderedImage2ByteArray(inRasterGC.getRenderedImage(), true);
/**
* First step : the pixels are sorted according to increasing grey values *
*/
WatershedStructure watershedStructure = new WatershedStructure(input, nCols, nRows, pm);
/**
* Start flooding *
*/
WatershedFIFO queue = new WatershedFIFO();
int curlab = 0;
int heightIndex1 = 0;
int heightIndex2 = 0;
for (int h = 0; h < 256; h++) /*Geodesic SKIZ of level h-1 inside level h */
{
for (int pixelIndex = heightIndex1; pixelIndex < watershedStructure.size(); pixelIndex++) /*mask all pixels at level h*/
{
WatershedPixel p = watershedStructure.get(pixelIndex);
if (p.getIntHeight() != h) {
/**
* This pixel is at level h+1 *
*/
heightIndex1 = pixelIndex;
break;
}
p.setLabelToMASK();
List<WatershedPixel> neighbours = p.getNeighbours();
for (int i = 0; i < neighbours.size(); i++) {
WatershedPixel q = (WatershedPixel) neighbours.get(i);
if (q.getLabel() >= 0) {
/*Initialise queue with neighbours at level h of current basins or watersheds*/
p.setDistance(1);
queue.fifo_add(p);
break;
}
// end if
}
// end for
}
// end for
int curdist = 1;
queue.fifo_add_FICTITIOUS();
while (true) /**
* extend basins *
*/
{
WatershedPixel p = queue.fifo_remove();
if (p.isFICTITIOUS())
if (queue.fifo_empty())
break;
else {
queue.fifo_add_FICTITIOUS();
curdist++;
p = queue.fifo_remove();
}
List<WatershedPixel> neighbours = p.getNeighbours();
for (int i = 0; i < neighbours.size(); i++) /* Labelling p by inspecting neighbours */
{
WatershedPixel q = (WatershedPixel) neighbours.get(i);
/* Original algorithm :
if( (q.getDistance() < curdist) &&
(q.getLabel()>0 || q.isLabelWSHED()) ) {*/
if ((q.getDistance() <= curdist) && (q.getLabel() >= 0)) {
if (q.getLabel() > 0) {
if (p.isLabelMASK())
// Removed from original algorithm || p.isLabelWSHED() )
p.setLabel(q.getLabel());
else if (p.getLabel() != q.getLabel())
p.setLabelToWSHED();
} else // end if lab>0
if (p.isLabelMASK())
p.setLabelToWSHED();
} else if (q.isLabelMASK() && (q.getDistance() == 0)) {
q.setDistance(curdist + 1);
queue.fifo_add(q);
}
}
// end for, end processing neighbours
}
/* Detect and process new minima at level h */
for (int pixelIndex = heightIndex2; pixelIndex < watershedStructure.size(); pixelIndex++) {
WatershedPixel p = watershedStructure.get(pixelIndex);
if (p.getIntHeight() != h) {
/**
* This pixel is at level h+1 *
*/
heightIndex2 = pixelIndex;
break;
}
p.setDistance(0);
if (p.isLabelMASK()) {
/* the pixel is inside a new minimum */
curlab++;
p.setLabel(curlab);
queue.fifo_add(p);
while (!queue.fifo_empty()) {
WatershedPixel q = queue.fifo_remove();
List<WatershedPixel> neighbours = q.getNeighbours();
for (int i = 0; i < neighbours.size(); i++) /* inspect neighbours of p2*/
{
WatershedPixel r = (WatershedPixel) neighbours.get(i);
if (r.isLabelMASK()) {
r.setLabel(curlab);
queue.fifo_add(r);
}
}
}
// end while
}
// end if
}
// end for
}
/**
* End of flooding *
*/
WritableRaster outWR = CoverageUtilities.createWritableRaster(nCols, nRows, null, null, doubleNovalue);
WritableRandomIter outIter = RandomIterFactory.createWritable(outWR, null);
pm.beginTask("Setting watersheds...", watershedStructure.size());
for (int pixelIndex = 0; pixelIndex < watershedStructure.size(); pixelIndex++) {
WatershedPixel p = watershedStructure.get(pixelIndex);
int c = p.getX();
int r = p.getY();
if (p.isLabelWSHED() && !p.allNeighboursAreWSHED()) {
if (doBorders)
outIter.setSample(c, r, 0, 1.0);
} else {
if (!doBorders)
outIter.setSample(c, r, 0, 1.0);
}
pm.worked(1);
}
pm.done();
outIter.done();
GridCoverage2D outRasterGC = CoverageUtilities.buildCoverage("normalized", outWR, regionMap, inRasterGC.getCoordinateReferenceSystem());
dumpRaster(outRasterGC, outRaster);
}
Aggregations