Watershed_Algorithm.java

Go to the documentation of this file.
00001 package watershed;
00002 
00003 import java.util.ArrayList;
00004 
00005 /*
00006  * Watershed algorithm
00007  *
00008  * Copyright (c) 2003 by Christopher Mei (christopher.mei@sophia.inria.fr)
00009  *
00010  * This plugin is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License version 2 
00012  * as published by the Free Software Foundation.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this plugin; if not, write to the Free Software
00021  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00022  */
00023 
00066 public class Watershed_Algorithm {
00067 
00068         final static int HMIN = 0;
00069 
00070         final static int HMAX = 256;
00071 
00072         int width, height;
00073 
00074         public void run(short[] pixels, int width, int height) {
00075                 this.width = width;
00076                 this.height = height;
00077 
00082                 WatershedStructure watershedStructure = new WatershedStructure(pixels,
00083                                 width, height);
00084 
00086                 WatershedFIFO queue = new WatershedFIFO();
00087                 int curlab = 0;
00088 
00089                 int heightIndex1 = 0;
00090                 int heightIndex2 = 0;
00091 
00092                 for (int h = HMIN; h < HMAX; h++) /*
00093                                                                                          * Geodesic SKIZ of level h-1 inside
00094                                                                                          * level h
00095                                                                                          */{
00096 
00097                         for (int pixelIndex = heightIndex1; pixelIndex < watershedStructure
00098                                         .size(); pixelIndex++) /* mask all pixels at level h */{
00099                                 WatershedPixel p = watershedStructure.get(pixelIndex);
00100 
00101                                 if (p.getIntHeight() != h) {
00103                                         heightIndex1 = pixelIndex;
00104                                         break;
00105                                 }
00106 
00107                                 p.setLabelToMASK();
00108 
00109                                 ArrayList neighbours = p.getNeighbours();
00110                                 for (int i = 0; i < neighbours.size(); i++) {
00111                                         WatershedPixel q = (WatershedPixel) neighbours.get(i);
00112 
00113                                         if (q.getLabel() >= 0) {/*
00114                                                                                          * Initialise queue with neighbours
00115                                                                                          * at level h of current basins or
00116                                                                                          * watersheds
00117                                                                                          */
00118                                                 p.setDistance(1);
00119                                                 queue.fifo_add(p);
00120                                                 break;
00121                                         } // end if
00122                                 } // end for
00123                         } // end for
00124 
00125                         int curdist = 1;
00126                         queue.fifo_add_FICTITIOUS();
00127 
00128                         while (true) 
00129                         {
00130                                 WatershedPixel p = queue.fifo_remove();
00131 
00132                                 if (p.isFICTITIOUS())
00133                                         if (queue.fifo_empty()) {
00134                                                 break;
00135                                         } else {
00136                                                 queue.fifo_add_FICTITIOUS();
00137                                                 curdist++;
00138                                                 p = queue.fifo_remove();
00139                                         }
00140 
00141                                 ArrayList neighbours = p.getNeighbours();
00142                                 for (int i = 0; i < neighbours.size(); i++) /*
00143                                                                                                                          * Labelling p by
00144                                                                                                                          * inspecting
00145                                                                                                                          * neighbours
00146                                                                                                                          */{
00147                                         WatershedPixel q = (WatershedPixel) neighbours.get(i);
00148 
00149                                         if ((q.getDistance() <= curdist) && (q.getLabel() >= 0)) {
00150                                                 /* q belongs to an existing basin or to a watershed */
00151 
00152                                                 if (q.getLabel() > 0) {
00153                                                         if (p.isLabelMASK())
00154                                                                 // Removed from original algorithm ||
00155                                                                 // p.isLabelWSHED() )
00156                                                                 p.setLabel(q.getLabel());
00157                                                         else if (p.getLabel() != q.getLabel())
00158                                                                 p.setLabelToWSHED();
00159                                                 } // end if lab>0
00160                                                 else if (p.isLabelMASK())
00161                                                         p.setLabelToWSHED();
00162                                         } else if (q.isLabelMASK() && (q.getDistance() == 0)) {
00163 
00164                                                 q.setDistance(curdist + 1);
00165                                                 queue.fifo_add(q);
00166                                         }
00167                                 } // end for, end processing neighbours
00168 
00169                         } // end while (loop)
00170 
00171                         /* Detect and process new minima at level h */
00172                         for (int pixelIndex = heightIndex2; pixelIndex < watershedStructure
00173                                         .size(); pixelIndex++) {
00174                                 WatershedPixel p = watershedStructure.get(pixelIndex);
00175 
00176                                 if (p.getIntHeight() != h) {
00178                                         heightIndex2 = pixelIndex;
00179                                         break;
00180                                 }
00181 
00182                                 p.setDistance(0); /* Reset distance to zero */
00183 
00184                                 if (p.isLabelMASK()) { /* the pixel is inside a new minimum */
00185                                         curlab++;
00186                                         p.setLabel(curlab);
00187                                         queue.fifo_add(p);
00188 
00189                                         while (!queue.fifo_empty()) {
00190                                                 WatershedPixel q = queue.fifo_remove();
00191 
00192                                                 ArrayList neighbours = q.getNeighbours();
00193 
00194                                                 for (int i = 0; i < neighbours.size(); i++) /*
00195                                                                                                                                          * inspect
00196                                                                                                                                          * neighbours
00197                                                                                                                                          * of p2
00198                                                                                                                                          */{
00199                                                         WatershedPixel r = (WatershedPixel) neighbours
00200                                                                         .get(i);
00201 
00202                                                         if (r.isLabelMASK()) {
00203                                                                 r.setLabel(curlab);
00204                                                                 queue.fifo_add(r);
00205                                                         }
00206                                                 }
00207                                         } // end while
00208                                 } // end if
00209                         } // end for
00210                 }
00213                 byte[] newPixels = new byte[pixels.length];
00214 
00215                 for (int pixelIndex = 0; pixelIndex < watershedStructure.size(); pixelIndex++) {
00216                         WatershedPixel p = watershedStructure.get(pixelIndex);
00217 
00218                         if (p.isLabelWSHED() && !p.allNeighboursAreWSHED())
00219                                 newPixels[p.getX() + p.getY() * width] = (byte) 255;
00220                 }
00221                 for (int i = 0; i < pixels.length; i++)
00222                         pixels[i] = newPixels[i];
00223         }
00224 
00225 }

Generated on Fri Nov 13 08:57:08 2009 for Theba by  doxygen 1.6.1