changes: 1) fixes problems in the original EyeTracking benchmark 2) fix a bug in...
[IRC.git] / Robust / src / Benchmarks / SSJava / EyeTrackingInfer / ClassifierTree.java
index 1454902918954b2f7b7638a7409325329e0cb63a..dc150e1d1b1c6eed5c9b993e8d95700aeb61c45d 100644 (file)
@@ -14,7 +14,10 @@ import SSJava.PCLOC;
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
- * 
+ *   private Point readEyes( Image image,  Rectangle2D rect) {
+  EyeDetector ed = new EyeDetector(image, rect);
+ return ed.detectEye();
+ }
  * You should have received a copy of the GNU Lesser General Public License
  * along with LEA. If not, see <http://www.gnu.org/licenses/>.
  */
@@ -28,75 +31,97 @@ import SSJava.PCLOC;
 public class ClassifierTree {
 
   
-  private Classifier classifiers[];
+  private Classifier[] classifiers;
+  
+  double x;
+  
+  double y;
+  
+  double width;
+  
+  double height;
 
-  public ClassifierTree(int size) {
+  
+  int size;
+
+  
+  public ClassifierTree( int size) {
+    this.size = size;
     classifiers = new Classifier[size];
+    x = -1;
+    y = -1;
+    width = -1;
+    height = -1;
   }
 
   public void addClassifier( int idx,  Classifier c) {
     classifiers[idx] = c;
   }
 
+  
   /**
-   * Locates a face by searching radial starting at the last known position. If
-   * lastCoordinates are null we simply start in the center of the image.
+   * Locates a face by searching radial starting at the last known position. If lastCoordinates are
+   * null we simply start in the center of the image.
    * <p>
-   * TODO: This method could quite possible be tweaked so that face recognition
-   * would be much faster
+   * TODO: This method could quite possible be tweaked so that face recognition would be much faster
    * 
    * @param image
    *          the image to process
    * @param lastCoordinates
    *          the last known coordinates or null if unknown
-   * @return an rectangle representing the actual face position on success or
-   *         null if no face could be detected
+   * @return an rectangle representing the actual face position on success or null if no face could
+   *         be detected
    */
   
-  
-  public Rectangle2D locateFaceRadial( Image smallImage,
-       Rectangle2D lastCoordinates) {
+  public void locateFaceRadial( Image smallImage) {
+
+     double px = x;
+     double py = y;
+     double pwidth = width;
+     double pheight = height;
+
+    x = -1;
+    y = -1;
+    width = -1;
+    height = -1;
 
      IntegralImageData imageData = new IntegralImageData(smallImage);
      float originalImageFactor = 1;
-
-    if (lastCoordinates == null) {
+    if (px == -1) {
+      // if(true){
       // if we don't have a last coordinate we just begin in the center
-       int smallImageMaxDimension =
-          Math.min(smallImage.getWidth(), smallImage.getHeight());
-      lastCoordinates =
-          new Rectangle2D((smallImage.getWidth() - smallImageMaxDimension) / 2.0,
-              (smallImage.getHeight() - smallImageMaxDimension) / 2.0, smallImageMaxDimension,
-              smallImageMaxDimension);
-      // System.out.println("lastCoordinates=" + lastCoordinates);
+       int smallImageMaxDimension = Math.min(smallImage.getWidth(), smallImage.getHeight());
+
+      px = (smallImage.getWidth() - smallImageMaxDimension) / 2.0;
+      py = (smallImage.getHeight() - smallImageMaxDimension) / 2.0;
+      pwidth = smallImageMaxDimension;
+      pheight = smallImageMaxDimension;
     } else {
       // first we have to scale the last coodinates back relative to the resized
       // image
-      lastCoordinates =
-          new Rectangle2D((lastCoordinates.getX() * (1 / originalImageFactor)),
-              (lastCoordinates.getY() * (1 / originalImageFactor)),
-              (lastCoordinates.getWidth() * (1 / originalImageFactor)),
-              (lastCoordinates.getHeight() * (1 / originalImageFactor)));
+      px = px * (1 / originalImageFactor);
+      py = py * (1 / originalImageFactor);
+      pwidth = pwidth * (1 / originalImageFactor);
+      pheight = pheight * (1 / originalImageFactor);
     }
 
-     float startFactor = (float) (lastCoordinates.getWidth() / 100.0f);
+
+     float startFactor = (float) (pwidth / 100.0f);
 
     // first we calculate the maximum scale factor for our 200x200 image
-     float maxScaleFactor =
-        Math.min(imageData.getWidth() / 100f, imageData.getHeight() / 100f);
+     float maxScaleFactor = Math.min(imageData.getWidth() / 100f, imageData.getHeight() / 100f);
     // maxScaleFactor = 1.0f;
 
     // we simply won't recognize faces that are smaller than 40x40 px
      float minScaleFactor = 0.5f;
 
-     float maxScaleDifference =
-        Math.max(Math.abs(maxScaleFactor - startFactor), Math.abs(minScaleFactor - startFactor));
+     float maxScaleDifference = Math.max(Math.abs(maxScaleFactor - startFactor), Math.abs(minScaleFactor - startFactor));
 
     // border for faceYes-possibility must be greater that that
      float maxBorder = 0.999f;
 
-     int startPosX = (int) lastCoordinates.getX();
-     int startPosY = (int) lastCoordinates.getX();
+     int startPosX = (int) px;
+     int startPosY = (int) py;
 
      int loopidx = 0;
     TERMINATE: for ( float factorDiff = 0.0f; Math.abs(factorDiff) <= maxScaleDifference; factorDiff =
@@ -106,7 +131,11 @@ public class ClassifierTree {
     ) {
 
       if (++loopidx > 1000) {
-        return null;
+        px = -1;
+        py = -1;
+        pwidth = -1;
+        pheight = -1;
+        return;
       }
 
        float factor = startFactor + factorDiff;
@@ -126,7 +155,11 @@ public class ClassifierTree {
           (xDiff + sgn(xDiff) * 0.5f) * -1) {
 
         if (++xidx > 1000) {
-          return null;
+          px = -1;
+          py = -1;
+          pwidth = -1;
+          pheight = -1;
+          return;
         }
 
          int xPos = Math.round((float) (startPosX + xDiff));
@@ -140,7 +173,11 @@ public class ClassifierTree {
             (yDiff + sgn(yDiff) * 0.5f) * -1) {
 
           if (++yidx > 1000) {
-            return null;
+            px = -1;
+            py = -1;
+            pwidth = -1;
+            pheight = -1;
+            return;
           }
 
            int yPos = Math.round(startPosY + yDiff);
@@ -150,9 +187,8 @@ public class ClassifierTree {
           // by now we should have a valid coordinate to process which we should
           // do now
            boolean backToYLines = false;
-          for ( int idx = 0; idx < classifiers.length; ++idx) {
-             float borderline =
-                0.8f + (idx / (classifiers.length - 1)) * (maxBorder - 0.8f);
+          for ( int idx = 0; idx < size; ++idx) {
+             float borderline = 0.8f + (idx / (size - 1)) * (maxBorder - 0.8f);
             if (!classifiers[idx].classifyFace(imageData, factor, xPos, yPos, borderline)) {
               backToYLines = true;
               break;
@@ -167,11 +203,12 @@ public class ClassifierTree {
           if (backToYLines) {
             continue;
           }
-           Rectangle2D faceRect =
-              new Rectangle2D(xPos * originalImageFactor, yPos * originalImageFactor,
-                  actualDimmension * originalImageFactor, actualDimmension * originalImageFactor);
 
-          return faceRect;
+          x = xPos * originalImageFactor;
+          y = yPos * originalImageFactor;
+          width = actualDimmension * originalImageFactor;
+          height = actualDimmension * originalImageFactor;
+          return;
 
         }
 
@@ -179,8 +216,6 @@ public class ClassifierTree {
 
     }
 
-    // System.out.println("Time: "+(System.currentTimeMillis()-timeStart)+"ms");
-    return null;
 
   }
 
@@ -190,4 +225,37 @@ public class ClassifierTree {
     return (value < 0 ? -1 : (value > 0 ? +1 : 1));
   }
 
+  
+  public FaceAndEyePosition getEyePosition( Image image) {
+    if (image == null) {
+      return null;
+    }
+
+     float originalImageFactor = 1;
+
+    locateFaceRadial(image);
+
+    if (width > image.getWidth() || height > image.getHeight()) {
+      return null;
+    }
+
+     EyePosition eyePosition = null;
+
+    if (x != -1) {
+       EyeDetector ed = new EyeDetector(image, x, y, width, height);
+       Point point = ed.detectEye();
+      if (point != null) {
+        eyePosition = new EyePosition(point.getX(), point.getY());
+      }
+    }
+
+    System.out.println("eyePosition=" + eyePosition);
+
+     FaceAndEyePosition fep = new FaceAndEyePosition(x, y, width, height, eyePosition);
+
+
+    return fep;
+  }
+
+
 }