Commit 89b9823b24a1fd933aeb8c2e3f16024eeb07ba85

Authored by Josh Klontz
1 parent 8b418541

generalized -evalDetection

Showing 1 changed file with 64 additions and 42 deletions
openbr/core/eval.cpp
... ... @@ -427,84 +427,106 @@ static QStringList computeDetectionResults(const QList<ResolvedDetection> &detec
427 427 return lines;
428 428 }
429 429  
430   -QString getDetectKey(const TemplateList &templates)
  430 +struct DetectionKey : public QString
431 431 {
432   - const File &f = templates.first().file;
433   - foreach (const QString &key, f.localKeys()) {
434   - // first check for single detections
  432 + enum Type {
  433 + Invalid,
  434 + Rect,
  435 + RectList,
  436 + XYWidthHeight
  437 + } type;
  438 +
  439 + DetectionKey(const QString &key = "", Type type = Invalid)
  440 + : QString(key), type(type) {}
  441 +};
  442 +
  443 +static DetectionKey getDetectKey(const FileList &files)
  444 +{
  445 + if (files.empty())
  446 + return DetectionKey();
  447 +
  448 + const File &f = files.first();
  449 + const QStringList localKeys = f.localKeys();
  450 +
  451 + // first check for single detections
  452 + foreach (const QString &key, localKeys)
435 453 if (!f.get<QRectF>(key, QRectF()).isNull())
436   - return key;
437   - }
  454 + return DetectionKey(key, DetectionKey::Rect);
  455 +
438 456 // and then multiple
439 457 if (!f.rects().empty())
440   - return "Rects";
441   - return "";
442   -}
  458 + return DetectionKey("Rects", DetectionKey::RectList);
443 459  
444   -bool detectKeyIsList(QString key, const TemplateList &templates)
445   -{
446   - return templates.first().file.get<QRectF>(key, QRectF()).isNull();
  460 + // check for <Key>_X, <Key>_Y, <Key>_Width, <Key>_Height
  461 + foreach (const QString &localKey, localKeys) {
  462 + if (!localKey.endsWith("_X"))
  463 + continue;
  464 + const QString key = localKey.mid(0, localKey.size()-2);
  465 + if (localKeys.contains(key+"_Y") &&
  466 + localKeys.contains(key+"_Width") &&
  467 + localKeys.contains(key+"_Height"))
  468 + return DetectionKey(key, DetectionKey::XYWidthHeight);
  469 + }
  470 +
  471 + return DetectionKey();
447 472 }
448 473  
449   -// return a list of detections whether the template holds
450   -// multiple detections or a single detection
451   -QList<Detection> getDetections(QString key, const Template &t, bool isList, bool isTruth)
  474 +// return a list of detections independent of the detection key format
  475 +static QList<Detection> getDetections(const DetectionKey &key, const File &f, bool isTruth)
