Commit f9c9e2d1c2d07fffcfc37dce2c6b39d811ba6539

Authored by Josh Klontz
1 parent eecc7b41

unbroke face recognition

sdk/plugins/algorithms.cpp
@@ -70,6 +70,7 @@ class AlgorithmsInitializer : public Initializer @@ -70,6 +70,7 @@ class AlgorithmsInitializer : public Initializer
70 Globals->abbreviations.insert("FaceClassificationExtraction", "((Grid(7,7)+SIFTDescriptor(8)+ByRow)/DenseLBP+PCA(0.95,instances=-1)+Cat)"); 70 Globals->abbreviations.insert("FaceClassificationExtraction", "((Grid(7,7)+SIFTDescriptor(8)+ByRow)/DenseLBP+PCA(0.95,instances=-1)+Cat)");
71 Globals->abbreviations.insert("AgeRegressor", "Center(Range,instances=-1)+SVM(RBF,EPS_SVR,instances=100)"); 71 Globals->abbreviations.insert("AgeRegressor", "Center(Range,instances=-1)+SVM(RBF,EPS_SVR,instances=100)");
72 Globals->abbreviations.insert("GenderClassifier", "Center(Range,instances=-1)+SVM(RBF,C_SVC,instances=4000)"); 72 Globals->abbreviations.insert("GenderClassifier", "Center(Range,instances=-1)+SVM(RBF,C_SVC,instances=4000)");
  73 + Globals->abbreviations.insert("UCharL1", "Unit(ByteL1)");
73 } 74 }
74 }; 75 };
75 76
sdk/plugins/compare.cpp
@@ -119,7 +119,7 @@ BR_REGISTER(Distance, DistDistance) @@ -119,7 +119,7 @@ BR_REGISTER(Distance, DistDistance)
119 * \brief Fast 8-bit L1 distance 119 * \brief Fast 8-bit L1 distance
120 * \author Josh Klontz \cite jklontz 120 * \author Josh Klontz \cite jklontz
121 */ 121 */
122 -class UCharL1Distance : public Distance 122 +class ByteL1Distance : public Distance
123 { 123 {
124 Q_OBJECT 124 Q_OBJECT
125 125
@@ -129,7 +129,7 @@ class UCharL1Distance : public Distance @@ -129,7 +129,7 @@ class UCharL1Distance : public Distance
129 } 129 }
130 }; 130 };
131 131
132 -BR_REGISTER(Distance, UCharL1Distance) 132 +BR_REGISTER(Distance, ByteL1Distance)
133 133
134 134
135 /*! 135 /*!
@@ -137,7 +137,7 @@ BR_REGISTER(Distance, UCharL1Distance) @@ -137,7 +137,7 @@ BR_REGISTER(Distance, UCharL1Distance)
137 * \brief Fast 4-bit L1 distance 137 * \brief Fast 4-bit L1 distance
138 * \author Josh Klontz \cite jklontz 138 * \author Josh Klontz \cite jklontz
139 */ 139 */
140 -class PackedUCharL1Distance : public Distance 140 +class HalfByteL1Distance : public Distance
141 { 141 {
142 Q_OBJECT 142 Q_OBJECT
143 143
@@ -147,7 +147,7 @@ class PackedUCharL1Distance : public Distance @@ -147,7 +147,7 @@ class PackedUCharL1Distance : public Distance
147 } 147 }
148 }; 148 };
149 149
150 -BR_REGISTER(Distance, PackedUCharL1Distance) 150 +BR_REGISTER(Distance, HalfByteL1Distance)
151 151
152 /*! 152 /*!
153 * \ingroup distances 153 * \ingroup distances
sdk/plugins/quality.cpp
@@ -201,6 +201,67 @@ class MPDistance : public Distance @@ -201,6 +201,67 @@ class MPDistance : public Distance
201 201
202 BR_REGISTER(Distance, MPDistance) 202 BR_REGISTER(Distance, MPDistance)
203 203
  204 +/*!
  205 + * \ingroup distances
  206 + * \brief Linear normalizes of a distance so the mean impostor score is 0 and the mean genuine score is 1.
  207 + * \author Josh Klontz \cite jklontz
  208 + */
  209 +class UnitDistance : public Distance
  210 +{
  211 + Q_OBJECT
  212 + Q_PROPERTY(br::Distance *distance READ get_distance WRITE set_distance RESET reset_distance)
  213 + Q_PROPERTY(float a READ get_a WRITE set_a RESET reset_a)
  214 + Q_PROPERTY(float b READ get_b WRITE set_b RESET reset_b)
  215 + BR_PROPERTY(br::Distance*, distance, make("Dist(L2)"))
  216 + BR_PROPERTY(float, a, 1)
  217 + BR_PROPERTY(float, b, 0)
  218 +
  219 + void train(const TemplateList &templates)
  220 + {
  221 + const TemplateList samples = templates.mid(0, 2000);
  222 + const QList<float> sampleLabels = samples.labels<float>();
  223 + QScopedPointer<MatrixOutput> memoryOutput(dynamic_cast<MatrixOutput*>(Output::make(".Matrix", FileList(samples.size()), FileList(samples.size()))));
  224 + compare(samples, samples, memoryOutput.data());
  225 +
  226 + double genuineAccumulator, impostorAccumulator;
  227 + int genuineCount, impostorCount;
  228 + genuineAccumulator = impostorAccumulator = genuineCount = impostorCount = 0;
  229 +
  230 + for (int i=0; i<samples.size(); i++) {
  231 + for (int j=0; j<i; j++) {
  232 + const float val = memoryOutput.data()->data.at<float>(i, j);
  233 + if (sampleLabels[i] == sampleLabels[j]) {
  234 + genuineAccumulator += val;
  235 + genuineCount++;
  236 + } else {
  237 + impostorAccumulator += val;
  238 + impostorCount++;
  239 + }
  240 + }
  241 + }
  242 +
  243 + if (genuineCount == 0) { qWarning("No genuine matches."); return; }
  244 + if (impostorCount == 0) { qWarning("No impostor matches."); return; }
  245 +
  246 + double genuineMean = genuineAccumulator / genuineCount;
  247 + double impostorMean = impostorAccumulator / impostorCount;
  248 +
  249 + if (genuineMean == impostorMean) { qWarning("Genuines and impostors are indistinguishable."); return; }
  250 +
  251 + a = 1.0/(genuineMean-impostorMean);
  252 + b = impostorMean;
  253 +
  254 + qDebug("a = %f, b = %f", a, b);
  255 + }
  256 +
  257 + float _compare(const Template &target, const Template &query) const
  258 + {
  259 + return a * (distance->compare(target, query) - b);
  260 + }
  261 +};
  262 +
  263 +BR_REGISTER(Distance, UnitDistance)
  264 +
204 } // namespace br 265 } // namespace br
205 266
206 #include "quality.moc" 267 #include "quality.moc"