Commit 09dc49393895dc48a7fee6e3f6070af72b49f117

Authored by Josh Klontz
1 parent d953599d

FaceRecognition now uses MatchProbabilityDistance

CHANGELOG.md
1 -0.2.0 - ??/??/?? 1 +0.2.0 - 2/23/13
2 ================ 2 ================
  3 +* FaceRecognition new distance metric
  4 + - 0 to 1 range indicating match probability
3 * Qt 4.8 -> Qt 5.0 5 * Qt 4.8 -> Qt 5.0
4 * Cleaner plots generated with 'br -plot' 6 * Cleaner plots generated with 'br -plot'
5 * Stasm and FLandmark wrappers 7 * Stasm and FLandmark wrappers
app/examples/face_recognition.cpp
@@ -62,8 +62,9 @@ int main(int argc, char *argv[]) @@ -62,8 +62,9 @@ int main(int argc, char *argv[])
62 float comparisonA = distance->compare(target, queryA); 62 float comparisonA = distance->compare(target, queryA);
63 float comparisonB = distance->compare(target, queryB); 63 float comparisonB = distance->compare(target, queryB);
64 64
65 - printf("Genuine match score: %.3f\n", comparisonA); // Scores above 1 are strong matches  
66 - printf("Impostor match score: %.3f\n", comparisonB); // Scores below 0.5 are strong non-matches 65 + // Scores range from 0 to 1 and represent match probability
  66 + printf("Genuine match score: %.3f\n", comparisonA);
  67 + printf("Impostor match score: %.3f\n", comparisonB);
