Commit 1b27e45e87f380b97519ac3d5b8087293dcaea6d
1 parent
686c452f
Added evaluation code for liveness
Showing
5 changed files
with
75 additions
and
1 deletions
app/br/br.cpp
| ... | ... | @@ -171,6 +171,9 @@ public: |
| 171 | 171 | } else if (!strcmp(fun, "evalKNN")) { |
| 172 | 172 | check(parc >= 2 && parc <= 3, "Incorrect parameter count for 'evalKNN'."); |
| 173 | 173 | br_eval_knn(parv[0], parv[1], parc > 2 ? parv[2] : ""); |
| 174 | + } else if (!strcmp(fun, "evalLiveness")) { | |
| 175 | + check(parc >=1 && parc <=3 , "Incorrect parameter count for 'evalLiveness'."); | |
| 176 | + br_eval_Liveness(parv[0], parc > 1 ? parv[1] : "", parc > 2 ? parv[2] : ""); | |
| 174 | 177 | } else if (!strcmp(fun, "pairwiseCompare")) { |
| 175 | 178 | check((parc >= 2) && (parc <= 3), "Incorrect parameter count for 'pairwiseCompare'."); |
| 176 | 179 | br_pairwise_compare(parv[0], parv[1], parc == 3 ? parv[2] : ""); | ... | ... |
openbr/core/eval.cpp
| ... | ... | @@ -1168,4 +1168,68 @@ void EvalKNN(const QString &knnGraph, const QString &knnTruth, const QString &cs |
| 1168 | 1168 | qDebug("FNIR @ FPIR = 0.01: %.3f", 1-getOperatingPointGivenFAR(operatingPoints, 0.01).TAR); |
| 1169 | 1169 | } |
| 1170 | 1170 | |
| 1171 | +void EvalLiveness(const QString &predictedXML, QString gt_property, QString distribution_property){ | |
| 1172 | + if (gt_property.isEmpty()) | |
| 1173 | + gt_property = "LivenessGT"; | |
| 1174 | + if (distribution_property.isEmpty()) | |
| 1175 | + distribution_property = "LivenessDistribution"; | |
| 1176 | + int genuineTemplateCount = 0; | |
| 1177 | + const TemplateList templateList(TemplateList::fromGallery(predictedXML)); | |
| 1178 | + | |
| 1179 | + QHash<QString, int> gtLabels; | |
| 1180 | + QHash<QString, QList<float> > scores; | |
| 1181 | + for (int i=0; i<templateList.size(); i++) { | |
| 1182 | + QString templateKey = templateList[i].file.path() + templateList[i].file.baseName(); | |
| 1183 | + int gtLabel = templateList[i].file.get<int>(gt_property); | |
| 1184 | + if (gtLabel == 1) | |
| 1185 | + genuineTemplateCount++; | |
| 1186 | + QList<float> templateScores = templateList[i].file.getList<float>(distribution_property); | |
| 1187 | + gtLabels[templateKey] = gtLabel; | |
| 1188 | + scores[templateKey] = templateScores; | |
| 1189 | + } | |
| 1190 | + | |
| 1191 | + const int numPoints = 200; | |
| 1192 | + const float stepSize = 100.0/numPoints; | |
| 1193 | + const int numTemplates = scores.size(); | |
| 1194 | + float thres = 0.0; //Between [0,100] | |
| 1195 | + float thresNorm = 0.0; //Between [0,1] | |
| 1196 | + int FA = 0, FR = 0; | |
| 1197 | + float minDiff = 100; | |
| 1198 | + float EER = 100; | |
| 1199 | + float EERThres = 0; | |
| 1200 | + | |
| 1201 | + for(int i = 0; i <= numPoints; i++){ | |
| 1202 | + FA = 0, FR = 0; | |
| 1203 | + thresNorm = thres/100.0; | |
| 1204 | + foreach(const QString &key, scores.keys()){ | |
| 1205 | + int gtLabel = gtLabels[key]; | |
| 1206 | + //> thresNorm = class 0 (spoof) : < thresNorm = class 1 (genuine) | |
| 1207 | + if (scores[key][0] >= thresNorm && gtLabel == 0) | |
| 1208 | + continue; | |
| 1209 | + else if (scores[key][0] < thresNorm && gtLabel == 1) | |
| 1210 | + continue; | |
| 1211 | + else if (scores[key][0] >= thresNorm && gtLabel == 1) | |
| 1212 | + FR +=1; | |
| 1213 | + else if (scores[key][0] < thresNorm && gtLabel == 0) | |
| 1214 | + FA +=1; | |
| 1215 | + } | |
| 1216 | + float FAR = FA / float(numTemplates - genuineTemplateCount); | |
| 1217 | + float FRR = FR / float(genuineTemplateCount); | |
| 1218 | + | |
| 1219 | + float diff = std::abs(FAR-FRR); | |
| 1220 | + if (diff < minDiff){ | |
| 1221 | + minDiff = diff; | |
| 1222 | + EER = (FAR+FRR)/2.0; | |
| 1223 | + EERThres = thresNorm; | |
| 1224 | + } | |
| 1225 | + thres += stepSize; | |
| 1226 | + } | |
| 1227 | + | |
| 1228 | + qDebug() <<"Genuine Templates:" << genuineTemplateCount << "Spoof Templates:" | |
| 1229 | + << numTemplates - genuineTemplateCount << "Total Templates:" << numTemplates; | |
| 1230 | + qDebug("EER: %.3f @ Threshold %.3f", EER*100, EERThres); | |
| 1231 | + | |
| 1232 | +} | |
| 1233 | + | |
| 1234 | + | |
| 1171 | 1235 | } // namespace br | ... | ... |
openbr/core/eval.h
| ... | ... | @@ -34,7 +34,7 @@ namespace br |
| 34 | 34 | float EvalLandmarking(const QString &predictedGallery, const QString &truthGallery, const QString &csv = "", int normalizationIndexA = 0, int normalizationIndexB = 1, int sampleIndex = 0, int totalExamples = 5); // Return average error |
| 35 | 35 | void EvalRegression(const QString &predictedGallery, const QString &truthGallery, QString predictedProperty = "", QString truthProperty = ""); |
| 36 | 36 | void EvalKNN(const QString &knnGraph, const QString &knnTruth, const QString &csv = ""); |
| 37 | - | |
| 37 | + void EvalLiveness(const QString &predictedXML, const QString gt_property = "", const QString distribution_property = ""); | |
| 38 | 38 | struct Candidate |
| 39 | 39 | { |
| 40 | 40 | size_t index; | ... | ... |
openbr/openbr.cpp
| ... | ... | @@ -150,6 +150,11 @@ void br_eval_knn(const char *knnGraph, const char *knnTruth, const char *csv) |
| 150 | 150 | EvalKNN(knnGraph, knnTruth, csv); |
| 151 | 151 | } |
| 152 | 152 | |
| 153 | +void br_eval_Liveness(const char *predicted_xml, const char *gt_property, const char *distribution_property ) | |
| 154 | +{ | |
| 155 | + EvalLiveness(predicted_xml, gt_property, distribution_property); | |
| 156 | +} | |
| 157 | + | |
| 153 | 158 | void br_finalize() |
| 154 | 159 | { |
| 155 | 160 | Context::finalize(); | ... | ... |
openbr/openbr.h
| ... | ... | @@ -66,6 +66,8 @@ BR_EXPORT void br_eval_regression(const char *predicted_gallery, const char *tru |
| 66 | 66 | |
| 67 | 67 | BR_EXPORT void br_eval_knn(const char *knnGraph, const char *knnTruth, const char *csv = ""); |
| 68 | 68 | |
| 69 | +BR_EXPORT void br_eval_Liveness(const char *predicted_xml, const char *gt_property = "", const char *distribution_property = ""); | |
| 70 | + | |
| 69 | 71 | BR_EXPORT void br_finalize(); |
| 70 | 72 | |
| 71 | 73 | BR_EXPORT void br_fuse(int num_input_simmats, const char *input_simmats[], | ... | ... |