452 476 {
453   - File f = t.file;
454 477 QList<Detection> dets;
455   - if (isList) {
  478 + if (key.type == DetectionKey::RectList) {
456 479 QList<QRectF> rects = f.rects();
457 480 QList<float> confidences = f.getList<float>("Confidences", QList<float>());
458 481 if (!isTruth && rects.size() != confidences.size())
459 482 qFatal("You don't have enough confidence. I mean, your detections don't all have confidence measures.");
460 483 for (int i=0; i<rects.size(); i++) {
461 484 if (isTruth)
462   - dets.append(Detection(rects.at(i)));
  485 + dets.append(Detection(rects[i]));
463 486 else
464   - dets.append(Detection(rects.at(i), confidences.at(i)));
  487 + dets.append(Detection(rects[i], confidences[i]));
465 488 }
466   - } else {
467   - if (isTruth)
468   - dets.append(Detection(f.get<QRectF>(key)));
469   - else
470   - dets.append(Detection(f.get<QRectF>(key), f.get<float>("Confidence", -1)));
  489 + } else if (key.type == DetectionKey::Rect) {
  490 + dets.append(Detection(f.get<QRectF>(key), isTruth ? -1 : f.get<float>("Confidence", -1)));
  491 + } else if (key.type == DetectionKey::XYWidthHeight) {
  492 + const QRectF rect(f.get<float>(key+"_X"), f.get<float>(key+"_Y"), f.get<float>(key+"_Width"), f.get<float>(key+"_Height"));
  493 + dets.append(Detection(rect, isTruth ? -1 : f.get<float>("Confidence", -1)));
471 494 }
472 495 return dets;
473 496 }
474 497  
475   -QMap<QString, Detections> getDetections(const TemplateList &predicted, const TemplateList &truth)
  498 +static QMap<QString, Detections> getDetections(const File &predictedGallery, const File &truthGallery)
476 499 {
  500 + const FileList predicted = TemplateList::fromGallery(predictedGallery).files();
  501 + const FileList truth = TemplateList::fromGallery(truthGallery).files();
  502 +
477 503 // Figure out which metadata field contains a bounding box
478   - QString truthDetectKey = getDetectKey(truth);
479   - if (truthDetectKey.isEmpty()) qFatal("No suitable ground truth metadata key found.");
480   - QString predictedDetectKey = getDetectKey(predicted);
481   - if (predictedDetectKey.isEmpty()) qFatal("No suitable predicted metadata key found.");
  504 + DetectionKey truthDetectKey = getDetectKey(truth);
  505 + if (truthDetectKey.isEmpty())
  506 + qFatal("No suitable ground truth metadata key found.");
  507 +
  508 + DetectionKey predictedDetectKey = getDetectKey(predicted);
  509 + if (predictedDetectKey.isEmpty())
  510 + qFatal("No suitable predicted metadata key found.");
  511 +
482 512 qDebug("Using metadata key: %s%s",
483 513 qPrintable(predictedDetectKey),
484 514 qPrintable(predictedDetectKey == truthDetectKey ? QString() : "/"+truthDetectKey));
485 515  
486 516 QMap<QString, Detections> allDetections;
487   - bool predKeyIsList = detectKeyIsList(predictedDetectKey, predicted);
488   - bool truthKeyIsList = detectKeyIsList(truthDetectKey, truth);
489   - foreach (const Template &t, predicted) {
490   - QList<Detection> dets = getDetections(predictedDetectKey, t, predKeyIsList, false);
491   - allDetections[t.file.baseName()].predicted.append(dets);
492   - }
493   - foreach (const Template &t, truth) {
494   - QList<Detection> dets = getDetections(truthDetectKey, t, truthKeyIsList, true);
495   - allDetections[t.file.baseName()].truth.append(dets);
496   - }
  517 + foreach (const File &f, predicted)
  518 + allDetections[f.baseName()].predicted.append(getDetections(predictedDetectKey, f, false));
  519 + foreach (const File &f, truth)
  520 + allDetections[f.baseName()].truth.append(getDetections(truthDetectKey, f, true));
497 521 return allDetections;
498 522 }
499 523  
500 524 float EvalDetection(const QString &predictedGallery, const QString &truthGallery, const QString &csv)
501 525 {
502 526 qDebug("Evaluating detection of %s against %s", qPrintable(predictedGallery), qPrintable(truthGallery));
503   - const TemplateList predicted(TemplateList::fromGallery(predictedGallery));
504   - const TemplateList truth(TemplateList::fromGallery(truthGallery));
505 527  
506 528 // Organized by file, QMap used to preserve order
507   - QMap<QString, Detections> allDetections = getDetections(predicted, truth);
  529 + QMap<QString, Detections> allDetections = getDetections(predictedGallery, truthGallery);
508 530  
509 531 QList<ResolvedDetection> resolvedDetections, falseNegativeDetections;
510 532 int totalTrueDetections = 0;
... ...