OrientationDescriptor3D.java
Go to the documentation of this file.00001 package theba.descriptors;
00002
00003 import theba.core.RegionDescriptor;
00004 import theba.core.RegionMask;
00005 import Jama.EigenvalueDecomposition;
00006 import Jama.Matrix;
00007
00008 public class OrientationDescriptor3D implements RegionDescriptor {
00009 public String getName() {
00010 return "Orientation (3D)";
00011 }
00012
00013 public String getAbout() {
00014 return "Returns the orientation of the region based on the covariance matrix eigenvectors";
00015 }
00016
00017 public boolean does3D() {
00018 return true;
00019 }
00020
00021 public boolean isNumeric() {
00022 return false;
00023 }
00024
00025 private String gatherstats(RegionMask mask) {
00026
00027 int tot = 0;
00028
00029 double xx = 0;
00030 double yy = 0;
00031 double zz = 0;
00032
00033 double xy = 0;
00034 double xz = 0;
00035 double yz = 0;
00036
00037 double mx = 0;
00038 double my = 0;
00039 double mz = 0;
00040
00041 if (mask.getDepth() < 1)
00042 return "Unable to measure";
00043
00044 for (int x = 0; x < mask.getWidth(); x = x + 1) {
00045 for (int y = 0; y < mask.getHeight(); y = y + 1) {
00046 for (int z = 0; z < mask.getDepth(); z = z + 1) {
00047 if (mask.isSet(x, y, z)) {
00048
00049 tot++;
00050
00051 mx += x;
00052 my += y;
00053 mz += z;
00054
00055 xx += x * x;
00056 yy += y * y;
00057 zz += z * z;
00058
00059 xy += x * y;
00060 xz += x * z;
00061 yz += z * y;
00062
00063 }
00064 }
00065 }
00066 }
00067
00068
00069 mx = mx / tot;
00070 my = my / tot;
00071 mz = mz / tot;
00072
00073 xx = xx / tot - mx * mx;
00074 yy = yy / tot - my * my;
00075 zz = zz / tot - mz * mz;
00076
00077 xy = xy / tot - mx * my;
00078 xz = xz / tot - mx * mz;
00079 yz = yz / tot - my * mz;
00080
00081
00082
00083 double[] m = { xx, xy, xz, xy, yy, yz, xz, yz, zz };
00084
00085 Matrix matrix = new Matrix(m, 3);
00086
00087 EigenvalueDecomposition ed = matrix.eig();
00088
00089 double x1 = ed.getV().get(0, 2);
00090 double y1 = ed.getV().get(1, 2);
00091 double z1 = ed.getV().get(2, 2);
00092
00093 double length = Math.sqrt(x1 * x1 + y1 * y1 + z1 * z1);
00094 x1 /= length;
00095 y1 /= length;
00096 z1 /= length;
00097
00098 double radians = Math.acos(x1 / Math.sqrt(x1 * x1 + y1 * y1));
00099 double degrees = radians * 360 / (2 * Math.PI);
00100
00101 if (z1 < 0) {
00102 x1 = -x1;
00103 y1 = -y1;
00104 z1 = -z1;
00105 }
00106
00107 y1 = -y1;
00108
00109 return "Orientation: " + x1 + " " + y1 + " " + z1 + " size: " + tot
00110 + " angle: " + degrees;
00111 }
00112
00113 public Object measure(RegionMask mask) {
00114
00115 return gatherstats(mask);
00116 }
00117 }