OrientationDescriptor.java

Go to the documentation of this file.
00001 package theba.descriptors;
00002 
00003 import java.awt.Graphics2D;
00004 import java.awt.image.BufferedImage;
00005 
00006 import theba.core.RegionDescriptor;
00007 import theba.core.RegionMask;
00008 import theba.core.gui.ThebaGUI;
00009 
00010 
00011 public class OrientationDescriptor implements RegionDescriptor {
00012 
00013         public String getName() {
00014                 return "Orientation (2D)";
00015         }
00016 
00017         public String getAbout() {
00018                 return "Returns the orientation of the region based on the covariance matrix eigenvectors";
00019         }
00020 
00021         public boolean does3D() {
00022                 return false;
00023         }
00024 
00025         public boolean isNumeric() {
00026                 return false;
00027         }
00028 
00029         class FloatPair {
00030                 public FloatPair(double x, double y) {
00031                         this.x = x;
00032                         this.y = y;
00033                 }
00034 
00035                 double x, y;
00036         }
00037 
00038         private double gatherstats(short[] image, int width, int height,
00039                         FloatPair mean) {
00040                         int x;
00041                         int y;
00042                         int found;
00043                         int tot;
00044                         double mxx=0,mxy=0,myy=0;
00045                         y = 0;
00046                         found = 0;
00047                         /* look for a new region */
00048                         do {
00049                                 x = 0;
00050                                 do {
00051 
00052                                         if (image[x + y * width] != 0) {
00053                                                 found = 1;
00054                                         } else {
00055                                                 x = x + 1;
00056                                         }
00057                                         ;
00058                                 } while ((found == 0) && (x < (width)));
00059                                 if (found == 0) {
00060                                         y = y + 1;
00061                                 }
00062                                 ;
00063                         } while ((found == 0) && (y < (height)));
00064                         if (found != 0) {
00065                                 /* gather stats for this region */
00066                                 /* do it the simple way in case */
00067                                 /* we want to modify to cover multipart */
00068                                 /* regions later */
00069                                 mean.x = 0.0;
00070                                 mean.y = 0.0;
00071                                 mxx = 0.0;
00072                                 myy = 0.0;
00073                                 mxy = 0.0;
00074                                 tot = 0;
00075                                 for (x = 0; x < width; x = x + 1) {
00076                                         for (y = 0; y < height; y = y + 1) {
00077                                                 if (image[x + y * width] != 0) {
00078                                                         tot = tot + 1;
00079                                                         mean.x += x;
00080                                                         mean.y += y;
00081                                                         mxx += x * x;
00082                                                         myy += y * y;
00083                                                         mxy += x * y;
00084                                                 }
00085                                         }
00086                                 }
00087                                 /* finalize stats: gives components of covariance matrix */
00088                                 mean.x = mean.x / tot;
00089                                 mean.y = mean.y / tot;
00090                                 mxx = mxx / tot - mean.x * mean.x;
00091                                 myy = myy / tot - mean.y * mean.y;
00092                                 mxy = mxy / tot - mean.x * mean.y;
00093                         }/* end of found */
00094                 
00095                 //Calculate the offset angle between the xy-plane and the plane of the eigenvectors
00096                 return Math.atan2((2 * mxy), (myy - mxx)) / 2.0 + Math.abs(Math.atan2(1.0, 0.0));
00097         }
00098 
00099         public Object measure(RegionMask mask) {
00100 
00101                 short[] image = new short[mask.getWidth() * mask.getHeight()];
00102                 int width = mask.getWidth();
00103                 int height = mask.getHeight();
00104                 for (int x = 0; x < width; x++) {
00105                         for (int y = 0; y < height; y++) {
00106                                 if (mask.isSet(x, y, 0))
00107                                         image[x + y * width] = (short) 0xffff;
00108                         }
00109                 }
00110 
00111                 FloatPair mean = new FloatPair(0, 0);
00112 
00113                 double radians = gatherstats(image, width, height, mean);
00114                 double degrees = radians * 360.0 / (2 * Math.PI);
00115 
00116                 BufferedImage buf = new BufferedImage(width, height,
00117                                 BufferedImage.TYPE_USHORT_555_RGB);
00118 
00119                 buf.getRaster().setDataElements(0, 0, width, height, image);
00120 
00121                 radians = -radians;
00122                 ((Graphics2D) buf.getGraphics()).drawLine((int) (mean.x + 0.5), (int) (mean.y + 0.5),
00123                                 (int) (mean.x + 60 * Math.cos(radians) + 0.5),
00124                                 (int) (mean.y + 60 * Math.sin(radians) + 0.5));
00125 
00126                 radians += Math.PI;
00127                 ((Graphics2D) buf.getGraphics()).drawLine((int) (mean.x + 0.5), (int) (mean.y + 0.5),
00128                                 (int) (mean.x + 60 * Math.cos(radians) + 0.5),
00129                                 (int) (mean.y + 60 * Math.sin(radians) + 0.5));
00130 
00131                 buf.flush();
00132                 buf.getRaster().getDataElements(0, 0, width, height, image);
00133                 ThebaGUI.getInstance().showImage(image);
00134 
00135                 try {
00136                         Thread.sleep(500);
00137                 } catch (InterruptedException e) {
00138                         //ignore
00139                 }
00140 
00141                 return "angle : " + degrees;
00142         }
00143 }

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