ConvexityDescriptor.java

Go to the documentation of this file.
00001 package theba.descriptors;
00002 
00003 import java.awt.Point;
00004 import java.awt.Polygon;
00005 
00006 import theba.core.ImageFunctions;
00007 import theba.core.RegionDescriptor;
00008 import theba.core.RegionMask;
00009 
00010 
00011 public class ConvexityDescriptor implements RegionDescriptor {
00012         public String getName() {
00013                 return "Convexity";
00014         }
00015 
00026         public static double getSolidity(short[] data, int width, int height) {
00027                 Polygon pout = getConvexRegion(data, width, height);
00028                 int cnt = 0;
00029                 int convcnt = 0;
00030                 for (int xx = 0; xx < width; xx++) {
00031                         for (int yy = 0; yy < height; yy++) {
00032                                 if (data[xx + yy * width] != 0) {
00033                                         cnt++;
00034                                 }
00035                                 if (pout.contains(xx, yy))
00036                                         convcnt++;
00037                         }
00038                 }
00039                 if (convcnt == 0)
00040                         return 0;
00041                 return (cnt / (double) convcnt);
00042         }
00043 
00044         public static Polygon getConvexRegion(short[] data, int width, int height) {
00045                 int counter = 0;
00046                 int i, j, k = 0, m;
00047                 for (j = 0; j < width; j++) {
00048                         for (i = 0; i < height; i++) {
00049                                 if (data[j + i * width] != 0)
00050                                         counter++;
00051                         }
00052                 }
00053                 int[] x = new int[counter + 1];
00054                 int[] y = new int[counter + 1];
00055                 for (j = 0; j < width; j++) {
00056                         for (i = 0; i < height; i++) {
00057                                 if (data[j + i * width] != 0) {
00058                                         x[k] = i;
00059                                         y[k] = j;
00060                                         k++;
00061                                 }
00062                         }
00063                 }
00064                 // cnvx hull
00065                 int n = counter, min = 0, ney = 0, h, h2, dx, dy, temp, ax, ay;
00066                 double minangle, th, t, v, zxmi = 0;
00067                 for (i = 1; i < n; i++) {
00068                         if (y[i] < y[min])
00069                                 min = i;
00070                 }
00071                 temp = x[0];
00072                 x[0] = x[min];
00073                 x[min] = temp;
00074                 temp = y[0];
00075                 y[0] = y[min];
00076                 y[min] = temp;
00077                 min = 0;
00078                 for (i = 1; i < n; i++) {
00079                         if (y[i] == y[0]) {
00080                                 ney++;
00081                                 if (x[i] < x[min])
00082                                         min = i;
00083                         }
00084                 }
00085                 temp = x[0];
00086                 x[0] = x[min];
00087                 x[min] = temp;
00088                 temp = y[0];
00089                 y[0] = y[min];
00090                 y[min] = temp;
00091                 min = 0;
00092                 m = -1;
00093                 x[n] = x[min];
00094                 y[n] = y[min];
00095                 if (ney > 0)
00096                         minangle = -1;
00097                 else
00098                         minangle = 0;
00099                 while (min != n + 0) {
00100                         m = m + 1;
00101                         temp = x[m];
00102                         x[m] = x[min];
00103                         x[min] = temp;
00104                         temp = y[m];
00105                         y[m] = y[min];
00106                         y[min] = temp;
00107                         min = n; // +1
00108                         v = minangle;
00109                         minangle = 360.0;
00110                         h2 = 0;
00111                         for (i = m + 1; i < n + 1; i++) {
00112                                 dx = x[i] - x[m];
00113                                 ax = Math.abs(dx);
00114                                 dy = y[i] - y[m];
00115                                 ay = Math.abs(dy);
00116                                 if (dx == 0 && dy == 0)
00117                                         t = 0.0;
00118                                 else
00119                                         t = (double) dy / (double) (ax + ay);
00120                                 if (dx < 0)
00121                                         t = 2.0 - t;
00122                                 else {
00123                                         if (dy < 0)
00124                                                 t = 4.0 + t;
00125                                 }
00126                                 th = t * 90.0;
00127                                 if (th > v) {
00128                                         if (th < minangle) {
00129                                                 min = i;
00130                                                 minangle = th;
00131                                                 h2 = dx * dx + dy * dy;
00132                                         } else {
00133                                                 if (th == minangle) {
00134                                                         h = dx * dx + dy * dy;
00135                                                         if (h > h2) {
00136                                                                 min = i;
00137                                                                 h2 = h;
00138                                                         }
00139                                                 }
00140                                         }
00141                                 }
00142                         }
00143                         zxmi = zxmi + Math.sqrt(h2);
00144                 }
00145                 m++;
00146                 int[] hx = new int[m];// ROI polygon array
00147                 int[] hy = new int[m];
00148                 for (i = 0; i < m; i++) {
00149                         hx[i] = x[i]; // copy to new polygon array
00150                         hy[i] = y[i];
00151                 }
00152                 // Merk at vi må flippe y og x for at koordinatene ikke skal bli vridd
00153                 Polygon pout = new Polygon(hy, hx, hx.length); // ny output
00154                 return pout;
00155         }
00156 
00165         public static double getConvexity(short[] data, int width, int height) {
00166                 Polygon pout = getConvexRegion(data, width, height);
00167                 int cnt = 0;
00168                 int convcnt = 0;
00169                 for (int xx = 0; xx < width; xx++) {
00170                         for (int yy = 0; yy < height; yy++) {
00171                                 if (data[xx + yy * width] != 0) {
00172                                         cnt++;
00173                                 }
00174                                 if (pout.contains(xx, yy))
00175                                         convcnt++;
00176                         }
00177                 }
00178                 Point start = null;
00179                 for (int xx = 0; xx < width; xx++) {
00180                         for (int yy = 0; yy < height; yy++) {
00181                                 if (data[xx + yy * width] != 0) {
00182                                         start = new Point(xx, yy);
00183                                         xx = width;
00184                                         yy = height;
00185                                 }
00186                         }
00187                 }
00188                 for (int xx = 0; xx < width; xx++) {
00189                         for (int yy = 0; yy < height; yy++) {
00190                                 if (data[xx + yy * width] != 0)
00191                                         data[xx + yy * width] = (byte) 150;
00192                         }
00193                 }
00194                 if (start == null) {
00195                         System.out.println("No region found!");
00196                         return 0.0;
00197                 }
00198                 int count1 = ImageFunctions.countOutlinePixels(data, start.x, start.y,
00199                                 width, height, (byte) 100);
00200                 short[] data2 = new short[data.length];
00201                 for (int xx = 0; xx < width; xx++) {
00202                         for (int yy = 0; yy < height; yy++) {
00203                                 if (pout.contains(xx, yy))
00204                                         data2[xx + yy * width] = (byte) 0x150;
00205                                 else
00206                                         data2[xx + yy * width] = 0;
00207                         }
00208                 }
00209                 int count2 = ImageFunctions.countOutlinePixels(data2, start.x, start.y,
00210                                 width, height, (byte) 100);
00211                 return (count2 / (double) count1);
00212         }
00213 
00214         public Object measure(RegionMask vmask) {
00215                 short[] mask = new short[vmask.getWidth() * vmask.getHeight()];
00216                 for (int x = 0; x < vmask.getWidth(); x++)
00217                         for (int y = 0; y < vmask.getHeight(); y++)
00218                                 if (vmask.isSet(x, y, 0))
00219                                         mask[x + y * vmask.getWidth()] = 1;
00220                 return getConvexity(mask, vmask.getWidth(), vmask.getHeight());
00221         }
00222 
00223         public String getAbout() {
00224                 return "Returns the convexity area of a 2D-shape";
00225         }
00226 
00227         public boolean does3D() {
00228                 return false;
00229         }
00230 
00231         public boolean isNumeric() {
00232                 return true;
00233         }
00234 }

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