9fa81d47bda3d71990cbe30cda1986b419a33c04
[IRC.git] / Robust / src / Benchmarks / SSJava / EyeTrackingInfer / 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
25 public class Classifier {
26
27   private ScanArea[] scanAreas;
28
29   private float[] possibilities_FaceYes;
30
31   private float[] possibilities_FaceNo;
32
33   private int possibilityFaceYes = 0;
34
35   private int possibilityFaceNo = 0;
36
37   public Classifier(int numScanAreas) {
38     this.scanAreas = new ScanArea[numScanAreas];
39     this.possibilities_FaceYes = new float[numScanAreas];
40     this.possibilities_FaceNo = new float[numScanAreas];
41   }
42
43   public void setScanArea(int idx, ScanArea area) {
44     scanAreas[idx] = area;
45   }
46
47   public void setPossibilitiesFaceYes(@DELEGATE float[] arr) {
48     this.possibilities_FaceYes = arr;
49   }
50
51   public void setPossibilityFaceYes(int v) {
52     this.possibilityFaceYes = v;
53   }
54
55   public void setPossibilitiesFaceNo(@DELEGATE float[] arr) {
56     this.possibilities_FaceNo = arr;
57   }
58
59   public void setPossibilityFaceNo(int v) {
60     this.possibilityFaceNo = v;
61   }
62
63   /**
64    * Classifies an images region as face
65    * 
66    * @param image
67    * @param scaleFactor
68    *          please be aware of the fact that the scanareas are scaled for use with 100x100 px
69    *          images
70    * @param translationX
71    * @param translationY
72    * @return true if this region was classified as face, else false
73    */
74
75   public boolean classifyFace(IntegralImageData image, float scaleFactor, int translationX, int translationY, float borderline) {
76
77     long[] values = new long[scanAreas.length];
78
79     float avg = 0f;
80     int avgItems = 0;
81     for (int i = 0; i < scanAreas.length; ++i) {
82       values[i] = 0l;
83
84       values[i] +=
85           image.getIntegralAt(translationX + scanAreas[i].getToX(scaleFactor), translationY
86               + scanAreas[i].getToY(scaleFactor));
87       values[i] +=
88           image.getIntegralAt(translationX + scanAreas[i].getFromX(scaleFactor), translationY
89               + scanAreas[i].getFromY(scaleFactor));
90
91       values[i] -=
92           image.getIntegralAt(translationX + scanAreas[i].getToX(scaleFactor), translationY
93               + scanAreas[i].getFromY(scaleFactor));
94       values[i] -=
95           image.getIntegralAt(translationX + scanAreas[i].getFromX(scaleFactor), translationY
96               + scanAreas[i].getToY(scaleFactor));
97
98       values[i] = (long) (values[i] / ((float) scanAreas[i].getSize(scaleFactor)));
99       avg = ((avgItems * avg) + values[i]) / (++avgItems);
100     }
101     // System.out.println("avg=" + avg);
102
103     // int amountYesNo = this.possibilityFaceNo + this.possibilityFaceYes;
104
105     // calculate the possibilites for face=yes and face=no with naive bayes
106     // P(Yes | M1 and ... and Mn) = P(Yes) * P(M1 | Yes) * ... * P(Mn | Yes) /xx
107     // P(No | M1 and ... and Mn) = P(No) * P(M1 | No) * ... * P(Mn | No) / xx
108     // as we just maximize the args we don't actually calculate the accurate
109     // possibility
110
111     float isFaceYes = 1.0f;// this.possibilityFaceYes /
112                            // (float)amountYesNo;
113     float isFaceNo = 1.0f;// this.possibilityFaceNo /
114                           // (float)amountYesNo;
115
116     for (int i = 0; i < this.scanAreas.length; ++i) {
117       boolean bright = (values[i] >= avg);
118       isFaceYes *= (bright ? this.possibilities_FaceYes[i] : 1 - this.possibilities_FaceYes[i]);
119       isFaceNo *= (bright ? this.possibilities_FaceNo[i] : 1 - this.possibilities_FaceNo[i]);
120     }
121     // System.out.println("avg=" + avg + " yes=" + isFaceYes + " no=" +
122     // isFaceNo);
123
124     return (isFaceYes >= isFaceNo && (isFaceYes / (isFaceYes + isFaceNo)) > borderline);
125   }
126
127   public ScanArea[] getScanAreas() {
128     return this.scanAreas;
129   }
130
131   public int getLearnedFacesYes() {
132     return this.possibilityFaceYes;
133   }
134
135   public int getLearnedFacesNo() {
136     return this.possibilityFaceNo;
137   }
138
139   public float getPossibility(int scanAreaID, boolean faceYes, boolean bright) {
140     if (faceYes) {
141       return (bright ? this.possibilities_FaceYes[scanAreaID]
142           : 1 - this.possibilities_FaceYes[scanAreaID]);
143     } else {
144       return (bright ? this.possibilities_FaceNo[scanAreaID]
145           : 1 - this.possibilities_FaceNo[scanAreaID]);
146     }
147   }
148
149   public int compareTo(Classifier o) {
150     if (o.getScanAreas().length > this.getScanAreas().length) {
151       return -1;
152     } else if (o.getScanAreas().length < this.getScanAreas().length) {
153       return 1;
154     } else
155       return 0;
156   }
157
158   public String toString() {
159
160     String str = "";
161     for (int i = 0; i < scanAreas.length; i++) {
162       str += scanAreas[i].toString() + "\n";
163     }
164
165     return str;
166
167   }
168
169 }