Commit f9c9e2d1c2d07fffcfc37dce2c6b39d811ba6539
1 parent
eecc7b41
unbroke face recognition
Showing
3 changed files
with
66 additions
and
4 deletions
sdk/plugins/algorithms.cpp
| ... | ... | @@ -70,6 +70,7 @@ class AlgorithmsInitializer : public Initializer |
| 70 | 70 | Globals->abbreviations.insert("FaceClassificationExtraction", "((Grid(7,7)+SIFTDescriptor(8)+ByRow)/DenseLBP+PCA(0.95,instances=-1)+Cat)"); |
| 71 | 71 | Globals->abbreviations.insert("AgeRegressor", "Center(Range,instances=-1)+SVM(RBF,EPS_SVR,instances=100)"); |
| 72 | 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 | 119 | * \brief Fast 8-bit L1 distance |
| 120 | 120 | * \author Josh Klontz \cite jklontz |
| 121 | 121 | */ |
| 122 | -class UCharL1Distance : public Distance | |
| 122 | +class ByteL1Distance : public Distance | |
| 123 | 123 | { |
| 124 | 124 | Q_OBJECT |
| 125 | 125 | |
| ... | ... | @@ -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 | 137 | * \brief Fast 4-bit L1 distance |
| 138 | 138 | * \author Josh Klontz \cite jklontz |
| 139 | 139 | */ |
| 140 | -class PackedUCharL1Distance : public Distance | |
| 140 | +class HalfByteL1Distance : public Distance | |
| 141 | 141 | { |
| 142 | 142 | Q_OBJECT |
| 143 | 143 | |
| ... | ... | @@ -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 | 153 | * \ingroup distances | ... | ... |
sdk/plugins/quality.cpp
| ... | ... | @@ -201,6 +201,67 @@ class MPDistance : public Distance |
| 201 | 201 | |
| 202 | 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 | 265 | } // namespace br |
| 205 | 266 | |
| 206 | 267 | #include "quality.moc" | ... | ... |