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
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
00066
00067
00068
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
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 }
00094
00095
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
00139 }
00140
00141 return "angle : " + degrees;
00142 }
00143 }