Commit 1b27e45e87f380b97519ac3d5b8087293dcaea6d

Authored by Keyur Patel
1 parent 686c452f

Added evaluation code for liveness

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 &amp;knnGraph, const QString &amp;knnTruth, const QString &amp;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[],
... ...