BackTrack.java

Go to the documentation of this file.
00001 package theba.core;
00002 
00003 import java.awt.Rectangle;
00004 
00013 public class BackTrack {
00014 
00015         static short[] queuex;
00016 
00017         static short[] queuey;
00018 
00019         static boolean[][] mark;
00020 
00021         static int first, last; // Pointers to first and last element in queue
00022 
00023         static final int overflow = 1000; // Max size of queue
00024 
00025         static int xx, yy; // Image dimensions
00026 
00027         static int px, py; // Queue pointers
00028 
00029         static int max;
00030 
00031         static int val;
00032 
00033         static short[] lumens; // Lumen image
00034 
00035         static int[] histogram;
00036 
00050         public static short[] backTrack(short[] lumens_, int max, int width,
00051                         int height, Rectangle bounds) {
00052 
00053                 queuex = new short[overflow];
00054                 queuey = new short[overflow];
00055 
00056                 xx = width;
00057                 yy = height;
00058 
00059                 lumens = lumens_;
00060 
00061                 mark = new boolean[width][height];
00062 
00063                 for (int y = 0; y < yy; y++) {
00064                         for (int x = 0; x < xx; x++) {
00065                                 if ((lumens[y * width + x] & 0xff) == max) { // Do backtracking with floodfill
00066                                         histogram = new int[max + 1];
00067                                         seed(x, y); // Seeds and creates histogram
00068                                         // Find minima in histogram
00069                                         int min = Integer.MAX_VALUE;
00070                                         int nr = 0;
00071                                         for (int t = 2; t < histogram.length; t++) {
00072                                                 if (histogram[t] < min) {
00073                                                         min = histogram[t];
00074                                                         nr = t;
00075                                                 }
00076                                         }
00077                                         // Remove pixels outside crack-point
00078                                         remove(nr, false);
00079                                 }
00080                         }
00081                 }
00082                 remove(100, true);
00083                 return lumens;
00084 
00085         }
00086 
00098         public static void remove(int remove, boolean last) {
00099                 for (int y = 0; y < yy; y++) {
00100                         for (int x = 0; x < xx; x++) {
00101                                 if ((lumens[y * xx + x] & 0xff) >= 50 + remove) {
00102                                         lumens[y * xx + x] = (byte) 0;
00103                                 }
00104                                 if (last && (lumens[y * xx + x] & 0xff) > 1) {
00105                                         lumens[y * xx + x] = (byte) 1;
00106                                 }
00107                         }
00108                 }
00109         }
00110 
00119         public static void seed(int x, int y) {
00120                 int p;
00121 
00122                 max = 0;
00123                 push(x, y);
00124                 while (first != last) {
00125                         p = pop();
00126                         px = queuex[p];
00127                         py = queuey[p];
00128                         val = lumens[py * xx + px] & 0xff;
00129                         histogram[val]++;
00130                         lumens[py * xx + px] = (byte) (50 + val);
00131 
00132                         // Add new points to queue:
00133                         if (px - 1 >= 0) {
00134                                 if (!mark[px - 1][py]
00135                                                 && (lumens[py * xx + px - 1] & 0xff) <= val
00136                                                 && (lumens[py * xx + px - 1] & 0xff) > 1) {
00137                                         push(px - 1, py);
00138                                         mark[px - 1][py] = true;
00139                                 }
00140                         }
00141                         if (px + 1 < xx) {
00142                                 if (!mark[px + 1][py]
00143                                                 && (lumens[py * xx + px + 1] & 0xff) <= val
00144                                                 && (lumens[py * xx + px + 1] & 0xff) > 1) {
00145                                         push(px + 1, py);
00146                                         mark[px + 1][py] = true;
00147                                 }
00148                         }
00149                         if (py - 1 >= 0) {
00150                                 if (!mark[px][py - 1]
00151                                                 && (lumens[(py - 1) * xx + px] & 0xff) <= val
00152                                                 && (lumens[(py - 1) * xx + px] & 0xff) > 1) {
00153                                         push(px, py - 1);
00154                                         mark[px][py - 1] = true;
00155                                 }
00156                         }
00157                         if (py + 1 < yy) {
00158                                 if (!mark[px][py + 1]
00159                                                 && (lumens[(py + 1) * xx + px] & 0xff) <= val
00160                                                 && (lumens[(py + 1) * xx + px] & 0xff) > 1) {
00161                                         push(px, py + 1);
00162                                         mark[px][py + 1] = true;
00163                                 }
00164                         }
00165                         if (py + 1 < yy && px - 1 >= 0) {
00166                                 if (!mark[px - 1][py + 1]
00167                                                 && (lumens[(py + 1) * xx + px - 1] & 0xff) <= val
00168                                                 && (lumens[(py + 1) * xx + px - 1] & 0xff) > 1) {
00169                                         push(px - 1, py + 1);
00170                                         mark[px - 1][py + 1] = true;
00171                                 }
00172                         } // 8-connected
00173                         if (px + 1 < xx && py + 1 < yy) {
00174                                 if (!mark[px + 1][py + 1]
00175                                                 && (lumens[(py + 1) * xx + px + 1] & 0xff) <= val
00176                                                 && (lumens[(py + 1) * xx + px + 1] & 0xff) > 1) {
00177                                         push(px + 1, py + 1);
00178                                         mark[px + 1][py + 1] = true;
00179                                 }
00180                         } // 8-connected
00181                         if (px - 1 >= 0 && py - 1 >= 0) {
00182                                 if (!mark[px - 1][py - 1]
00183                                                 && (lumens[(py - 1) * xx + px - 1] & 0xff) <= val
00184                                                 && (lumens[(py - 1) * xx + px - 1] & 0xff) > 1) {
00185                                         push(px - 1, py - 1);
00186                                         mark[px - 1][py - 1] = true;
00187                                 }
00188                         } // 8-connected
00189                         if (py - 1 >= 0 && px + 1 < xx) {
00190                                 if (!mark[px + 1][py - 1]
00191                                                 && (lumens[(py - 1) * xx + px + 1] & 0xff) <= val
00192                                                 && (lumens[(py - 1) * xx + px + 1] & 0xff) > 1) {
00193                                         push(px + 1, py - 1);
00194                                         mark[px + 1][py - 1] = true;
00195                                 }
00196                         } // 8-connected
00197                 }
00198         }
00199 
00205         public static int pop() {
00206                 first++;
00207                 if (first == overflow) {
00208                         first = 0;
00209                         return overflow - 1;
00210                 }
00211                 return first - 1;
00212         }
00213 
00222         public static void push(int x, int y) {
00223                 queuex[last] = (short) x;
00224                 queuey[last] = (short) y;
00225                 last++;
00226                 if (last == overflow) {
00227                         last = 0;
00228                 }
00229                 if (last < first) {
00230                         if (last + overflow - first > max) {
00231                                 max = last + overflow - first;
00232                         }
00233                 } else if (last - first > max) {
00234                         max = last - first;
00235                 }
00236                 if (last == first) {
00237                         System.out.println("Queue overflow");
00238                         System.exit(1);
00239                 }
00240         }
00241 }

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