evalutils.h
3.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#ifndef EVALUTILS_EVALUTILS_H
#define EVALUTILS_EVALUTILS_H
#include <openbr/openbr_plugin.h>
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<Detection> 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<Detection> getDetections(const DetectionKey &key, const br::File &f, bool isTruth);
QMap<QString, Detections> getDetections(const br::File &predictedGallery, const br::File &truthGallery);
QMap<QString, Detections> filterDetections(const QMap<QString, Detections> &allDetections, int threshold, bool useMin=true);
int associateGroundTruthDetections(QList<ResolvedDetection> &resolved, QList<ResolvedDetection> &falseNegative, QMap<QString, Detections> &all, QRectF &offsets);
QStringList computeDetectionResults(const QList<ResolvedDetection> &detections, int totalTrueDetections, int numImages, bool discrete, QList<DetectionOperatingPoint> &points);
inline int getNumberOfImages(const QMap<QString, Detections> detections)
{
return detections.keys().size();
}
}
QDebug operator<<(QDebug dbg, const ResolvedDetection &d);
#endif // EVALUTILS_EVALUTILS_H