#ifndef EVALUTILS_EVALUTILS_H #define EVALUTILS_EVALUTILS_H #include struct Detection { QRectF boundingBox; QString filePath; float confidence; // The ignore flag is useful when certain faces in an image should be ignored // and should not effect detection performance. Predicted detections that overlap // with an ignored truth detection will not count as a true positive, false positive, // true negative, or false negative, it will simply be ignored. bool ignore; Detection() {} Detection(const QRectF &boundingBox_, const QString &filePath = QString(), float confidence_ = -1, bool ignore_ = false) : boundingBox(boundingBox_), filePath(filePath), confidence(confidence_), ignore(ignore_) {} float area() const { return boundingBox.width() * boundingBox.height(); } float overlap(const Detection &other) const { const Detection intersection(boundingBox.intersected(other.boundingBox)); return intersection.area() / (area() + other.area() - intersection.area()); } }; struct SortedDetection { int truth_idx, predicted_idx; float overlap; SortedDetection() : truth_idx(-1), predicted_idx(-1), overlap(-1) {} SortedDetection(int truth_idx_, int predicted_idx_, float overlap_) : truth_idx(truth_idx_), predicted_idx(predicted_idx_), overlap(overlap_) {} inline bool operator<(const SortedDetection &other) const { return overlap > other.overlap; } }; struct ResolvedDetection { QString filePath; QRectF boundingBox; float confidence, overlap; ResolvedDetection() : confidence(-1), overlap(-1) {} ResolvedDetection(const QString &filePath, const QRectF &boundingBox, float confidence_, float overlap_) : filePath(filePath), boundingBox(boundingBox), confidence(confidence_), overlap(overlap_) {} inline bool operator<(const ResolvedDetection &other) const { return confidence > other.confidence; } }; struct Detections { QList predicted, truth; }; struct DetectionKey : public QString { enum Type { Invalid, Rect, RectList, XYWidthHeight } type; DetectionKey(const QString &key = "", Type type = Invalid) : QString(key), type(type) {} }; struct DetectionOperatingPoint { float Recall, FalsePositiveRate, Precision, Confidence; DetectionOperatingPoint() : Recall(-1), FalsePositiveRate(-1), Precision(-1) {} DetectionOperatingPoint(float TP, float FP, float totalPositives, float numImages, float confidence) : Recall(TP/totalPositives), FalsePositiveRate(FP/numImages), Precision(TP/(TP+FP)), Confidence(confidence) {} }; namespace EvalUtils { // Detection DetectionKey getDetectKey(const br::FileList &files); QList getDetections(const DetectionKey &key, const br::File &f, bool isTruth); QMap getDetections(const br::File &predictedGallery, const br::File &truthGallery); QMap filterDetections(const QMap &allDetections, int threshold, bool useMin=true); int associateGroundTruthDetections(QList &resolved, QList &falseNegative, QMap &all, QRectF &offsets); QStringList computeDetectionResults(const QList &detections, int totalTrueDetections, int numImages, bool discrete, QList &points); inline int getNumberOfImages(const QMap detections) { return detections.keys().size(); } } QDebug operator<<(QDebug dbg, const ResolvedDetection &d); #endif // EVALUTILS_EVALUTILS_H