From f942cda2f0ea302191f88b8168f77b61adb5c0ed Mon Sep 17 00:00:00 2001 From: yeom Date: Wed, 14 Sep 2011 01:40:58 +0000 Subject: [PATCH] add eye tracking benchmark. get rid of all XML serialization. --- .../SSJava/EyeTracking/Classifier.java | 358 +++ .../SSJava/EyeTracking/ClassifierTree.java | 344 +++ .../SSJava/EyeTracking/Deviation.java | 57 + .../SSJava/EyeTracking/DeviationScanner.java | 81 + .../SSJava/EyeTracking/Dimension.java | 5 + .../EyeTracking/DummyCaptureDevice.java | 52 + .../SSJava/EyeTracking/EyeDetector.java | 89 + .../SSJava/EyeTracking/EyeInfoPanel.java | 71 + .../SSJava/EyeTracking/EyePosition.java | 85 + .../EyeTracking/FaceAndEyePosition.java | 47 + .../SSJava/EyeTracking/FaceInfoPanel.java | 67 + .../SSJava/EyeTracking/ICaptureDevice.java | 52 + .../EyeTracking/IEyeMovementListener.java | 50 + .../SSJava/EyeTracking/InfoPanel.java | 158 ++ .../SSJava/EyeTracking/IntegralImageData.java | 70 + .../SSJava/EyeTracking/JMFCaptureDevice.java | 213 ++ .../Benchmarks/SSJava/EyeTracking/LEA.java | 176 ++ .../SSJava/EyeTracking/LEAImplementation.java | 117 + .../SSJava/EyeTracking/LEAStatusWindow.java | 127 + .../Benchmarks/SSJava/EyeTracking/Point.java | 14 + .../SSJava/EyeTracking/ScanArea.java | 115 + .../EyeTracking/StaticSizeArrayList.java | 72 + .../SSJava/EyeTracking/facedata.dat | 2090 +++++++++++++++++ .../Benchmarks/SSJava/EyeTracking/makefile | 23 + 24 files changed, 4533 insertions(+) create mode 100644 Robust/src/Benchmarks/SSJava/EyeTracking/Classifier.java create mode 100644 Robust/src/Benchmarks/SSJava/EyeTracking/ClassifierTree.java create mode 100644 Robust/src/Benchmarks/SSJava/EyeTracking/Deviation.java create mode 100644 Robust/src/Benchmarks/SSJava/EyeTracking/DeviationScanner.java create mode 100644 Robust/src/Benchmarks/SSJava/EyeTracking/Dimension.java create mode 100644 Robust/src/Benchmarks/SSJava/EyeTracking/DummyCaptureDevice.java create mode 100644 Robust/src/Benchmarks/SSJava/EyeTracking/EyeDetector.java create mode 100644 Robust/src/Benchmarks/SSJava/EyeTracking/EyeInfoPanel.java create mode 100644 Robust/src/Benchmarks/SSJava/EyeTracking/EyePosition.java create mode 100644 Robust/src/Benchmarks/SSJava/EyeTracking/FaceAndEyePosition.java create mode 100644 Robust/src/Benchmarks/SSJava/EyeTracking/FaceInfoPanel.java create mode 100644 Robust/src/Benchmarks/SSJava/EyeTracking/ICaptureDevice.java create mode 100644 Robust/src/Benchmarks/SSJava/EyeTracking/IEyeMovementListener.java create mode 100644 Robust/src/Benchmarks/SSJava/EyeTracking/InfoPanel.java create mode 100644 Robust/src/Benchmarks/SSJava/EyeTracking/IntegralImageData.java create mode 100644 Robust/src/Benchmarks/SSJava/EyeTracking/JMFCaptureDevice.java create mode 100644 Robust/src/Benchmarks/SSJava/EyeTracking/LEA.java create mode 100644 Robust/src/Benchmarks/SSJava/EyeTracking/LEAImplementation.java create mode 100644 Robust/src/Benchmarks/SSJava/EyeTracking/LEAStatusWindow.java create mode 100644 Robust/src/Benchmarks/SSJava/EyeTracking/Point.java create mode 100644 Robust/src/Benchmarks/SSJava/EyeTracking/ScanArea.java create mode 100644 Robust/src/Benchmarks/SSJava/EyeTracking/StaticSizeArrayList.java create mode 100644 Robust/src/Benchmarks/SSJava/EyeTracking/facedata.dat create mode 100644 Robust/src/Benchmarks/SSJava/EyeTracking/makefile diff --git a/Robust/src/Benchmarks/SSJava/EyeTracking/Classifier.java b/Robust/src/Benchmarks/SSJava/EyeTracking/Classifier.java new file mode 100644 index 00000000..1be3c78d --- /dev/null +++ b/Robust/src/Benchmarks/SSJava/EyeTracking/Classifier.java @@ -0,0 +1,358 @@ +/* + * Copyright 2009 (c) Florian Frankenberger (darkblue.de) + * + * This file is part of LEA. + * + * LEA is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * LEA is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with LEA. If not, see . + */ + +/** + * + * @author Florian + */ +public class Classifier { + + private ScanArea[] scanAreas; + + // private float possibilityFace = 0f; + private float[] possibilities_FaceYes; + private float[] possibilities_FaceNo; + private int possibilityFaceYes = 0; + private int possibilityFaceNo = 0; + + public static final long serialVersionUID = 5168971806943656945l; + + public Classifier(int numScanAreas) { + this.scanAreas = new ScanArea[numScanAreas]; + this.possibilities_FaceYes = new float[numScanAreas]; + this.possibilities_FaceNo = new float[numScanAreas]; + } + + public void setScanArea(int idx, ScanArea area) { + scanAreas[idx] = area; + } + + public void setPossibilitiesFaceYes(float[] arr) { + this.possibilities_FaceYes = arr; + } + + public void setPossibilityFaceYes(int v) { + this.possibilityFaceYes = v; + } + + public void setPossibilitiesFaceNo(float[] arr) { + this.possibilities_FaceNo = arr; + } + + public void setPossibilityFaceNo(int v) { + this.possibilityFaceNo = v; + } + + // public void learn(IntegralImageData image, boolean isFace) { + // long values[] = new long[this.scanAreas.length]; + // // + // System.out.println("HERE:"+image.getIntegralAt(image.getDimension().width-1, + // // image.getDimension().height-1)); + // // we assume the image is rectangular so we can simply use one side to + // // calculate + // // the scale factor + // float scaleFactor = image.getDimension().width / 100.0f; + // + // float avg = 0f; + // int avgItems = 0; + // for (int i = 0; i < this.scanAreas.length; ++i) { + // ScanArea scanArea = this.scanAreas[i]; + // values[i] = 0l; + // + // values[i] += image.getIntegralAt(scanArea.getToX(scaleFactor), + // scanArea.getToY(scaleFactor)); + // values[i] += + // image.getIntegralAt(scanArea.getFromX(scaleFactor), + // scanArea.getFromY(scaleFactor)); + // + // values[i] -= + // image.getIntegralAt(scanArea.getToX(scaleFactor), + // scanArea.getFromY(scaleFactor)); + // values[i] -= + // image.getIntegralAt(scanArea.getFromX(scaleFactor), + // scanArea.getToY(scaleFactor)); + // + // values[i] = (long) (values[i] / ((float) scanArea.getSize(scaleFactor))); + // avg = ((avgItems * avg) + values[i]) / (++avgItems); + // } + // + // if (isFace) { + // this.possibilityFaceYes++; + // } else { + // this.possibilityFaceNo++; + // } + // for (int i = 0; i < this.scanAreas.length; ++i) { + // boolean bright = (values[i] >= avg); + // + // if (isFace) { + // // here we change the possibility of P(Scanarea_N = (Bright | NotBright) + // // | Face=Yes) + // this.possibilities_FaceYes[i] = + // (((this.possibilityFaceYes - 1) * this.possibilities_FaceYes[i]) + (bright + // ? 0.999f + // : 0.001f)) / this.possibilityFaceYes; + // // + // System.out.println("P(Scannarea"+i+"=bright|Face=Yes) = "+this.possibilities_FaceYes[i]); + // // + // System.out.println("P(Scannarea"+i+"=dark|Face=Yes) = "+(1.0f-this.possibilities_FaceYes[i])); + // } else { + // // here we change the possibility of P(Scanarea_N = (Bright | NotBright) + // // | Face=No) + // this.possibilities_FaceNo[i] = + // (((this.possibilityFaceNo - 1) * this.possibilities_FaceNo[i]) + (bright ? + // 0.999f + // : 0.001f)) / this.possibilityFaceNo; + // // + // System.out.println("P(Scannarea"+i+"=bright|Face=No) = "+this.possibilities_FaceNo[i]); + // // + // System.out.println("P(Scannarea"+i+"=dark|Face=No) = "+(1.0f-this.possibilities_FaceNo[i])); + // } + // + // } + // + // // System.out.println("Average: "+avg); + // // System.out.println(this); + // } + + /** + * Classifies an images region as face + * + * @param image + * @param scaleFactor + * please be aware of the fact that the scanareas are scaled for use + * with 100x100 px images + * @param translationX + * @param translationY + * @return true if this region was classified as face, else false + */ + // public boolean classifyFace(IntegralImageData image, float scaleFactor, int + // translationX, + // int translationY, float borderline) { + // + // long values[] = new long[this.scanAreas.length]; + // + // float avg = 0f; + // int avgItems = 0; + // for (int i = 0; i < this.scanAreas.length; ++i) { + // ScanArea scanArea = this.scanAreas[i]; + // values[i] = 0l; + // + // values[i] += + // image.getIntegralAt(translationX + scanArea.getToX(scaleFactor), + // translationY + scanArea.getToY(scaleFactor)); + // values[i] += + // image.getIntegralAt(translationX + scanArea.getFromX(scaleFactor), + // translationY + // + scanArea.getFromY(scaleFactor)); + // + // values[i] -= + // image.getIntegralAt(translationX + scanArea.getToX(scaleFactor), + // translationY + scanArea.getFromY(scaleFactor)); + // values[i] -= + // image.getIntegralAt(translationX + scanArea.getFromX(scaleFactor), + // translationY + // + scanArea.getToY(scaleFactor)); + // + // values[i] = (long) (values[i] / ((float) scanArea.getSize(scaleFactor))); + // avg = ((avgItems * avg) + values[i]) / (++avgItems); + // } + // + // // int amountYesNo = this.possibilityFaceNo + this.possibilityFaceYes; + // + // // calculate the possibilites for face=yes and face=no with naive bayes + // // P(Yes | M1 and ... and Mn) = P(Yes) * P(M1 | Yes) * ... * P(Mn | Yes) + // /xx + // // P(No | M1 and ... and Mn) = P(No) * P(M1 | No) * ... * P(Mn | No) / xx + // // as we just maximize the args we don't actually calculate the accurate + // // possibility + // + // float isFaceYes = 1.0f;// this.possibilityFaceYes / (float)amountYesNo; + // float isFaceNo = 1.0f;// this.possibilityFaceNo / (float)amountYesNo; + // + // for (int i = 0; i < this.scanAreas.length; ++i) { + // boolean bright = (values[i] >= avg); + // isFaceYes *= (bright ? this.possibilities_FaceYes[i] : 1 - + // this.possibilities_FaceYes[i]); + // isFaceNo *= (bright ? this.possibilities_FaceNo[i] : 1 - + // this.possibilities_FaceNo[i]); + // } + // + // return (isFaceYes >= isFaceNo && (isFaceYes / (isFaceYes + isFaceNo)) > + // borderline); + // } + + public ScanArea[] getScanAreas() { + return this.scanAreas; + } + + public int getLearnedFacesYes() { + return this.possibilityFaceYes; + } + + public int getLearnedFacesNo() { + return this.possibilityFaceNo; + } + + public float getPossibility(int scanAreaID, boolean faceYes, boolean bright) { + if (faceYes) { + return (bright ? this.possibilities_FaceYes[scanAreaID] + : 1 - this.possibilities_FaceYes[scanAreaID]); + } else { + return (bright ? this.possibilities_FaceNo[scanAreaID] + : 1 - this.possibilities_FaceNo[scanAreaID]); + } + } + + public int compareTo(Classifier o) { + if (o.getScanAreas().length > this.getScanAreas().length) { + return -1; + } else if (o.getScanAreas().length < this.getScanAreas().length) { + return 1; + } else + return 0; + } + + public String toString() { + + String str = ""; + for (int i = 0; i < scanAreas.length; i++) { + str += scanAreas[i].toString() + "\n"; + } + + return str; + + } + // @Override + // public String toString() { + // StringBuilder sb = new StringBuilder(); + // sb.append("Classifier [ScanAreas: " + this.scanAreas.length); + // int yesNo = this.possibilityFaceYes + this.possibilityFaceNo; + // sb.append(String.format("|Yes: %3.2f| No:%3.2f] (", + // (this.possibilityFaceYes / (float) yesNo) * 100.0f, + // (this.possibilityFaceNo / (float) yesNo) * 100.0f)); + // for (int i = 0; i < this.scanAreas.length; ++i) { + // sb.append(String.format("[%3d|Yes: %3.2f| No: %3.2f], ", i + 1, + // (this.possibilities_FaceYes[i] * 100.0f), (this.possibilities_FaceNo[i] * + // 100.0f))); + // } + // sb.append(")"); + // + // return sb.toString(); + // } + + /** + * Generates a new set of classifiers each with more ScanAreas than the last + * classifier. You can specifiy the amount of classifiers you want to generate + * + * @param amount + * amount of classifiers to create + * @param startAmountScanAreas + * the start amount of scanAreas - if your first classifiers should + * contain 3 items you should give 3 here + * @param incAmountScanAreas + * the amount of which the scanAreas should increase - a simple 2 + * will increase them by 2 every step + * @return a List of classifiers + */ + // public static List generateNewClassifiers(int amount, int + // startAmountScanAreas, + // float incAmountScanAreas) { + // List classifiers = new ArrayList(); + // + // int maxDim = 40; + // Random random = new Random(System.currentTimeMillis()); + // double maxSpace = 2 * Math.PI * Math.pow(50, 2); + // + // for (int i = 0; i < amount; ++i) { + // // we create an odd amount of ScanAreas starting with 1 (3, 5, 7, ...) + // int scanAreaAmount = startAmountScanAreas + (int) + // Math.pow(incAmountScanAreas, i);// + + // // ((i)*incAmountScanAreas+1); + // + // int scanAreaSize = + // randomInt(random, scanAreaAmount * 20, (int) Math.min(maxDim * maxDim, + // maxSpace)) + // / scanAreaAmount; + // // System.out.println("scanAreaSize = "+scanAreaSize); + // + // List scanAreas = new ArrayList(); + // + // for (int j = 0; j < scanAreaAmount; ++j) { + // + // int counter = 0; + // ScanArea scanArea = null; + // do { + // // new the width has the first choice + // int minWidth = (int) Math.ceil(scanAreaSize / (float) maxDim); + // + // int scanAreaWidth = randomInt(random, minWidth, Math.min(maxDim, + // scanAreaSize / 2)); + // int scanAreaHeight = (int) Math.ceil(scanAreaSize / (float) scanAreaWidth); + // + // int radius = + // randomInt(random, 5, Math.min(50 - scanAreaHeight / 2, 50 - scanAreaWidth / + // 2)); + // double angle = random.nextFloat() * 2 * Math.PI; + // + // int posX = (int) (50 + Math.cos(angle) * radius) - (scanAreaWidth / 2); + // int posY = (int) (50 + Math.sin(angle) * radius) - (scanAreaHeight / 2); + // + // // System.out.println("[Angle: "+(angle / + // // (Math.PI*2)*180)+" | radius: "+radius+"]"); + // // + // System.out.println("Area"+j+" is "+posX+", "+posY+" ("+scanAreaWidth+" x "+scanAreaHeight+" = "+((scanAreaWidth*scanAreaHeight))+")"); + // + // // now we get random position for this area + // scanArea = new ScanArea(posX, posY, scanAreaWidth, scanAreaHeight); + // + // counter++; + // } while (scanAreas.contains(scanArea) && counter < 30); + // + // if (counter == 30) { + // j -= 1; + // continue; + // } + // + // scanAreas.add(scanArea); + // } + // + // Classifier classifier = new Classifier(scanAreas.toArray(new ScanArea[0])); + // classifiers.add(classifier); + // } + // + // return classifiers; + // } + + // private static int randomInt(Random random, int from, int to) { + // if (to - from <= 0) + // to = from + 1; + // return from + random.nextInt(to - from); + // } + // + // public static List getDefaultClassifier() { + // List classifier = new ArrayList(); + // + // classifier.add(new Classifier(new ScanArea(30, 30, 30, 30), new + // ScanArea(15, 8, 15, 82), + // new ScanArea(75, 8, 15, 82))); + // + // return classifier; + // } + +} diff --git a/Robust/src/Benchmarks/SSJava/EyeTracking/ClassifierTree.java b/Robust/src/Benchmarks/SSJava/EyeTracking/ClassifierTree.java new file mode 100644 index 00000000..4c66afff --- /dev/null +++ b/Robust/src/Benchmarks/SSJava/EyeTracking/ClassifierTree.java @@ -0,0 +1,344 @@ +/* + * Copyright 2009 (c) Florian Frankenberger (darkblue.de) + * + * This file is part of LEA. + * + * LEA is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * LEA is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with LEA. If not, see . + */ + +import java.awt.RenderingHints; +import java.awt.color.ColorSpace; +import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; +import java.awt.image.BufferedImageOp; +import java.awt.image.ColorConvertOp; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.io.Reader; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * + * @author Florian + */ +public class ClassifierTree { + + private List classifiers; + private static XStream xStream = new XStream(new DomDriver()); + + static { + xStream.alias("ClassifierTree", ClassifierTree.class); + xStream.alias("Classifier", Classifier.class); + xStream.alias("ScanArea", ScanArea.class); + } + + public ClassifierTree(List classifier) { + this.classifiers = new ArrayList(classifier); + Collections.sort(this.classifiers); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("ClassifierTree {\n"); + for (Classifier classifier : this.classifiers) { + sb.append(classifier.toString()); + sb.append('\n'); + } + sb.append("}\n"); + return sb.toString(); + } + + public static BufferedImage resizeImageFittingInto(BufferedImage image, int dimension) { + + int newHeight = 0; + int newWidth = 0; + float factor = 0; + if (image.getWidth() > image.getHeight()) { + factor = dimension / (float) image.getWidth(); + newWidth = dimension; + newHeight = (int) (factor * image.getHeight()); + } else { + factor = dimension / (float) image.getHeight(); + newHeight = dimension; + newWidth = (int) (factor * image.getWidth()); + } + + if (factor > 1) { + BufferedImageOp op = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null); + BufferedImage tmpImage = op.filter(image, null); + + return tmpImage; + } + + BufferedImage resizedImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB); + + Graphics2D g2D = resizedImage.createGraphics(); + g2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, + RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR); + + g2D.drawImage(image, 0, 0, newWidth - 1, newHeight - 1, 0, 0, image.getWidth() - 1, + image.getHeight() - 1, null); + + BufferedImageOp op = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null); + BufferedImage tmpImage = op.filter(resizedImage, null); + + return tmpImage; + } + + /** + * Image should have 100x100px and should be in b/w + * + * @param image + */ + public void learn(BufferedImage image, boolean isFace) { + IntegralImageData imageData = new IntegralImageData(image); + for (Classifier classifier : this.classifiers) { + classifier.learn(imageData, isFace); + } + } + + public int getLearnedFacesYes() { + return this.classifiers.get(0).getLearnedFacesYes(); + } + + public int getLearnedFacesNo() { + return this.classifiers.get(0).getLearnedFacesNo(); + } + + /** + * Locates a face by linear iteration through all probable face positions + * + * @deprecated use locateFaceRadial instead for improved performance + * @param image + * @return an rectangle representing the actual face position on success or + * null if no face could be detected + */ + public Rectangle2D locateFace(BufferedImage image) { + long timeStart = System.currentTimeMillis(); + + int resizeTo = 600; + + BufferedImage smallImage = resizeImageFittingInto(image, resizeTo); + IntegralImageData imageData = new IntegralImageData(smallImage); + + float factor = image.getWidth() / (float) smallImage.getWidth(); + + int maxIterations = 0; + + // first we calculate the maximum scale factor for our 200x200 image + float maxScaleFactor = Math.min(imageData.getWidth() / 100f, imageData.getHeight() / 100f); + + // we simply won't recognize faces that are smaller than 40x40 px + float minScaleFactor = 0.5f; + + // border for faceYes-possibility must be greater that that + float maxBorder = 0.999f; + + for (float scale = maxScaleFactor; scale > minScaleFactor; scale -= 0.25) { + int actualDimension = (int) (scale * 100); + int borderX = imageData.getWidth() - actualDimension; + int borderY = imageData.getHeight() - actualDimension; + for (int x = 0; x <= borderX; ++x) { + yLines: for (int y = 0; y <= borderY; ++y) { + + for (int iterations = 0; iterations < this.classifiers.size(); ++iterations) { + Classifier classifier = this.classifiers.get(iterations); + + float borderline = + 0.8f + (iterations / this.classifiers.size() - 1) * (maxBorder - 0.8f); + if (iterations > maxIterations) + maxIterations = iterations; + if (!classifier.classifyFace(imageData, scale, x, y, borderline)) { + continue yLines; + } + } + + // if we reach here we have a face recognized because our image went + // through all + // classifiers + + Rectangle2D faceRect = + new Rectangle2D.Float(x * factor, y * factor, actualDimension * factor, + actualDimension * factor); + + System.out.println("Time: " + (System.currentTimeMillis() - timeStart) + "ms"); + return faceRect; + + } + } + } + + return null; + } + + /** + * 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. + *

+ * 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 + */ + public Rectangle2D locateFaceRadial(BufferedImage image, Rectangle2D lastCoordinates) { + + int resizeTo = 600; + + BufferedImage smallImage = resizeImageFittingInto(image, resizeTo); + float originalImageFactor = image.getWidth() / (float) smallImage.getWidth(); + IntegralImageData imageData = new IntegralImageData(smallImage); + + if (lastCoordinates == null) { + // 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.Float((smallImage.getWidth() - smallImageMaxDimension) / 2.0f, + (smallImage.getHeight() - smallImageMaxDimension) / 2.0f, smallImageMaxDimension, + smallImageMaxDimension); + } else { + // first we have to scale the last coodinates back relative to the resized + // image + lastCoordinates = + new Rectangle2D.Float((float) (lastCoordinates.getX() * (1 / originalImageFactor)), + (float) (lastCoordinates.getY() * (1 / originalImageFactor)), + (float) (lastCoordinates.getWidth() * (1 / originalImageFactor)), + (float) (lastCoordinates.getHeight() * (1 / originalImageFactor))); + } + + float startFactor = (float) (lastCoordinates.getWidth() / 100.0f); + + // first we calculate the maximum scale factor for our 200x200 image + 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)); + + // border for faceYes-possibility must be greater that that + float maxBorder = 0.999f; + + int startPosX = (int) lastCoordinates.getX(); + int startPosY = (int) lastCoordinates.getX(); + + for (float factorDiff = 0.0f; Math.abs(factorDiff) <= maxScaleDifference; factorDiff = + (factorDiff + sgn(factorDiff) * 0.1f) * -1 // we alternate between + // negative and positiv + // factors + ) { + + float factor = startFactor + factorDiff; + if (factor > maxScaleFactor || factor < minScaleFactor) + continue; + + // now we calculate the actualDimmension + int actualDimmension = (int) (100 * factor); + int maxX = imageData.getWidth() - actualDimmension; + int maxY = imageData.getHeight() - actualDimmension; + + int maxDiffX = Math.max(Math.abs(startPosX - maxX), startPosX); + int maxDiffY = Math.max(Math.abs(startPosY - maxY), startPosY); + + for (float xDiff = 0.1f; Math.abs(xDiff) <= maxDiffX; xDiff = + (xDiff + sgn(xDiff) * 0.5f) * -1) { + int xPos = Math.round(startPosX + xDiff); + if (xPos < 0 || xPos > maxX) + continue; + + yLines: for (float yDiff = 0.1f; Math.abs(yDiff) <= maxDiffY; yDiff = + (yDiff + sgn(yDiff) * 0.5f) * -1) { + int yPos = Math.round(startPosY + yDiff); + if (yPos < 0 || yPos > maxY) + continue; + + // by now we should have a valid coordinate to process which we should + // do now + for (int iterations = 0; iterations < this.classifiers.size(); ++iterations) { + Classifier classifier = this.classifiers.get(iterations); + + float borderline = + 0.8f + (iterations / (this.classifiers.size() - 1)) * (maxBorder - 0.8f); + + if (!classifier.classifyFace(imageData, factor, xPos, yPos, borderline)) { + continue yLines; + } + } + + // if we reach here we have a face recognized because our image went + // through all + // classifiers + + Rectangle2D faceRect = + new Rectangle2D.Float(xPos * originalImageFactor, yPos * originalImageFactor, + actualDimmension * originalImageFactor, actualDimmension * originalImageFactor); + + return faceRect; + + } + + } + + } + + // System.out.println("Time: "+(System.currentTimeMillis()-timeStart)+"ms"); + return null; + + } + + public List getClassifiers() { + return new ArrayList(this.classifiers); + } + + public static void saveToXml(OutputStream out, ClassifierTree tree) throws IOException { + PrintWriter writer = new PrintWriter(new OutputStreamWriter(out, "UTF-8")); + writer.write(xStream.toXML(tree)); + writer.close(); + } + + public static ClassifierTree loadFromXml(InputStream in) throws IOException { + Reader reader = new InputStreamReader(in, "UTF-8"); + StringBuilder sb = new StringBuilder(); + + char[] buffer = new char[1024]; + int read = 0; + do { + read = reader.read(buffer); + if (read > 0) { + sb.append(buffer, 0, read); + } + } while (read > -1); + reader.close(); + + return (ClassifierTree) xStream.fromXML(sb.toString()); + } + + private static int sgn(float value) { + return (value < 0 ? -1 : (value > 0 ? +1 : 1)); + } + +} diff --git a/Robust/src/Benchmarks/SSJava/EyeTracking/Deviation.java b/Robust/src/Benchmarks/SSJava/EyeTracking/Deviation.java new file mode 100644 index 00000000..bc76ef7c --- /dev/null +++ b/Robust/src/Benchmarks/SSJava/EyeTracking/Deviation.java @@ -0,0 +1,57 @@ +/* + * Copyright 2009 (c) Florian Frankenberger (darkblue.de) + * + * This file is part of LEA. + * + * LEA is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * LEA is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with LEA. If not, see . + */ + + +/** + * Representing an eyes deviation + * + * @author Florian Frankenberger + */ +public enum Deviation { + LEFT_UP(+1, -1), + UP(0, -1), + RIGHT_UP(-1, -1), + LEFT(+1, 0), + NONE(0, 0), + RIGHT(-1, 0), + LEFT_DOWN(+1, +1), + DOWN(0, +1), + RIGHT_DOWN(-1, +1); + + int directionX, directionY; + Deviation(int directionX, int directionY) { + this.directionX = directionX; + this.directionY = directionY; + } + + private boolean concurs(int directionX, int directionY) { + return (directionX == this.directionX && directionY == this.directionY); + } + + + public static Deviation getDirectionFor(int directionX, int directionY) { + for (Deviation direction: Deviation.values()) { + if (direction.concurs(directionX, directionY)) { + return direction; + } + } + + return null; + } + } diff --git a/Robust/src/Benchmarks/SSJava/EyeTracking/DeviationScanner.java b/Robust/src/Benchmarks/SSJava/EyeTracking/DeviationScanner.java new file mode 100644 index 00000000..aa09a483 --- /dev/null +++ b/Robust/src/Benchmarks/SSJava/EyeTracking/DeviationScanner.java @@ -0,0 +1,81 @@ +/* + * Copyright 2009 (c) Florian Frankenberger (darkblue.de) + * + * This file is part of LEA. + * + * LEA is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * LEA is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with LEA. If not, see . + */ + + +import java.awt.geom.Rectangle2D; + +/** + * No description given. + * + * @author Florian Frankenberger + */ +public class DeviationScanner { + + private StaticSizeArrayList eyePositions = new StaticSizeArrayList(3); + + public DeviationScanner() { + } + + public void addEyePosition(EyePosition eyePosition) { + eyePositions.add(eyePosition); + } + + public Deviation scanForDeviation(Rectangle2D faceRect) { + Deviation deviation = Deviation.NONE; + if (eyePositions.size() >= 3) { + double deviationX = 0; + double deviationY = 0; + + EyePosition lastEyePosition = null; + for (int i = 0; i < 3; ++i) { + EyePosition eyePosition = this.eyePositions.get(i); + if (lastEyePosition != null) { + deviationX += (eyePosition.getX() - lastEyePosition.getX()); + deviationY += (eyePosition.getY() - lastEyePosition.getY()); + } + lastEyePosition = eyePosition; + } + + final double deviationPercentX = 0.04; + final double deviationPercentY = 0.04; + + deviationX /= faceRect.getWidth(); + deviationY /= faceRect.getWidth(); + + int deviationAbsoluteX = 0; + int deviationAbsoluteY = 0; + if (deviationX > deviationPercentX) deviationAbsoluteX = 1; + if (deviationX < -deviationPercentX) deviationAbsoluteX = -1; + if (deviationY > deviationPercentY) deviationAbsoluteY = 1; + if (deviationY < -deviationPercentY) deviationAbsoluteY = -1; + + deviation = Deviation.getDirectionFor(deviationAbsoluteX, deviationAbsoluteY); + if (deviation != Deviation.NONE) this.eyePositions.clear(); + //System.out.println(String.format("%.2f%% | %.2f%% => %d and %d >>> %s", deviationX*100, deviationY*100, deviationAbsoluteX, deviationAbsoluteY, deviation.toString())); + + } + + return deviation; + } + + public void clear() { + System.out.println("CLEAR"); + this.eyePositions.clear(); + } +} diff --git a/Robust/src/Benchmarks/SSJava/EyeTracking/Dimension.java b/Robust/src/Benchmarks/SSJava/EyeTracking/Dimension.java new file mode 100644 index 00000000..c6013eb7 --- /dev/null +++ b/Robust/src/Benchmarks/SSJava/EyeTracking/Dimension.java @@ -0,0 +1,5 @@ +public class Dimension { + public int width; + public int height; + +} diff --git a/Robust/src/Benchmarks/SSJava/EyeTracking/DummyCaptureDevice.java b/Robust/src/Benchmarks/SSJava/EyeTracking/DummyCaptureDevice.java new file mode 100644 index 00000000..699a620d --- /dev/null +++ b/Robust/src/Benchmarks/SSJava/EyeTracking/DummyCaptureDevice.java @@ -0,0 +1,52 @@ +/** + * + */ + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; + +import de.darkblue.lea.ifaces.ICaptureDevice; + +/** + * No description given. + * + * @author Florian Frankenberger + */ +public class DummyCaptureDevice implements ICaptureDevice { + + /** + * + */ + public DummyCaptureDevice() { + // TODO Auto-generated constructor stub + } + + /* (non-Javadoc) + * @see de.darkblue.lea.ifaces.ICaptureDevice#close() + */ + @Override + public void close() { + } + + /* (non-Javadoc) + * @see de.darkblue.lea.ifaces.ICaptureDevice#getFrameRate() + */ + @Override + public int getFrameRate() { + return 15; + } + + /* (non-Javadoc) + * @see de.darkblue.lea.ifaces.ICaptureDevice#getImage() + */ + @Override + public BufferedImage getImage() { + BufferedImage image = new BufferedImage(640, 480, BufferedImage.TYPE_INT_RGB); + Graphics2D g2d = (Graphics2D)image.getGraphics(); + g2d.setColor(new Color(255, 255, 255)); + g2d.fillRect(0, 0, 639, 479); + return image; + } + +} diff --git a/Robust/src/Benchmarks/SSJava/EyeTracking/EyeDetector.java b/Robust/src/Benchmarks/SSJava/EyeTracking/EyeDetector.java new file mode 100644 index 00000000..0cc71444 --- /dev/null +++ b/Robust/src/Benchmarks/SSJava/EyeTracking/EyeDetector.java @@ -0,0 +1,89 @@ +/* + * Copyright 2009 (c) Florian Frankenberger (darkblue.de) + * + * This file is part of LEA. + * + * LEA is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * LEA is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with LEA. If not, see . + */ + + +import java.awt.Point; +import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; +import java.awt.image.PixelGrabber; + +/** + * No description given. + * + * @author Florian Frankenberger + */ +class EyeDetector { + + private int width; + private int height; + private int[] pixelBuffer; + + double percent; + + public EyeDetector(BufferedImage image, Rectangle2D faceRect) { + + percent = 0.15*faceRect.getWidth(); + faceRect = new Rectangle2D.Double( + faceRect.getX()+ percent, + faceRect.getY()+ percent, + faceRect.getWidth() - percent, + faceRect.getHeight() - 2*percent + ); + + width = (int)faceRect.getWidth() / 2; + height = (int)faceRect.getHeight() / 2; + pixelBuffer = new int[width*height]; + PixelGrabber pg = new PixelGrabber( + image, + (int)faceRect.getX(), (int)faceRect.getY(), + width, height, + pixelBuffer, 0, width); + + try { + pg.grabPixels(); + } catch (InterruptedException ie) {} + } + + public Point detectEye() { + Point eyePosition = null; + float brightness = 255f; + + for (int y = 0; y < height; ++y) { + for (int x = 0; x < width; ++x) { + final int position = y*width + x; + final int[] color = new int[] { (pixelBuffer[position] & 0xFF0000) >> 16, (pixelBuffer[position] & 0x00FF00) >> 8, pixelBuffer[position] & 0x0000FF }; + final float acBrightness = getBrightness(color); + + if (acBrightness < brightness) { + eyePosition = new Point(x + (int)percent, y + (int)percent); + brightness = acBrightness; + } + } + } + + return eyePosition; + } + + private static float getBrightness(int[] color) { + int min = Math.min(Math.min(color[0], color[1]), color[2]); + int max = Math.max(Math.max(color[0], color[1]), color[2]); + + return 0.5f * (max + min); + } +} diff --git a/Robust/src/Benchmarks/SSJava/EyeTracking/EyeInfoPanel.java b/Robust/src/Benchmarks/SSJava/EyeTracking/EyeInfoPanel.java new file mode 100644 index 00000000..544a48d2 --- /dev/null +++ b/Robust/src/Benchmarks/SSJava/EyeTracking/EyeInfoPanel.java @@ -0,0 +1,71 @@ +/* + * Copyright 2009 (c) Florian Frankenberger (darkblue.de) + * + * This file is part of LEA. + * + * LEA is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * LEA is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with LEA. If not, see . + */ + +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; + +/** + * + * @author Florian + */ +class EyeInfoPanel extends InfoPanel { + + private static final long serialVersionUID = 7681992432092759058L; + + public EyeInfoPanel() { + super("Eye Status", new String[] { "nolock.png" }, 0, 100, 40); + } + + public void setDeviation(Deviation deviation) { + if (deviation == null) { + this.setImage(null); + } else { + this.setImage(loadImage(deviation.toString() + ".png")); + } + } + + public void setEyePosition(BufferedImage image, Rectangle2D faceRect, EyePosition eyePosition) { + + BufferedImage faceRectImage = null; + if (image != null && faceRect != null) { + int width = 100; + int height = 40; + + int posX = (int) (faceRect.getX() + eyePosition.getX()); + int posY = (int) (faceRect.getY() + eyePosition.getY()); + + int targetWidth = (int) (0.3 * faceRect.getWidth()); + int targetHeight = (int) (height / (float) width * targetWidth); + + faceRectImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + + Graphics2D g2D = faceRectImage.createGraphics(); + g2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, + RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR); + + g2D.drawImage(image, 0, 0, width, height, posX - targetWidth / 2, posY - targetHeight / 2, + posX + targetWidth / 2, posY + targetHeight / 2, null); + + } + this.setImage(faceRectImage); + } + +} diff --git a/Robust/src/Benchmarks/SSJava/EyeTracking/EyePosition.java b/Robust/src/Benchmarks/SSJava/EyeTracking/EyePosition.java new file mode 100644 index 00000000..11aef4cb --- /dev/null +++ b/Robust/src/Benchmarks/SSJava/EyeTracking/EyePosition.java @@ -0,0 +1,85 @@ +/* + * Copyright 2009 (c) Florian Frankenberger (darkblue.de) + * + * This file is part of LEA. + * + * LEA is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * LEA is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with LEA. If not, see . + */ + +package de.darkblue.lea.model; + +import java.awt.Point; +import java.awt.geom.Rectangle2D; + +/** + * No description given. + * + * @author Florian Frankenberger + */ +public class EyePosition { + private int x; + private int y; + private Rectangle2D faceRect; + + public EyePosition(Point p, Rectangle2D faceRect) { + this(p.x, p.y, faceRect); + } + + public EyePosition(int x, int y, Rectangle2D faceRect) { + this.x = x; + this.y = y; + this.faceRect = faceRect; + } + + public int getX() { + return this.x; + } + + public int getY() { + return this.y; + } + + public Deviation getDeviation(EyePosition oldEyePosition) { + if (oldEyePosition == null) return Deviation.NONE; + + //first we check if the faceRects are corresponding + double widthChange = (this.faceRect.getWidth() - oldEyePosition.faceRect.getWidth()) / this.faceRect.getWidth(); + if (widthChange > 0.1) return Deviation.NONE; + + int maxDeviationX = (int)Math.round(this.faceRect.getWidth() / 4f); + int maxDeviationY = (int)Math.round(this.faceRect.getWidth() / 8f); + int minDeviation = (int)Math.round(this.faceRect.getWidth() / 16f); + + int deviationX = Math.abs(x - oldEyePosition.x); + int directionX = sgn(x - oldEyePosition.x); + if (deviationX < minDeviation || deviationX > maxDeviationX) directionX = 0; + + int deviationY = Math.abs(y - oldEyePosition.y); + int directionY = sgn(y - oldEyePosition.y); + if (deviationY < minDeviation || deviationY > maxDeviationY) directionY = 0; + + double deviationXPercent = deviationX / this.faceRect.getWidth(); + double deviationYPercent = deviationY / this.faceRect.getWidth(); + + System.out.println(String.format("devX: %.2f | devY: %.2f", deviationXPercent*100f, deviationYPercent*100f)); + return Deviation.getDirectionFor(directionX, directionY); + } + + + private static int sgn(int i) { + if (i > 0) return 1; + if (i < 0) return -1; + return 0; + } +} diff --git a/Robust/src/Benchmarks/SSJava/EyeTracking/FaceAndEyePosition.java b/Robust/src/Benchmarks/SSJava/EyeTracking/FaceAndEyePosition.java new file mode 100644 index 00000000..97d98010 --- /dev/null +++ b/Robust/src/Benchmarks/SSJava/EyeTracking/FaceAndEyePosition.java @@ -0,0 +1,47 @@ +/* + * Copyright 2009 (c) Florian Frankenberger (darkblue.de) + * + * This file is part of LEA. + * + * LEA is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * LEA is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with LEA. If not, see . + */ + +package de.darkblue.lea.model; + +import java.awt.geom.Rectangle2D; + +/** + * No description given. + * + * @author Florian Frankenberger + */ +public class FaceAndEyePosition { + + private Rectangle2D facePosition; + private EyePosition eyePosition; + + public FaceAndEyePosition(Rectangle2D facePosition, EyePosition eyePosition) { + this.facePosition = facePosition; + this.eyePosition = eyePosition; + } + + public Rectangle2D getFacePosition() { + return this.facePosition; + } + + public EyePosition getEyePosition() { + return this.eyePosition; + } + +} diff --git a/Robust/src/Benchmarks/SSJava/EyeTracking/FaceInfoPanel.java b/Robust/src/Benchmarks/SSJava/EyeTracking/FaceInfoPanel.java new file mode 100644 index 00000000..a696ece7 --- /dev/null +++ b/Robust/src/Benchmarks/SSJava/EyeTracking/FaceInfoPanel.java @@ -0,0 +1,67 @@ +/* + * Copyright 2009 (c) Florian Frankenberger (darkblue.de) + * + * This file is part of LEA. + * + * LEA is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * LEA is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with LEA. If not, see . + */ + + +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; + +/** + * + * @author Florian + */ +class FaceInfoPanel extends InfoPanel { + + private static final long serialVersionUID = 453216951714787407L; + + public FaceInfoPanel() { + super( + "Face Detection", + new String[] { + "noface0.png", + "noface1.png" + }, + 2, + 100, + 100); + this.setFace(null, null); + } + + public void setFace(BufferedImage image, Rectangle2D faceRect) { + + BufferedImage faceRectImage = null; + if (image != null && faceRect != null) { + int width = (int)faceRect.getWidth(); + int height = (int)faceRect.getHeight(); + + faceRectImage = new BufferedImage(width, + height, BufferedImage.TYPE_INT_RGB); + + Graphics2D g2D = faceRectImage.createGraphics(); + g2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, + RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR); + + g2D.drawImage(image, 0, 0, width, height, (int)faceRect.getX(), (int)faceRect.getY(), (int)faceRect.getX() + width, (int)faceRect.getY() + height, null); + + } + this.setImage(faceRectImage); + } + +} diff --git a/Robust/src/Benchmarks/SSJava/EyeTracking/ICaptureDevice.java b/Robust/src/Benchmarks/SSJava/EyeTracking/ICaptureDevice.java new file mode 100644 index 00000000..f050a978 --- /dev/null +++ b/Robust/src/Benchmarks/SSJava/EyeTracking/ICaptureDevice.java @@ -0,0 +1,52 @@ +/* + * Copyright 2009 (c) Florian Frankenberger (darkblue.de) + * + * This file is part of LEA. + * + * LEA is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * LEA is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with LEA. If not, see . + */ + + +import java.awt.image.BufferedImage; + +/** + * Describes a capture device. For now it is only tested + * with images in 640x480 at RGB or YUV color space. + * + * @author Florian Frankenberger + */ +public interface ICaptureDevice { + + /** + * Returns the frame rate of the image source per second + * + * @return the frame rate (e.g. 15 = 15 frames per second) + */ + public int getFrameRate(); + + /** + * Will be called a maximum of getFrameRate()-times in a second and returns + * the actual image of the capture device + * + * @return the actual image of the capture device + */ + public BufferedImage getImage(); + + /** + * LEA calls this when it cleans up. You should put your own cleanup code in here. + */ + public void close(); + + +} diff --git a/Robust/src/Benchmarks/SSJava/EyeTracking/IEyeMovementListener.java b/Robust/src/Benchmarks/SSJava/EyeTracking/IEyeMovementListener.java new file mode 100644 index 00000000..339514cb --- /dev/null +++ b/Robust/src/Benchmarks/SSJava/EyeTracking/IEyeMovementListener.java @@ -0,0 +1,50 @@ +/* + * Copyright 2009 (c) Florian Frankenberger (darkblue.de) + * + * This file is part of LEA. + * + * LEA is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * LEA is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with LEA. If not, see . + */ + + +import de.darkblue.lea.model.Deviation; + +/** + * Implementations of eye movements and face detections should + * look like this. + * s + * @author Florian Frankenberger + */ +public interface IEyeMovementListener { + + /** + * Is called whenever a face has been detected. Only + * if a face was detected onEyeMoved will be + * called (no face = no eye movement) + */ + public void onFaceDetected(); + + /** + * If the face was lost this method is being called + */ + public void onFaceLost(); + + /** + * Gets called whenever an eye movement has been recognized + * + * @param deviation the calculated deviation + */ + public void onEyeMoved(Deviation deviation); + +} diff --git a/Robust/src/Benchmarks/SSJava/EyeTracking/InfoPanel.java b/Robust/src/Benchmarks/SSJava/EyeTracking/InfoPanel.java new file mode 100644 index 00000000..77bf54f8 --- /dev/null +++ b/Robust/src/Benchmarks/SSJava/EyeTracking/InfoPanel.java @@ -0,0 +1,158 @@ +/* + * Copyright 2009 (c) Florian Frankenberger (darkblue.de) + * + * This file is part of LEA. + * + * LEA is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * LEA is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with LEA. If not, see . + */ + + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.io.InputStream; +import javax.imageio.ImageIO; +import javax.swing.JPanel; + +/** + * + * @author Florian + */ +abstract class InfoPanel extends JPanel { + + private static final long serialVersionUID = 8311083210432152308L; + + private String text = ""; + private BufferedImage image = null; + private BufferedImage[] noImageImages = null; + private int imageWidth, imageHeight; + private int animationTime = 0; + + private AnimationThread animationThread = null; + + private class AnimationThread extends Thread { + + private boolean shutdown = false; + private int counter = 0; + + public AnimationThread() { + this.start(); + } + + public void shutdown() { + this.shutdown = true; + } + + @Override + public void run() { + while (!shutdown) { + counter = (++counter % noImageImages.length); + image = noImageImages[counter]; + repaint(); + + try { Thread.sleep(animationTime); } catch (InterruptedException e) {} + } + } + + } + + public InfoPanel(String text, String[] noImageImageFileNames, int fps, int imageWidth, int imageHeight) { + this.text = text; + this.imageWidth = imageWidth; + this.imageHeight = imageHeight; + if (noImageImageFileNames == null || noImageImageFileNames.length == 0) { + this.noImageImages = null; + } else { + this.noImageImages = new BufferedImage[noImageImageFileNames.length]; + for (int i = 0; i < noImageImageFileNames.length; ++i) { + this.noImageImages[i] = loadImage(noImageImageFileNames[i]); + } + } + this.animationTime = (fps == 0 ? 0 : 1000/fps); + this.setImage(null); + } + + protected static BufferedImage loadImage(String fileName) { + BufferedImage image = null; + try { + InputStream in = + FaceInfoPanel.class.getClassLoader().getResourceAsStream(fileName); + if (in != null) { + image = ImageIO.read(in); + in.close(); + } + } catch (IOException ex) { + ex.printStackTrace(); + + } + + return image; + } + + @Override + public void paint(Graphics g) { + Graphics2D g2d = (Graphics2D) g; + + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, + RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR); + + g2d.setBackground(new Color(0, 0, 0)); + g2d.clearRect(0, 0, this.getWidth(), this.getHeight()); + + g2d.setColor(new Color(39, 53, 66)); + g2d.fillRoundRect(2, 2, this.getWidth()-4, this.getHeight()-4, 10, 10); + + g2d.setColor(new Color(118, 149, 174)); + g2d.drawString(text, 10, 20); + + g2d.setColor(new Color(81, 111, 137)); + g2d.drawRect(this.getWidth()-11-imageWidth, 9, imageWidth+1, imageHeight+1); + + if (image != null) { + g2d.drawImage(image, + this.getWidth() - 10 - imageWidth, 10, + imageWidth, imageHeight, null); + } + + g2d.setStroke(new BasicStroke(2.0f)); + g2d.setColor(new Color(81, 111, 137)); + g2d.drawRoundRect(2, 2, this.getWidth()-4, this.getHeight()-4, 10, 10); + } + + protected synchronized void setImage(BufferedImage image) { + if (image == null) { + if (this.noImageImages != null && this.noImageImages.length > 0) { + image = this.noImageImages[0]; + if (this.animationTime > 0) { + if (this.animationThread == null) + this.animationThread = new AnimationThread(); + } + } + } else { + if (this.animationThread != null) { + this.animationThread.shutdown(); + this.animationThread = null; + } + } + this.image = image; + this.repaint(); + } + + +} diff --git a/Robust/src/Benchmarks/SSJava/EyeTracking/IntegralImageData.java b/Robust/src/Benchmarks/SSJava/EyeTracking/IntegralImageData.java new file mode 100644 index 00000000..f6aad026 --- /dev/null +++ b/Robust/src/Benchmarks/SSJava/EyeTracking/IntegralImageData.java @@ -0,0 +1,70 @@ +/* + * Copyright 2009 (c) Florian Frankenberger (darkblue.de) + * + * This file is part of LEA. + * + * LEA is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * LEA is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with LEA. If not, see . + */ + + + +/** + * No description given. + * + * @author Florian Frankenberger + */ +public class IntegralImageData { + + private long[][] integral; + private Dimension dimension; + + public IntegralImageData(BufferedImage bufferedImage) { + this.integral = new long[bufferedImage.getWidth()][bufferedImage.getHeight()]; + this.dimension = new Dimension(bufferedImage.getWidth(), bufferedImage.getHeight()); + + int[] pixelBuffer = new int[bufferedImage.getWidth()*bufferedImage.getHeight()]; + PixelGrabber pg = new PixelGrabber( + bufferedImage, 0, 0, bufferedImage.getWidth(), bufferedImage.getHeight(), pixelBuffer, 0, bufferedImage.getWidth()); + + try { + pg.grabPixels(); + } catch (InterruptedException ie) {} + + long[][] s = new long[bufferedImage.getWidth()][bufferedImage.getHeight()]; + for (int y = 0; y < bufferedImage.getHeight(); ++y) { + for (int x = 0; x < bufferedImage.getWidth(); ++x) { + s[x][y] = (y-1 < 0 ? 0 : s[x][y-1]) + (pixelBuffer[y*bufferedImage.getWidth() + x] & 0xff); + this.integral[x][y] = (x-1 < 0 ? 0 : this.integral[x-1][y]) + s[x][y]; + } + } + + } + + public long getIntegralAt(int x, int y) { + return this.integral[x][y]; + } + + public Dimension getDimension() { + return this.dimension; + } + + public int getWidth() { + return this.dimension.width; + } + + public int getHeight() { + return this.dimension.height; + } + +} diff --git a/Robust/src/Benchmarks/SSJava/EyeTracking/JMFCaptureDevice.java b/Robust/src/Benchmarks/SSJava/EyeTracking/JMFCaptureDevice.java new file mode 100644 index 00000000..5199a853 --- /dev/null +++ b/Robust/src/Benchmarks/SSJava/EyeTracking/JMFCaptureDevice.java @@ -0,0 +1,213 @@ +/* + * Copyright 2009 (c) Florian Frankenberger (darkblue.de) + * + * This file is part of LEA. + * + * LEA is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * LEA is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with LEA. If not, see . + */ + + +import java.awt.Dimension; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.util.Vector; + +import javax.media.Buffer; +import javax.media.CannotRealizeException; +import javax.media.CaptureDeviceInfo; +import javax.media.CaptureDeviceManager; +import javax.media.Format; +import javax.media.Manager; +import javax.media.MediaLocator; +import javax.media.NoDataSourceException; +import javax.media.NoPlayerException; +import javax.media.Player; +import javax.media.control.FormatControl; +import javax.media.control.FrameGrabbingControl; +import javax.media.format.RGBFormat; +import javax.media.format.VideoFormat; +import javax.media.format.YUVFormat; +import javax.media.protocol.CaptureDevice; +import javax.media.protocol.DataSource; +import javax.media.util.BufferToImage; + +import de.darkblue.lea.ifaces.ICaptureDevice; + +/** + * This class is a proxy to the Java Media Framework. You can use + * this class to make use of a JMF compatible webcam or + * other image source. + *

+ * To receive a list of all available image sources just call the static + * method getImageSources. + * + * @author Florian Frankenberger + */ +public class JMFCaptureDevice implements ICaptureDevice { + + private Player player; + private FrameGrabbingControl fgc; + + /** + * Initializes the JMF with the first available (YUV compatible) image source. The image + * source is then tested if it matches certain criteria - if not an IllegalStateException + * is thrown. + *

+ * Criteria are: + *

  • provides YUV or RGB images + *
  • can provide images with 640x480 pixels + * + * @throws NoDataSourceException + * @throws NoPlayerException + * @throws CannotRealizeException + * @throws IOException + * @throws IllegalStateException if the data source does not match the criteria + */ + public JMFCaptureDevice() throws NoDataSourceException, NoPlayerException, CannotRealizeException, IOException { + CaptureDeviceInfo imageSource = null; + + // get all image sources on the system that can supply us with at least YUV-images + CaptureDeviceInfo[] devices = getImageSourcesAvailable(); + + if (devices.length == 0) { + throw new IllegalStateException("No Webcams found on this system."); + } + + // we use the first best (most of the time this is the webcam the user wants) + imageSource = devices[0]; + + initImageSource(imageSource); + } + + /** + * Initializes the JMF with the given image source. An IllegalStateException is thrown + * if the image source does not the following criteria: + *

    + * Criteria are: + *

  • provides YUV or RGB images + *
  • can provide images with 640x480 pixels + * + * @param imageSource the image source to use + * @throws NoDataSourceException + * @throws NoPlayerException + * @throws CannotRealizeException + * @throws IOException + * @throws IllegalStateException if the data source does not match the criteria + */ + public JMFCaptureDevice(CaptureDeviceInfo imageSource) throws NoDataSourceException, NoPlayerException, CannotRealizeException, IOException { + initImageSource(imageSource); + } + + private void initImageSource(CaptureDeviceInfo imageSource) throws NoDataSourceException, IOException, NoPlayerException, CannotRealizeException { + if (imageSource == null) throw new IllegalStateException("Image source cannot be null"); + + // search the right format + VideoFormat matchingFormat = null; + VideoFormat alternateMatchingFormat = null; + for (Format format: imageSource.getFormats()) { + if (format instanceof VideoFormat) { + VideoFormat videoFormat = (VideoFormat) format; + + if (videoFormat instanceof RGBFormat) { + RGBFormat rgbFormat = (RGBFormat)videoFormat; + Dimension size = rgbFormat.getSize(); + + if (size.width == 640 && size.height == 480 && + rgbFormat.getBitsPerPixel() == 24) { + matchingFormat = videoFormat; + break; + } + } + + if (videoFormat instanceof YUVFormat) { + YUVFormat rgbFormat = (YUVFormat)videoFormat; + Dimension size = rgbFormat.getSize(); + + if (size.width == 640 && size.height == 480) { + alternateMatchingFormat = videoFormat; + } + } + } + } + + if (matchingFormat == null && alternateMatchingFormat != null) + matchingFormat = alternateMatchingFormat; + + if (matchingFormat == null) { + throw new IllegalStateException ("Your image source does not support the 640x480 RGB/YUV format. This testenvironment relies on the fact, that your cam provides this resolution in this colorspace."); + } + + MediaLocator mediaLocator = imageSource.getLocator(); + + DataSource dataSource = Manager.createDataSource(mediaLocator); + for (FormatControl formatControl: ((CaptureDevice) dataSource).getFormatControls()) { + if (formatControl == null) continue; + formatControl.setFormat(matchingFormat); + } + + player = Manager.createRealizedPlayer(dataSource); + + player.setRate(15); + player.start(); + + fgc = (FrameGrabbingControl) player.getControl("javax.media.control.FrameGrabbingControl"); + } + + /** + * Returns a vector of all image sources available on this system + * @return a vector of image sources + */ + @SuppressWarnings("unchecked") + public static CaptureDeviceInfo[] getImageSourcesAvailable() { + // get all image sources on the system that can supply us with at least YUV-images + Vector devices = CaptureDeviceManager.getDeviceList(new VideoFormat(VideoFormat.YUV)); + return devices.toArray(new CaptureDeviceInfo[0]); + } + + + /* (non-Javadoc) + * @see de.darkblue.lea.ICaptureDevice#getFrameRate() + */ + @Override + public int getFrameRate() { + return 15; + } + + /* (non-Javadoc) + * @see de.darkblue.lea.ICaptureDevice#getImage() + */ + @Override + public BufferedImage getImage() { + Buffer buffer = fgc.grabFrame(); + + // Convert it to an image + BufferToImage btoi = new BufferToImage((VideoFormat)buffer.getFormat()); + return (BufferedImage)btoi.createImage(buffer); + } + + /* (non-Javadoc) + * @see de.darkblue.lea.ICaptureDevice#close() + */ + @Override + public void close() { + if (player != null) { + player.close(); + player.deallocate(); + } + } + + + + +} diff --git a/Robust/src/Benchmarks/SSJava/EyeTracking/LEA.java b/Robust/src/Benchmarks/SSJava/EyeTracking/LEA.java new file mode 100644 index 00000000..c51fd076 --- /dev/null +++ b/Robust/src/Benchmarks/SSJava/EyeTracking/LEA.java @@ -0,0 +1,176 @@ +import Benchmarks.oooJava.barneshut.FileInputStream; + +/* + * Copyright 2009 (c) Florian Frankenberger (darkblue.de) + * + * This file is part of LEA. + * + * LEA is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * LEA is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with LEA. If not, see . + */ + +/** + * This is the main class of LEA. + *

    + * It uses a face detection algorithm to find an a face within the provided + * image(s). Then it searches for the eye in a region where it most likely + * located and traces its position relative to the face and to the last known + * position. The movements are estimated by comparing more than one movement. If + * a movement is distinctly pointing to a direction it is recognized and all + * listeners get notified. + *

    + * The notification is designed as observer pattern. You simply call + * addEyeMovementListener(IEyeMovementListener) to add an + * implementation of IEyeMovementListener to LEA. When a face is + * recognized/lost or whenever an eye movement is detected LEA will call the + * appropriate methods of the listener + *

    + * LEA also needs an image source implementing the ICaptureDevice. + * One image source proxy to the Java Media Framework is included ( + * JMFCaptureDevice). + *

    + * Example (for using LEA with Java Media Framework): + *

    + * + * LEA lea = new LEA(new JMFCaptureDevice(), true); + * + *

    + * This will start LEA with the first available JMF datasource with an extra + * status window showing if face/eye has been detected successfully. Please note + * that face detection needs about 2 seconds to find a face. After detection the + * following face detection is much faster. + * + * @author Florian Frankenberger + */ +public class LEA { + + private boolean showStatusWindow; + + private boolean shutdown = false; + + // private LEAImplementation implementation = new LEAImplementation(); + + // private ImageProcessor imageProcessor; + // + // private class ImageProcessor extends TimedThread { + // + // private FaceAndEyePosition lastPositions = new FaceAndEyePosition(null, + // null); + // private DeviationScanner deviationScanner = new DeviationScanner(); + // private int counter = 0; + // + // private int fps; + // + // public ImageProcessor(int fps) { + // super(fps); + // this.fps = fps; + // } + // + // @Override + // public void doRun() { + // + // BufferedImage image = captureDevice.getImage(); + // if (image == null) + // return; + // + // try { + // FaceAndEyePosition positions = implementation.getEyePosition(image); + // + // if (((lastPositions.getFacePosition() == null && + // positions.getFacePosition() != null) || (lastPositions + // .getFacePosition() != null && positions.getFacePosition() == null)) || + // counter++ > fps) { + // + // if ((lastPositions.getFacePosition() == null && positions.getFacePosition() + // != null) + // || (lastPositions.getFacePosition() != null && positions.getFacePosition() + // == null)) { + // if (positions.getFacePosition() != null) { + // notifyEyeMovementListenerFaceDetected(); + // } else { + // notifyEyeMovementListenerFaceLost(); + // } + // } + // counter = 0; + // if (statusWindow != null) + // statusWindow.getFaceInfoPanel().setFace(image, + // positions.getFacePosition()); + // } + // + // if (positions.getEyePosition() != null) { + // if (statusWindow != null) { + // statusWindow.getEyeInfoPanel().setEyePosition(image, + // positions.getFacePosition(), + // positions.getEyePosition()); + // } + // deviationScanner.addEyePosition(positions.getEyePosition()); + // Deviation deviation = + // deviationScanner.scanForDeviation(positions.getFacePosition());// + // positions.getEyePosition().getDeviation(lastPositions.getEyePosition()); + // + // if (deviation != Deviation.NONE) { + // notifyEyeMovementListenerEyeMoved(deviation); + // } + // + // } else { + // if (statusWindow != null) + // statusWindow.getEyeInfoPanel().setDeviation(null); + // } + // + // lastPositions = positions; + // } catch (Exception e) { + // e.printStackTrace(); + // try { + // close(); + // } catch (Exception e2) { + // } + // } + // } + // + // public synchronized void clearDeviationScanner() { + // this.deviationScanner.clear(); + // } + // + // } + + public LEA() { + // this.imageProcessor = new + // ImageProcessor(this.captureDevice.getFrameRate()); + // this.imageProcessor.start(); + LEAImplementation impl = new LEAImplementation(); + System.out.println("Done."); + } + + /** + * Clears the internal movement buffer. If you just capture some of the eye + * movements you should call this every time you start recording the + * movements. Otherwise you may get notified for movements that took place + * BEFORE you started recording. + */ + public void clear() { + // this.imageProcessor.clearDeviationScanner(); + } + + /** + * To test LEA with the first capture device from the + * Java Media Framework just start from here. + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + LEA lea = new LEA(); + + } + +} diff --git a/Robust/src/Benchmarks/SSJava/EyeTracking/LEAImplementation.java b/Robust/src/Benchmarks/SSJava/EyeTracking/LEAImplementation.java new file mode 100644 index 00000000..39d16478 --- /dev/null +++ b/Robust/src/Benchmarks/SSJava/EyeTracking/LEAImplementation.java @@ -0,0 +1,117 @@ +/* + * Copyright 2009 (c) Florian Frankenberger (darkblue.de) + * + * This file is part of LEA. + * + * LEA is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * LEA is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with LEA. If not, see . + */ + +/** + * No description given. + * + * @author Florian Frankenberger + */ +public class LEAImplementation { + + // private ClassifierTree classifierTree = null; + + // private Rectangle2D lastRectangle; + + public LEAImplementation() { + this.loadFaceData(); + } + + // public FaceAndEyePosition getEyePosition(BufferedImage image) { + // if (image == null) + // return null; + // + // Rectangle2D faceRect = this.classifierTree.locateFaceRadial(image, + // lastRectangle); + // EyePosition eyePosition = null; + // if (faceRect != null) { + // + // lastRectangle = faceRect; + // Point point = readEyes(image, faceRect); + // if (point != null) { + // eyePosition = new EyePosition(point, faceRect); + // } + // } + // + // return new FaceAndEyePosition(faceRect, eyePosition); + // } + + public boolean needsCalibration() { + return false; + } + + /** + * This method loads the faceData from a file called facedata.dat which should + * be within the jar-file + */ + private void loadFaceData() { + + FileInputStream inputFile = new FileInputStream("facedata.dat"); + + int numClassifier = Integer.parseInt(inputFile.readLine()); + System.out.println("numClassifier=" + numClassifier); + for (int c = 0; c < numClassifier; c++) { + + int numArea = Integer.parseInt(inputFile.readLine()); + Classifier classifier = new Classifier(numArea); + // parsing areas + for (int idx = 0; idx < numArea; idx++) { + // 54,54,91,62,296.0 + Point fromPoint = new Point(); + Point toPoint = new Point(); + fromPoint.x = Integer.parseInt(inputFile.readLine()); + fromPoint.y = Integer.parseInt(inputFile.readLine()); + toPoint.x = Integer.parseInt(inputFile.readLine()); + toPoint.y = Integer.parseInt(inputFile.readLine()); + float size = Float.parseFloat(inputFile.readLine()); + ScanArea area = new ScanArea(fromPoint, toPoint, size); + classifier.setScanArea(idx, area); + } + + // parsing possibilities face yes + float array[] = new float[numArea]; + for (int idx = 0; idx < numArea; idx++) { + array[idx] = Float.parseFloat(inputFile.readLine()); + } + classifier.setPossibilitiesFaceYes(array); + + // parsing possibilities face no + for (int idx = 0; idx < numArea; idx++) { + array[idx] = Float.parseFloat(inputFile.readLine()); + } + classifier.setPossibilitiesFaceNo(array); + classifier.setPossibilityFaceYes(Integer.parseInt(inputFile.readLine())); + classifier.setPossibilityFaceNo(Integer.parseInt(inputFile.readLine())); + + } + } + // private Point readEyes(BufferedImage image, Rectangle2D rect) { + // + // // now we cluster the black image points and try to find the inner eye + // /* + // * BlackHoleDetector bhd = new BlackHoleDetector(image, rect); + // * bhd.detect(20); + // * + // * return bhd.getPosition(); + // */ + // + // EyeDetector ed = new EyeDetector(image, rect); + // return ed.detectEye(); + // } + +} diff --git a/Robust/src/Benchmarks/SSJava/EyeTracking/LEAStatusWindow.java b/Robust/src/Benchmarks/SSJava/EyeTracking/LEAStatusWindow.java new file mode 100644 index 00000000..105dc677 --- /dev/null +++ b/Robust/src/Benchmarks/SSJava/EyeTracking/LEAStatusWindow.java @@ -0,0 +1,127 @@ +/* + * Copyright 2009 (c) Florian Frankenberger (darkblue.de) + * + * This file is part of LEA. + * + * LEA is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * LEA is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with LEA. If not, see . + */ + + +/** + * + * @author Florian + */ +class LEAStatusWindow extends javax.swing.JFrame { + + private static final long serialVersionUID = 6565861506173488477L; + + /** Creates new form LEAStatusWindow */ + public LEAStatusWindow() { + initComponents(); + this.setLocationRelativeTo(null); + } + + public FaceInfoPanel getFaceInfoPanel() { + return (FaceInfoPanel)this.faceInfoPanel; + } + + public EyeInfoPanel getEyeInfoPanel() { + return (EyeInfoPanel)this.eyeInfoPanel; + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + jPanel1 = new javax.swing.JPanel(); + faceInfoPanel = new FaceInfoPanel(); + eyeInfoPanel = new EyeInfoPanel(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE); + setTitle("LEA Status Window"); + setBackground(new java.awt.Color(0, 0, 0)); + setResizable(false); + + jPanel1.setBackground(new java.awt.Color(0, 0, 0)); + + javax.swing.GroupLayout faceInfoPanelLayout = new javax.swing.GroupLayout(faceInfoPanel); + faceInfoPanel.setLayout(faceInfoPanelLayout); + faceInfoPanelLayout.setHorizontalGroup( + faceInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 468, Short.MAX_VALUE) + ); + faceInfoPanelLayout.setVerticalGroup( + faceInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 119, Short.MAX_VALUE) + ); + + javax.swing.GroupLayout eyeInfoPanelLayout = new javax.swing.GroupLayout(eyeInfoPanel); + eyeInfoPanel.setLayout(eyeInfoPanelLayout); + eyeInfoPanelLayout.setHorizontalGroup( + eyeInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 468, Short.MAX_VALUE) + ); + eyeInfoPanelLayout.setVerticalGroup( + eyeInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 60, Short.MAX_VALUE) + ); + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(eyeInfoPanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(faceInfoPanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addComponent(faceInfoPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(eyeInfoPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + ); + + pack(); + }// //GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel eyeInfoPanel; + private javax.swing.JPanel faceInfoPanel; + private javax.swing.JPanel jPanel1; + // End of variables declaration//GEN-END:variables + +} diff --git a/Robust/src/Benchmarks/SSJava/EyeTracking/Point.java b/Robust/src/Benchmarks/SSJava/EyeTracking/Point.java new file mode 100644 index 00000000..cfc3eafa --- /dev/null +++ b/Robust/src/Benchmarks/SSJava/EyeTracking/Point.java @@ -0,0 +1,14 @@ +public class Point { + + public int x; + public int y; + + public Point(int x, int y) { + this.x = x; + this.y = y; + } + + public Point() { + } + +} diff --git a/Robust/src/Benchmarks/SSJava/EyeTracking/ScanArea.java b/Robust/src/Benchmarks/SSJava/EyeTracking/ScanArea.java new file mode 100644 index 00000000..df3c8425 --- /dev/null +++ b/Robust/src/Benchmarks/SSJava/EyeTracking/ScanArea.java @@ -0,0 +1,115 @@ +/* + * Copyright 2009 (c) Florian Frankenberger (darkblue.de) + * + * This file is part of LEA. + * + * LEA is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * LEA is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with LEA. If not, see . + */ + +/** + * + * @author Florian + */ +public class ScanArea { + + private Point fromPoint; + private Point toPoint; + private float size; + + /** + * Imagine you want to classify an image with 100px x 100px what would be the + * scanarea in this kind of image. That size gets automatically scalled to fit + * bigger images + * + * @param fromPoint + * @param toPoint + */ + public ScanArea(Point fromPoint, Point toPoint) { + this.fromPoint = fromPoint; + this.toPoint = toPoint; + + this.size = (this.toPoint.x - this.fromPoint.x) * (this.toPoint.y - this.fromPoint.y); + } + + public ScanArea(Point fromPoint, Point toPoint, float size) { + this.fromPoint = fromPoint; + this.toPoint = toPoint; + this.size = size; + } + + public ScanArea(int fromX, int fromY, int width, int height) { + this(new Point(fromX, fromY), new Point(fromX + width, fromY + height)); + } + + public int getFromX(float scaleFactor) { + return (int) (this.fromPoint.x * scaleFactor); + } + + public int getFromY(float scaleFactor) { + return (int) (this.fromPoint.y * scaleFactor); + } + + public int getToX(float scaleFactor) { + return (int) (this.toPoint.x * scaleFactor); + } + + public int getToY(float scaleFactor) { + return (int) (this.toPoint.y * scaleFactor); + } + + public int getSize(float scaleFactor) { + return (int) (this.size * Math.pow(scaleFactor, 2)); + } + + @Override + public boolean equals(Object o) { + ScanArea other = (ScanArea) o; + + return pointsWithin(other.fromPoint.x, other.toPoint.x, this.fromPoint.x, this.toPoint.x) + && pointsWithin(other.fromPoint.y, other.toPoint.y, this.fromPoint.y, this.toPoint.y); + } + + private static boolean pointsWithin(int pointA1, int pointA2, int pointB1, int pointB2) { + boolean within = false; + within = within || (pointB1 >= pointA1 && pointB1 <= pointA2); + within = within || (pointB2 >= pointA1 && pointB2 <= pointA2); + within = within || (pointA1 >= pointB1 && pointA1 <= pointB2); + within = within || (pointA2 >= pointB1 && pointA2 <= pointB2); + + return within; + } + + // private boolean checkPoints(ScanArea a, ScanArea b) { + // Point[] pointsToCheck = new Point[] { + // a.fromPoint, a.toPoint, + // new Point (a.fromPoint.x, a.toPoint.y), + // new Point (a.toPoint.x, a.fromPoint.y) + // }; + // for (Point point: pointsToCheck) { + // if (point.x >= b.fromPoint.x && point.x <= b.toPoint.x && + // point.y >= b.fromPoint.y && point.y <= b.toPoint.y) return true; + // } + // + // return false; + // } + + public String toString() { + String str = ""; + str += "fromPoint=(" + fromPoint.x + "," + fromPoint.y + ")"; + str += "\n"; + str += "toPoint=(" + toPoint.x + "," + toPoint.y + ")"; + str += "\n"; + return str; + } +} diff --git a/Robust/src/Benchmarks/SSJava/EyeTracking/StaticSizeArrayList.java b/Robust/src/Benchmarks/SSJava/EyeTracking/StaticSizeArrayList.java new file mode 100644 index 00000000..168369c2 --- /dev/null +++ b/Robust/src/Benchmarks/SSJava/EyeTracking/StaticSizeArrayList.java @@ -0,0 +1,72 @@ +/* + * Copyright 2009 (c) Florian Frankenberger (darkblue.de) + * + * This file is part of LEA. + * + * LEA is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * LEA is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with LEA. If not, see . + */ + + +/** + * An array with just a static size. If you add more than + * the capacity holds the oldest element gets removed. + *

    + * This List is implemented as an ring buffer array. + *

    + * TODO: implement the List interface + * + * @author Florian Frankenberger + */ +public class StaticSizeArrayList { + + private Object[] buffer; + private int startPos = 0; + private int pos = 0; + private int size = 0; + + public StaticSizeArrayList(int size) { + this.buffer = new Object[size]; + } + + public synchronized void add(T item) { + this.buffer[pos] = item; + pos = ++pos % buffer.length; + if (size < buffer.length) { + size++; + } else { + this.startPos = ++this.startPos % this.buffer.length; + } + } + + @SuppressWarnings("unchecked") + public synchronized T get(int i) { + if (i >= this.size) + throw new ArrayIndexOutOfBoundsException("Size is "+this.size+" but tried to access item "+i); + + int acPos = (this.startPos + i) % this.buffer.length; + + return (T)this.buffer[acPos]; + } + + public synchronized void clear() { + this.startPos = 0; + this.pos = 0; + this.size = 0; + } + + public synchronized int size() { + return this.size; + } + +} diff --git a/Robust/src/Benchmarks/SSJava/EyeTracking/facedata.dat b/Robust/src/Benchmarks/SSJava/EyeTracking/facedata.dat new file mode 100644 index 00000000..a38e0e8d --- /dev/null +++ b/Robust/src/Benchmarks/SSJava/EyeTracking/facedata.dat @@ -0,0 +1,2090 @@ +8 +6 +54 +54 +91 +62 +296.0 +25 +47 +39 +66 +266.0 +12 +29 +45 +38 +297.0 +49 +65 +62 +86 +273.0 +58 +38 +90 +47 +288.0 +49 +5 +61 +28 +276.0 +0.78447694 +0.51399076 +0.019654196 +0.038308397 +0.7471684 +0.89640224 +0.43222174 +0.5485019 +0.56839997 +0.44714534 +0.44154882 +0.5034207 +107 +3210 +7 +43 +65 +57 +71 +84.0 +42 +55 +81 +58 +117.0 +76 +21 +79 +49 +84.0 +54 +27 +69 +33 +90.0 +43 +40 +58 +46 +90.0 +25 +73 +57 +76 +96.0 +36 +21 +60 +25 +96.0 +0.57928056 +0.9243835 +0.5139905 +0.29946703 +0.30879453 +0.17821494 +0.6632244 +0.4956475 +0.49564773 +0.4794796 +0.49347022 +0.5314026 +0.54974556 +0.561873 +107 +3210 +9 +35 +74 +54 +79 +95.0 +12 +61 +23 +70 +99.0 +60 +45 +69 +56 +99.0 +58 +26 +87 +30 +116.0 +27 +60 +49 +65 +110.0 +53 +45 +59 +61 +96.0 +44 +38 +70 +42 +104.0 +48 +18 +75 +22 +108.0 +29 +31 +62 +34 +99.0 +0.112925306 +0.5979346 +0.93371063 +0.07561684 +0.41139242 +0.45802805 +0.73784137 +0.4953364 +0.532645 +0.50652957 +0.5596948 +0.4552287 +0.46455583 +0.54508185 +0.45616162 +0.48165566 +0.4869416 +0.5376199 +107 +3210 +13 +32 +32 +60 +36 +112.0 +28 +18 +46 +24 +108.0 +36 +52 +71 +55 +105.0 +22 +45 +55 +48 +99.0 +59 +37 +92 +40 +99.0 +30 +60 +59 +64 +116.0 +73 +67 +92 +72 +95.0 +67 +11 +73 +27 +96.0 +55 +82 +75 +87 +100.0 +32 +37 +56 +41 +96.0 +6 +27 +14 +39 +96.0 +58 +44 +82 +48 +96.0 +41 +72 +45 +96 +96.0 +0.3927383 +0.17821503 +0.69120574 +0.6165889 +0.8590937 +0.28081292 +0.79380393 +0.08494394 +0.70985985 +0.37408417 +0.14090677 +0.93371063 +0.280813 +0.5202099 +0.5513008 +0.48352194 +0.5264276 +0.4269359 +0.51119345 +0.43066725 +0.45709372 +0.4431036 +0.51896566 +0.5761743 +0.43595245 +0.4853875 +107 +3210 +21 +70 +43 +89 +46 +57.0 +39 +37 +54 +40 +45.0 +33 +60 +53 +63 +60.0 +52 +67 +59 +74 +49.0 +51 +14 +55 +25 +44.0 +13 +73 +26 +77 +52.0 +71 +69 +84 +73 +52.0 +59 +35 +66 +42 +49.0 +13 +35 +17 +46 +44.0 +35 +23 +38 +38 +45.0 +47 +51 +63 +54 +48.0 +58 +56 +77 +59 +57.0 +33 +72 +40 +79 +49.0 +39 +41 +54 +44 +45.0 +8 +57 +14 +65 +48.0 +58 +10 +66 +16 +48.0 +43 +83 +62 +86 +57.0 +20 +25 +28 +31 +48.0 +35 +47 +50 +50 +45.0 +70 +47 +81 +51 +44.0 +10 +52 +24 +56 +56.0 +0.9243835 +0.17821491 +0.13157943 +0.5419719 +0.94303775 +0.16888793 +0.80313104 +0.6538973 +0.2528317 +0.2714859 +0.5979345 +0.9803462 +0.03830837 +0.1222525 +0.07561681 +0.9243835 +0.50466365 +0.001 +0.21552329 +0.9803462 +0.5233179 +0.41791958 +0.49968916 +0.50497437 +0.44185993 +0.48569784 +0.5497462 +0.42507058 +0.44652277 +0.5702664 +0.5276726 +0.45025402 +0.4306672 +0.500933 +0.49657974 +0.550678 +0.46766484 +0.4685978 +0.5634273 +0.5105703 +0.42569247 +0.5606273 +107 +3210 +37 +35 +20 +45 +24 +40.0 +28 +58 +44 +61 +48.0 +29 +43 +45 +46 +48.0 +50 +53 +53 +65 +36.0 +73 +64 +75 +82 +36.0 +22 +70 +37 +73 +45.0 +56 +51 +62 +57 +36.0 +19 +22 +23 +31 +36.0 +16 +63 +18 +81 +36.0 +79 +58 +81 +76 +36.0 +13 +52 +29 +55 +48.0 +46 +8 +61 +11 +45.0 +53 +38 +68 +41 +45.0 +84 +37 +86 +55 +36.0 +38 +25 +51 +28 +39.0 +69 +28 +70 +63 +35.0 +32 +62 +45 +65 +39.0 +64 +14 +80 +17 +48.0 +39 +70 +49 +74 +40.0 +15 +33 +19 +42 +36.0 +49 +46 +59 +50 +40.0 +41 +13 +51 +17 +40.0 +38 +86 +46 +91 +40.0 +79 +22 +82 +34 +36.0 +66 +88 +74 +93 +40.0 +54 +73 +56 +91 +36.0 +2 +47 +7 +54 +35.0 +57 +81 +65 +86 +40.0 +36 +29 +44 +34 +40.0 +3 +60 +15 +63 +36.0 +27 +35 +34 +40 +35.0 +57 +59 +59 +77 +36.0 +64 +64 +69 +71 +35.0 +26 +14 +28 +32 +36.0 +85 +58 +94 +62 +36.0 +51 +30 +57 +36 +36.0 +42 +80 +49 +85 +35.0 +0.24350454 +0.44870088 +0.36475706 +0.7285142 +0.9057293 +0.29946718 +0.32744858 +0.028981311 +0.3834112 +0.961692 +0.87774795 +0.9057293 +0.6445702 +0.88707507 +0.54197204 +0.99900043 +0.1315795 +0.45802796 +0.48600936 +0.16888788 +0.6725514 +0.93371063 +0.45802793 +0.18754214 +0.60726196 +0.4020654 +0.010327146 +0.52331775 +0.31812155 +0.07561681 +0.8590937 +0.3181214 +0.70053285 +0.001 +0.52331793 +0.5419721 +0.38341117 +0.5376197 +0.5286042 +0.52269644 +0.46206897 +0.4185414 +0.5307805 +0.44310337 +0.5584525 +0.53886336 +0.41698694 +0.546638 +0.5080832 +0.44963196 +0.42444828 +0.51274693 +0.42382675 +0.51492363 +0.45243058 +0.48103434 +0.5528546 +0.46984145 +0.5180326 +0.49067295 +0.44590148 +0.43968338 +0.44154894 +0.56404704 +0.44869992 +0.5335793 +0.5453939 +0.5528552 +0.42071792 +0.42942348 +0.5472579 +0.42413813 +0.47077382 +0.4866306 +107 +3210 +69 +29 +33 +31 +44 +22.0 +75 +35 +83 +38 +24.0 +33 +36 +34 +57 +21.0 +32 +71 +36 +77 +24.0 +70 +34 +74 +40 +24.0 +51 +84 +56 +89 +25.0 +35 +26 +39 +32 +24.0 +25 +60 +34 +63 +27.0 +41 +51 +46 +56 +25.0 +49 +23 +55 +27 +24.0 +43 +23 +44 +44 +21.0 +72 +57 +75 +64 +21.0 +26 +50 +32 +54 +24.0 +17 +55 +24 +58 +21.0 +5 +42 +11 +46 +24.0 +64 +19 +70 +23 +24.0 +51 +47 +57 +51 +24.0 +20 +86 +28 +89 +24.0 +30 +10 +33 +17 +21.0 +71 +25 +78 +28 +21.0 +42 +10 +49 +13 +21.0 +64 +58 +68 +64 +24.0 +24 +71 +29 +76 +25.0 +16 +34 +21 +39 +25.0 +35 +51 +39 +57 +24.0 +57 +67 +58 +88 +21.0 +75 +18 +83 +21 +24.0 +64 +6 +67 +13 +21.0 +71 +81 +74 +88 +21.0 +37 +4 +40 +11 +21.0 +90 +51 +98 +54 +24.0 +35 +58 +42 +61 +21.0 +80 +53 +85 +58 +25.0 +25 +14 +29 +20 +24.0 +43 +80 +51 +83 +24.0 +36 +86 +42 +90 +24.0 +7 +60 +16 +63 +27.0 +21 +27 +30 +30 +27.0 +53 +31 +56 +38 +21.0 +49 +66 +54 +71 +25.0 +52 +4 +61 +7 +27.0 +58 +22 +62 +28 +24.0 +39 +73 +44 +78 +25.0 +27 +64 +32 +69 +25.0 +76 +68 +78 +79 +22.0 +54 +61 +62 +64 +24.0 +54 +53 +59 +58 +25.0 +61 +70 +64 +77 +21.0 +43 +45 +48 +50 +25.0 +62 +83 +70 +86 +24.0 +16 +74 +18 +85 +22.0 +22 +42 +24 +53 +22.0 +15 +18 +21 +22 +24.0 +6 +51 +14 +54 +24.0 +81 +61 +82 +82 +21.0 +41 +92 +50 +95 +27.0 +75 +41 +81 +45 +24.0 +58 +46 +67 +49 +27.0 +52 +13 +59 +16 +21.0 +87 +42 +89 +53 +22.0 +27 +78 +35 +81 +24.0 +46 +61 +52 +65 +24.0 +56 +42 +64 +45 +24.0 +35 +42 +42 +45 +21.0 +61 +33 +66 +38 +25.0 +69 +49 +76 +52 +21.0 +56 +94 +61 +99 +25.0 +30 +86 +34 +92 +24.0 +84 +32 +92 +35 +24.0 +0.89640224 +0.44870088 +0.803131 +0.178215 +0.72851413 +0.5606263 +0.25283164 +0.8964022 +0.20619617 +0.95236486 +0.094271086 +0.99900043 +0.9803462 +0.83111244 +0.1595608 +0.13157965 +0.58860755 +0.1968692 +0.4673551 +0.11292524 +0.9243835 +0.8124582 +0.28081292 +0.13157965 +0.1968692 +0.29014012 +0.1409067 +0.89640224 +0.7005328 +0.87774795 +0.29014015 +0.12225243 +0.9150564 +0.001 +0.280813 +0.3367756 +0.1409067 +0.001 +0.4487009 +0.7378413 +0.89640224 +0.37408397 +0.09427106 +0.5419721 +0.7844768 +0.31812128 +0.3274484 +0.3367757 +0.4020654 +0.5886074 +0.16888782 +0.94303775 +0.08494392 +0.18754199 +0.81245816 +0.7844769 +0.95236486 +0.66322434 +0.9243835 +0.7844769 +0.09427106 +0.5233177 +0.4673551 +0.19686913 +0.6165888 +0.9896733 +0.75649554 +0.26215878 +0.280813 +0.54601437 +0.42662486 +0.5239404 +0.51741076 +0.44030485 +0.46548912 +0.53233284 +0.53264564 +0.5055968 +0.49471414 +0.50404143 +0.42320526 +0.5413512 +0.5450827 +0.55627555 +0.44776708 +0.46393427 +0.54010737 +0.56498075 +0.4434139 +0.5242502 +0.43066725 +0.5410397 +0.54912555 +0.52922535 +0.4328436 +0.44869947 +0.47139576 +0.42475927 +0.54850155 +0.42040655 +0.5174102 +0.42507055 +0.5609385 +0.48880714 +0.497513 +0.5450818 +0.5584515 +0.46144667 +0.4505651 +0.4962689 +0.45087564 +0.49782407 +0.5220751 +0.42724708 +0.4353308 +0.4555398 +0.43657473 +0.5043537 +0.43875065 +0.53824323 +0.530781 +0.56187207 +0.5584515 +0.41667587 +0.48663133 +0.43035597 +0.44403616 +0.4869417 +0.42040643 +0.52922606 +0.47605973 +0.45585036 +0.52735937 +0.44683382 +0.43284342 +0.45989278 +0.5198991 +0.4384393 +107 +3210 +133 +29 +21 +30 +41 +20.0 +24 +73 +26 +83 +20.0 +25 +20 +27 +30 +20.0 +15 +50 +20 +54 +20.0 +86 +28 +89 +35 +21.0 +37 +37 +43 +41 +24.0 +49 +54 +53 +59 +20.0 +33 +56 +39 +60 +24.0 +83 +28 +84 +48 +20.0 +58 +44 +65 +47 +21.0 +77 +73 +85 +76 +24.0 +49 +18 +58 +21 +27.0 +51 +92 +56 +96 +20.0 +41 +45 +49 +48 +24.0 +12 +63 +20 +66 +24.0 +67 +9 +76 +12 +27.0 +69 +26 +76 +29 +21.0 +29 +62 +36 +65 +21.0 +41 +9 +50 +12 +27.0 +67 +46 +69 +56 +20.0 +53 +48 +57 +53 +20.0 +29 +74 +38 +77 +27.0 +53 +71 +56 +78 +21.0 +10 +46 +18 +49 +24.0 +42 +63 +44 +73 +20.0 +39 +20 +48 +23 +27.0 +24 +42 +31 +45 +21.0 +63 +6 +64 +26 +20.0 +24 +46 +26 +56 +20.0 +50 +43 +55 +47 +20.0 +25 +10 +31 +14 +24.0 +64 +86 +70 +90 +24.0 +75 +39 +78 +46 +21.0 +65 +73 +72 +76 +21.0 +26 +68 +35 +71 +27.0 +44 +36 +48 +41 +20.0 +68 +61 +76 +64 +24.0 +21 +57 +25 +62 +20.0 +56 +54 +63 +57 +21.0 +47 +74 +50 +81 +21.0 +37 +28 +43 +32 +24.0 +81 +50 +82 +70 +20.0 +54 +29 +63 +32 +27.0 +70 +79 +75 +83 +20.0 +55 +12 +61 +16 +24.0 +46 +87 +54 +90 +24.0 +33 +29 +35 +39 +20.0 +31 +46 +40 +49 +27.0 +20 +77 +23 +84 +21.0 +93 +37 +97 +42 +20.0 +83 +61 +91 +64 +24.0 +53 +3 +60 +6 +21.0 +65 +37 +72 +40 +21.0 +54 +38 +60 +42 +24.0 +14 +73 +17 +80 +21.0 +7 +55 +12 +59 +20.0 +46 +25 +48 +35 +20.0 +35 +3 +37 +13 +20.0 +19 +32 +26 +35 +21.0 +80 +22 +84 +27 +20.0 +80 +78 +86 +82 +24.0 +64 +27 +68 +32 +20.0 +74 +55 +80 +59 +24.0 +57 +63 +59 +73 +20.0 +89 +53 +96 +56 +21.0 +80 +37 +82 +47 +20.0 +45 +65 +49 +70 +20.0 +45 +91 +49 +96 +20.0 +22 +86 +31 +89 +27.0 +57 +74 +60 +81 +21.0 +66 +19 +73 +22 +21.0 +37 +83 +42 +87 +20.0 +29 +50 +33 +55 +20.0 +10 +31 +13 +38 +21.0 +13 +57 +18 +61 +20.0 +86 +46 +91 +50 +20.0 +40 +74 +45 +78 +20.0 +86 +70 +90 +75 +20.0 +12 +26 +19 +29 +21.0 +28 +17 +35 +20 +21.0 +39 +50 +45 +54 +24.0 +2 +48 +8 +52 +24.0 +14 +39 +20 +43 +24.0 +39 +13 +46 +16 +21.0 +73 +49 +77 +54 +20.0 +30 +91 +39 +94 +27.0 +69 +31 +73 +36 +20.0 +66 +77 +69 +84 +21.0 +64 +53 +66 +63 +20.0 +18 +21 +24 +25 +24.0 +29 +78 +34 +82 +20.0 +76 +77 +79 +84 +21.0 +1 +40 +9 +43 +24.0 +51 +79 +56 +83 +20.0 +59 +33 +66 +36 +21.0 +50 +24 +56 +28 +24.0 +46 +60 +51 +64 +20.0 +38 +63 +41 +70 +21.0 +66 +41 +74 +44 +24.0 +62 +92 +66 +97 +20.0 +4 +67 +12 +70 +24.0 +81 +14 +86 +18 +20.0 +75 +85 +82 +88 +21.0 +8 +74 +13 +78 +20.0 +31 +21 +36 +25 +20.0 +14 +16 +19 +20 +20.0 +92 +60 +96 +65 +20.0 +53 +63 +56 +70 +21.0 +13 +68 +20 +71 +21.0 +9 +21 +15 +25 +24.0 +50 +33 +53 +40 +21.0 +43 +55 +48 +59 +20.0 +71 +84 +74 +91 +21.0 +62 +66 +68 +70 +24.0 +70 +67 +74 +72 +20.0 +78 +28 +82 +33 +20.0 +54 +59 +62 +62 +24.0 +21 +64 +23 +74 +20.0 +5 +60 +11 +64 +24.0 +86 +36 +89 +43 +21.0 +91 +28 +94 +35 +21.0 +75 +15 +79 +20 +20.0 +59 +48 +65 +52 +24.0 +3 +33 +8 +37 +20.0 +27 +56 +31 +61 +20.0 +86 +66 +94 +69 +24.0 +57 +86 +62 +90 +20.0 +45 +4 +50 +8 +20.0 +52 +7 +61 +10 +27.0 +70 +47 +72 +57 +20.0 +92 +44 +98 +48 +24.0 +61 +73 +63 +83 +20.0 +21 +36 +26 +40 +20.0 +0.12225246 +0.37408406 +0.06628969 +0.64457035 +0.23417756 +0.26215884 +0.7658226 +0.374084 +0.47668225 +0.5792806 +0.76582265 +0.961692 +0.8124583 +0.2994673 +0.47668222 +0.8870751 +0.084943935 +0.53264505 +0.93371063 +0.99900043 +0.47668222 +0.22485054 +0.3087944 +0.5606262 +0.24350454 +0.5979348 +0.93371063 +0.8031311 +0.99900043 +0.6165891 +0.6259161 +0.70986 +0.961692 +0.6259158 +0.29946718 +0.23417749 +0.99900043 +0.9803462 +0.374084 +0.08494389 +0.29946724 +0.95236486 +0.48600927 +0.7098599 +0.9150564 +0.47668222 +0.5886074 +0.42071956 +0.38341117 +0.34610268 +0.65389746 +0.89640224 +0.877748 +0.34610277 +0.15956078 +0.14090666 +0.54197186 +0.87774795 +0.12225238 +0.1968692 +0.5606262 +0.3367757 +0.99900043 +0.4113925 +0.40206534 +0.9243835 +0.7005328 +0.8217853 +0.2528317 +0.09427108 +0.15956095 +0.29946703 +0.93371063 +0.16888794 +0.45802802 +0.77514976 +0.112925306 +0.41139245 +0.028981315 +0.010327125 +0.11292531 +0.028981313 +0.5046636 +0.9150564 +0.99900043 +0.36475682 +0.4673551 +0.3367756 +0.81245816 +0.2155235 +0.12225255 +0.7285141 +0.03830839 +0.34610268 +0.6445701 +0.90572935 +0.46735507 +0.08494399 +0.9803462 +0.7005328 +0.028981308 +0.1502338 +0.55129915 +0.056962583 +0.26215878 +0.001 +0.21552338 +0.6818787 +0.38341117 +0.038308375 +0.6818787 +0.5046638 +0.7005328 +0.60726166 +0.81245816 +0.23417744 +0.3461027 +0.65389735 +0.06628969 +0.7098598 +0.32744846 +0.18754216 +0.6352431 +0.10359822 +0.94303775 +0.3367755 +0.7564956 +0.9150564 +0.89640224 +0.99900043 +0.2528317 +0.09427107 +0.635243 +0.5369992 +0.52984786 +0.54756886 +0.5422835 +0.43719596 +0.52363014 +0.47108513 +0.5279833 +0.4213391 +0.45305237 +0.41823047 +0.49129438 +0.4642455 +0.50652903 +0.53482056 +0.4664212 +0.4449682 +0.52300787 +0.5289151 +0.4384398 +0.45864865 +0.52207553 +0.4490107 +0.55969524 +0.48445427 +0.5267381 +0.5404183 +0.44869956 +0.5320225 +0.4654884 +0.566225 +0.45087644 +0.43128857 +0.42880148 +0.52425164 +0.5087055 +0.4176089 +0.54197407 +0.44652355 +0.46704352 +0.52798176 +0.4107687 +0.4654884 +0.42849013 +0.48010147 +0.47543806 +0.538551 +0.5115033 +0.53357875 +0.4390612 +0.41885254 +0.5000005 +0.45149782 +0.4567832 +0.5382421 +0.5540993 +0.5031086 +0.5453929 +0.55005723 +0.44590163 +0.43097773 +0.4483886 +0.42569262 +0.43470928 +0.41854125 +0.42165032 +0.46984157 +0.47699314 +0.5382414 +0.44901082 +0.44621223 +0.48974022 +0.5304696 +0.56062824 +0.5485018 +0.41854134 +0.49409282 +0.42786875 +0.5615612 +0.5506783 +0.50777215 +0.56124943 +0.5540982 +0.5357551 +0.43035617 +0.5099492 +0.4319103 +0.43159947 +0.42600358 +0.562494 +0.5174119 +0.43128875 +0.5609393 +0.45927057 +0.4493212 +0.49720109 +0.48134533 +0.4947147 +0.44963247 +0.45522898 +0.5397966 +0.4605139 +0.43097767 +0.53699964 +0.5435267 +0.5659129 +0.41885272 +0.44683474 +0.5335799 +0.55845106 +0.48258862 +0.4978235 +0.4340867 +0.4350199 +0.42817983 +0.4418594 +0.43999457 +0.52300787 +0.5500567 +0.43284288 +0.44621256 +0.45429567 +0.45243043 +0.55876267 +0.52829295 +0.41636503 +0.4542963 +0.5292259 +0.49720162 +0.4284908 +0.41667572 +0.4390618 +0.5429041 +107 +3210 diff --git a/Robust/src/Benchmarks/SSJava/EyeTracking/makefile b/Robust/src/Benchmarks/SSJava/EyeTracking/makefile new file mode 100644 index 00000000..353e7db1 --- /dev/null +++ b/Robust/src/Benchmarks/SSJava/EyeTracking/makefile @@ -0,0 +1,23 @@ +BUILDSCRIPT=../../../buildscript + +PROGRAM=LEA +SOURCE_FILES=LEA.java + +BSFLAGS= -32bit -ssjava -mainclass $(PROGRAM) -heapsize-mb 1000 -nooptimize -debug -garbagestats -ssjavadebug #-printlinenum #-joptimize + +default: $(PROGRAM)s.bin + +$(PROGRAM)s.bin: $(SOURCE_FILES) makefile + $(BUILDSCRIPT) $(BSFLAGS) -o $(PROGRAM) -builddir sing $(SOURCE_FILES) + +clean: + rm -f $(PROGRAM).bin + rm -fr sing + rm -f *~ + rm -f *.dot + rm -f *.png + rm -f *.txt + rm -f aliases.txt + rm -f results*txt + rm -f *log + -- 2.34.1