67 68
68 br::Context::finalize(); 69 br::Context::finalize();
69 return 0; 70 return 0;
sdk/plugins/algorithms.cpp
@@ -31,7 +31,7 @@ class AlgorithmsInitializer : public Initializer @@ -31,7 +31,7 @@ class AlgorithmsInitializer : public Initializer
31 void initialize() const 31 void initialize() const
32 { 32 {
33 // Face 33 // Face
34 - Globals->abbreviations.insert("FaceRecognition", "FaceDetection!<FaceRecognitionRegistration>!<FaceRecognitionExtraction>+<FaceRecognitionEmbedding>+<FaceRecognitionQuantization>:UCharL1"); 34 + Globals->abbreviations.insert("FaceRecognition", "FaceDetection!<FaceRecognitionRegistration>!<FaceRecognitionExtraction>+<FaceRecognitionEmbedding>+<FaceRecognitionQuantization>:MatchProbability(ByteL1)");
35 Globals->abbreviations.insert("FaceRecognitionNoTraining", "FaceDetection!ASEFEyes+Affine(86,86,0.25,0.35)!Blur(1.1)+Gamma(0.2)+DoG(1,2)+ContrastEq(0.1,10)+Mask+LBP(1,2)+RectRegions(8,8,6,6)+Hist(59)+Cat:ChiSquared"); 35 Globals->abbreviations.insert("FaceRecognitionNoTraining", "FaceDetection!ASEFEyes+Affine(86,86,0.25,0.35)!Blur(1.1)+Gamma(0.2)+DoG(1,2)+ContrastEq(0.1,10)+Mask+LBP(1,2)+RectRegions(8,8,6,6)+Hist(59)+Cat:ChiSquared");
36 Globals->abbreviations.insert("GenderClassification", "FaceDetection!<FaceClassificationRegistration>!<FaceClassificationExtraction>+<GenderClassifier>+Discard"); 36 Globals->abbreviations.insert("GenderClassification", "FaceDetection!<FaceClassificationRegistration>!<FaceClassificationExtraction>+<GenderClassifier>+Discard");
37 Globals->abbreviations.insert("AgeRegression", "FaceDetection!<FaceClassificationRegistration>!<FaceClassificationExtraction>+<AgeRegressor>+Discard"); 37 Globals->abbreviations.insert("AgeRegression", "FaceDetection!<FaceClassificationRegistration>!<FaceClassificationExtraction>+<AgeRegressor>+Discard");
sdk/plugins/format.cpp
@@ -222,7 +222,6 @@ class DefaultFormat : public Format @@ -222,7 +222,6 @@ class DefaultFormat : public Format
222 fileName = file.fileName(); 222 fileName = file.fileName();
223 if (!QFileInfo(fileName).exists()) { 223 if (!QFileInfo(fileName).exists()) {
224 fileName = file.getString("path") + "/" + file.fileName(); 224 fileName = file.getString("path") + "/" + file.fileName();
225 - qDebug() << fileName;  
226 if (!QFileInfo(fileName).exists()) return t; 225 if (!QFileInfo(fileName).exists()) return t;
227 } 226 }
228 } 227 }
sdk/plugins/quality.cpp
@@ -147,13 +147,11 @@ class MatchProbabilityDistance : public Distance @@ -147,13 +147,11 @@ class MatchProbabilityDistance : public Distance
147 { 147 {
148 Q_OBJECT 148 Q_OBJECT
149 Q_PROPERTY(br::Distance* distance READ get_distance WRITE set_distance RESET reset_distance STORED false) 149 Q_PROPERTY(br::Distance* distance READ get_distance WRITE set_distance RESET reset_distance STORED false)
150 - Q_PROPERTY(QString binKey READ get_binKey WRITE set_binKey RESET reset_binKey STORED false)  
151 Q_PROPERTY(bool gaussian READ get_gaussian WRITE set_gaussian RESET reset_gaussian STORED false) 150 Q_PROPERTY(bool gaussian READ get_gaussian WRITE set_gaussian RESET reset_gaussian STORED false)
152 BR_PROPERTY(br::Distance*, distance, make("Dist(L2)")) 151 BR_PROPERTY(br::Distance*, distance, make("Dist(L2)"))
153 - BR_PROPERTY(QString, binKey, "")  
154 BR_PROPERTY(bool, gaussian, true) 152 BR_PROPERTY(bool, gaussian, true)
155 153
156 - QHash<QString, MP> mps; 154 + MP mp;
157 155
158 void train(const TemplateList &src) 156 void train(const TemplateList &src)
159 { 157 {
@@ -163,37 +161,38 @@ class MatchProbabilityDistance : public Distance @@ -163,37 +161,38 @@ class MatchProbabilityDistance : public Distance
163 QScopedPointer<MatrixOutput> memoryOutput(dynamic_cast<MatrixOutput*>(Output::make(".Matrix", FileList(src.size()), FileList(src.size())))); 161 QScopedPointer<MatrixOutput> memoryOutput(dynamic_cast<MatrixOutput*>(Output::make(".Matrix", FileList(src.size()), FileList(src.size()))));
164 distance->compare(src, src, memoryOutput.data()); 162 distance->compare(src, src, memoryOutput.data());
165 163
166 - QHash< QString, QList<float> > genuineScores, impostorScores;  
167 - for (int i=0; i<src.size(); i++) 164 + QList<float> genuineScores, impostorScores;
  165 + genuineScores.reserve(labels.size());
  166 + impostorScores.reserve(labels.size()*labels.size());
  167 + for (int i=0; i<src.size(); i++) {
168 for (int j=0; j<i; j++) { 168 for (int j=0; j<i; j++) {
169 const float score = memoryOutput.data()->data.at<float>(i, j); 169 const float score = memoryOutput.data()->data.at<float>(i, j);
170 if (score == -std::numeric_limits<float>::max()) continue; 170 if (score == -std::numeric_limits<float>::max()) continue;
171 - const QString bin = src[i].file.getString(binKey, "");  
172 - if (labels[i] == labels[j]) genuineScores[bin].append(score);  
173 - else impostorScores[bin].append(score); 171 + if (labels[i] == labels[j]) genuineScores.append(score);
  172 + else impostorScores.append(score);
174 } 173 }
  174 + }
175 175
176 - foreach (const QString &key, genuineScores.keys())  
177 - mps.insert(key, MP(genuineScores[key], impostorScores[key])); 176 + mp = MP(genuineScores, impostorScores);
178 } 177 }
179 178
180 float compare(const Template &target, const Template &query) const 179 float compare(const Template &target, const Template &query) const
181 { 180 {
182 float rawScore = distance->compare(target, query); 181 float rawScore = distance->compare(target, query);
183 if (rawScore == -std::numeric_limits<float>::max()) return rawScore; 182 if (rawScore == -std::numeric_limits<float>::max()) return rawScore;
184 - return mps[query.file.getString(binKey, "")](rawScore, gaussian); 183 + return mp(rawScore, gaussian);
185 } 184 }
186 185
187 void store(QDataStream &stream) const 186 void store(QDataStream &stream) const
188 { 187 {
189 distance->store(stream); 188 distance->store(stream);
190 - stream << mps; 189 + stream << mp;
191 } 190 }
192 191
193 void load(QDataStream &stream) 192 void load(QDataStream &stream)
194 { 193 {
195 distance->load(stream); 194 distance->load(stream);
196 - stream >> mps; 195 + stream >> mp;
197 } 196 }
198 }; 197 };
199 198
1 -Subproject commit b560a337e5b47770234d4ab554c563b5043e3595 1 +Subproject commit 3ab0a438e4d93ead1a7db346d221bbb4ae81ccf1