4f5f8f34263914d8e3242e4f6ade0b45d6f8a7b6
[IRC.git] / Robust / src / Benchmarks / SSJava / EyeTracking / Classifier.java
1 /*
2  * Copyright 2009 (c) Florian Frankenberger (darkblue.de)
3  * 
4  * This file is part of LEA.
5  * 
6  * LEA is free software: you can redistribute it and/or modify it under the
7  * terms of the GNU Lesser General Public License as published by the Free
8  * Software Foundation, either version 3 of the License, or (at your option) any
9  * later version.
10  * 
11  * LEA is distributed in the hope that it will be useful, but WITHOUT ANY
12  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
14  * details.
15  * 
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with LEA. If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 /**
21  * 
22  * @author Florian
23  */
24 @LATTICE("V")
25 @METHODDEFAULT("OUT<V,V<THIS,THIS<C,C<IN,C*,V*,THISLOC=THIS,RETURNLOC=OUT")
26 public class Classifier {
27
28   @LOC("V")
29   private ScanArea[] scanAreas;
30
31   @LOC("V")
32   private float[] possibilities_FaceYes;
33   @LOC("V")
34   private float[] possibilities_FaceNo;
35   @LOC("V")
36   private int possibilityFaceYes = 0;
37   @LOC("V")
38   private int possibilityFaceNo = 0;
39
40   public Classifier(int numScanAreas) {
41     this.scanAreas = new ScanArea[numScanAreas];
42     this.possibilities_FaceYes = new float[numScanAreas];
43     this.possibilities_FaceNo = new float[numScanAreas];
44   }
45
46   public void setScanArea(int idx, ScanArea area) {
47     scanAreas[idx] = area;
48   }
49
50   public void setPossibilitiesFaceYes(@DELEGATE float[] arr) {
51     this.possibilities_FaceYes = arr;
52   }
53
54   public void setPossibilityFaceYes(int v) {
55     this.possibilityFaceYes = v;
56   }
57
58   public void setPossibilitiesFaceNo(@DELEGATE float[] arr) {
59     this.possibilities_FaceNo = arr;
60   }
61
62   public void setPossibilityFaceNo(int v) {
63     this.possibilityFaceNo = v;
64   }
65
66   /**
67    * Classifies an images region as face
68    * 
69    * @param image
70    * @param scaleFactor
71    *          please be aware of the fact that the scanareas are scaled for use
72    *          with 100x100 px images
73    * @param translationX
74    * @param translationY
75    * @return true if this region was classified as face, else false
76    */
77   public boolean classifyFace(@LOC("IN") IntegralImageData image, @LOC("IN") float scaleFactor,
78       @LOC("IN") int translationX, @LOC("IN") int translationY, @LOC("IN") float borderline) {
79
80     @LOC("V") long values[] = new long[this.scanAreas.length];
81
82     @LOC("V") float avg = 0f;
83     @LOC("V") int avgItems = 0;
84     for (@LOC("C") int i = 0; i < this.scanAreas.length; ++i) {
85       values[i] = 0l;
86
87       values[i] +=
88           image.getIntegralAt(translationX + scanAreas[i].getToX(scaleFactor), translationY
89               + scanAreas[i].getToY(scaleFactor));
90       values[i] +=
91           image.getIntegralAt(translationX + scanAreas[i].getFromX(scaleFactor), translationY
92               + scanAreas[i].getFromY(scaleFactor));
93
94       values[i] -=
95           image.getIntegralAt(translationX + scanAreas[i].getToX(scaleFactor), translationY
96               + scanAreas[i].getFromY(scaleFactor));
97       values[i] -=
98           image.getIntegralAt(translationX + scanAreas[i].getFromX(scaleFactor), translationY
99               + scanAreas[i].getToY(scaleFactor));
100
101       values[i] = (long) (values[i] / ((float) scanAreas[i].getSize(scaleFactor)));
102       avg = ((avgItems * avg) + values[i]) / (++avgItems);
103     }
104     // System.out.println("avg=" + avg);
105
106     // int amountYesNo = this.possibilityFaceNo + this.possibilityFaceYes;
107
108     // calculate the possibilites for face=yes and face=no with naive bayes
109     // P(Yes | M1 and ... and Mn) = P(Yes) * P(M1 | Yes) * ... * P(Mn | Yes) /xx
110     // P(No | M1 and ... and Mn) = P(No) * P(M1 | No) * ... * P(Mn | No) / xx
111     // as we just maximize the args we don't actually calculate the accurate
112     // possibility
113
114     @LOC("OUT") float isFaceYes = 1.0f;// this.possibilityFaceYes /
115                                        // (float)amountYesNo;
116     @LOC("OUT") float isFaceNo = 1.0f;// this.possibilityFaceNo /
117                                       // (float)amountYesNo;
118
119     for (@LOC("C") int i = 0; i < this.scanAreas.length; ++i) {
120       @LOC("V") boolean bright = (values[i] >= avg);
121       isFaceYes *= (bright ? this.possibilities_FaceYes[i] : 1 - this.possibilities_FaceYes[i]);
122       isFaceNo *= (bright ? this.possibilities_FaceNo[i] : 1 - this.possibilities_FaceNo[i]);
123     }
124     // System.out.println("avg=" + avg + " yes=" + isFaceYes + " no=" +
125     // isFaceNo);
126
127     return (isFaceYes >= isFaceNo && (isFaceYes / (isFaceYes + isFaceNo)) > borderline);
128   }
129
130   public ScanArea[] getScanAreas() {
131     return this.scanAreas;
132   }
133
134   public int getLearnedFacesYes() {
135     return this.possibilityFaceYes;
136   }
137
138   public int getLearnedFacesNo() {
139     return this.possibilityFaceNo;
140   }
141
142   public float getPossibility(int scanAreaID, boolean faceYes, boolean bright) {
143     if (faceYes) {
144       return (bright ? this.possibilities_FaceYes[scanAreaID]
145           : 1 - this.possibilities_FaceYes[scanAreaID]);
146     } else {
147       return (bright ? this.possibilities_FaceNo[scanAreaID]
148           : 1 - this.possibilities_FaceNo[scanAreaID]);
149     }
150   }
151
152   public int compareTo(Classifier o) {
153     if (o.getScanAreas().length > this.getScanAreas().length) {
154       return -1;
155     } else if (o.getScanAreas().length < this.getScanAreas().length) {
156       return 1;
157     } else
158       return 0;
159   }
160
161   public String toString() {
162
163     @LOC("OUT") String str = "";
164     for (@LOC("C") int i = 0; i < scanAreas.length; i++) {
165       str += scanAreas[i].toString() + "\n";
166     }
167
168     return str;
169
170   }
171
172 }