From 1b27e45e87f380b97519ac3d5b8087293dcaea6d Mon Sep 17 00:00:00 2001 From: Keyur Patel Date: Mon, 24 Oct 2016 09:47:06 -0600 Subject: [PATCH] Added evaluation code for liveness --- app/br/br.cpp | 3 +++ openbr/core/eval.cpp | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ openbr/core/eval.h | 2 +- openbr/openbr.cpp | 5 +++++ openbr/openbr.h | 2 ++ 5 files changed, 75 insertions(+), 1 deletion(-) diff --git a/app/br/br.cpp b/app/br/br.cpp index 949b277..ceffa16 100644 --- a/app/br/br.cpp +++ b/app/br/br.cpp @@ -171,6 +171,9 @@ public: } else if (!strcmp(fun, "evalKNN")) { check(parc >= 2 && parc <= 3, "Incorrect parameter count for 'evalKNN'."); br_eval_knn(parv[0], parv[1], parc > 2 ? parv[2] : ""); + } else if (!strcmp(fun, "evalLiveness")) { + check(parc >=1 && parc <=3 , "Incorrect parameter count for 'evalLiveness'."); + br_eval_Liveness(parv[0], parc > 1 ? parv[1] : "", parc > 2 ? parv[2] : ""); } else if (!strcmp(fun, "pairwiseCompare")) { check((parc >= 2) && (parc <= 3), "Incorrect parameter count for 'pairwiseCompare'."); br_pairwise_compare(parv[0], parv[1], parc == 3 ? parv[2] : ""); diff --git a/openbr/core/eval.cpp b/openbr/core/eval.cpp index 4cfcd5c..f26d3ec 100755 --- a/openbr/core/eval.cpp +++ b/openbr/core/eval.cpp @@ -1168,4 +1168,68 @@ void EvalKNN(const QString &knnGraph, const QString &knnTruth, const QString &cs qDebug("FNIR @ FPIR = 0.01: %.3f", 1-getOperatingPointGivenFAR(operatingPoints, 0.01).TAR); } +void EvalLiveness(const QString &predictedXML, QString gt_property, QString distribution_property){ + if (gt_property.isEmpty()) + gt_property = "LivenessGT"; + if (distribution_property.isEmpty()) + distribution_property = "LivenessDistribution"; + int genuineTemplateCount = 0; + const TemplateList templateList(TemplateList::fromGallery(predictedXML)); + + QHash gtLabels; + QHash > scores; + for (int i=0; i(gt_property); + if (gtLabel == 1) + genuineTemplateCount++; + QList templateScores = templateList[i].file.getList(distribution_property); + gtLabels[templateKey] = gtLabel; + scores[templateKey] = templateScores; + } + + const int numPoints = 200; + const float stepSize = 100.0/numPoints; + const int numTemplates = scores.size(); + float thres = 0.0; //Between [0,100] + float thresNorm = 0.0; //Between [0,1] + int FA = 0, FR = 0; + float minDiff = 100; + float EER = 100; + float EERThres = 0; + + for(int i = 0; i <= numPoints; i++){ + FA = 0, FR = 0; + thresNorm = thres/100.0; + foreach(const QString &key, scores.keys()){ + int gtLabel = gtLabels[key]; + //> thresNorm = class 0 (spoof) : < thresNorm = class 1 (genuine) + if (scores[key][0] >= thresNorm && gtLabel == 0) + continue; + else if (scores[key][0] < thresNorm && gtLabel == 1) + continue; + else if (scores[key][0] >= thresNorm && gtLabel == 1) + FR +=1; + else if (scores[key][0] < thresNorm && gtLabel == 0) + FA +=1; + } + float FAR = FA / float(numTemplates - genuineTemplateCount); + float FRR = FR / float(genuineTemplateCount); + + float diff = std::abs(FAR-FRR); + if (diff < minDiff){ + minDiff = diff; + EER = (FAR+FRR)/2.0; + EERThres = thresNorm; + } + thres += stepSize; + } + + qDebug() <<"Genuine Templates:" << genuineTemplateCount << "Spoof Templates:" + << numTemplates - genuineTemplateCount << "Total Templates:" << numTemplates; + qDebug("EER: %.3f @ Threshold %.3f", EER*100, EERThres); + +} + + } // namespace br diff --git a/openbr/core/eval.h b/openbr/core/eval.h index 0edfd25..a4f117a 100644 --- a/openbr/core/eval.h +++ b/openbr/core/eval.h @@ -34,7 +34,7 @@ namespace br 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 void EvalRegression(const QString &predictedGallery, const QString &truthGallery, QString predictedProperty = "", QString truthProperty = ""); void EvalKNN(const QString &knnGraph, const QString &knnTruth, const QString &csv = ""); - + void EvalLiveness(const QString &predictedXML, const QString gt_property = "", const QString distribution_property = ""); struct Candidate { size_t index; diff --git a/openbr/openbr.cpp b/openbr/openbr.cpp index 97155ec..7a5dfdc 100644 --- a/openbr/openbr.cpp +++ b/openbr/openbr.cpp @@ -150,6 +150,11 @@ void br_eval_knn(const char *knnGraph, const char *knnTruth, const char *csv) EvalKNN(knnGraph, knnTruth, csv); } +void br_eval_Liveness(const char *predicted_xml, const char *gt_property, const char *distribution_property ) +{ + EvalLiveness(predicted_xml, gt_property, distribution_property); +} + void br_finalize() { Context::finalize(); diff --git a/openbr/openbr.h b/openbr/openbr.h index 12a769a..a002703 100644 --- a/openbr/openbr.h +++ b/openbr/openbr.h @@ -66,6 +66,8 @@ BR_EXPORT void br_eval_regression(const char *predicted_gallery, const char *tru BR_EXPORT void br_eval_knn(const char *knnGraph, const char *knnTruth, const char *csv = ""); +BR_EXPORT void br_eval_Liveness(const char *predicted_xml, const char *gt_property = "", const char *distribution_property = ""); + BR_EXPORT void br_finalize(); BR_EXPORT void br_fuse(int num_input_simmats, const char *input_simmats[], -- libgit2 0.21.4