Commit 09dc49393895dc48a7fee6e3f6070af72b49f117
1 parent
d953599d
FaceRecognition now uses MatchProbabilityDistance
Showing
6 changed files
with
20 additions
and
19 deletions
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 |