Commit 2834229bd88a407735e392fda46c6fda64db472c
Merge branch 'master' into csv
Showing
1 changed file
with
33 additions
and
30 deletions
openbr/core/evalutils.cpp
| @@ -46,6 +46,10 @@ DetectionKey EvalUtils::getDetectKey(const FileList &files) | @@ -46,6 +46,10 @@ DetectionKey EvalUtils::getDetectKey(const FileList &files) | ||
| 46 | // return a list of detections independent of the detection key format | 46 | // return a list of detections independent of the detection key format |
| 47 | QList<Detection> EvalUtils::getDetections(const DetectionKey &key, const File &f, bool isTruth) | 47 | QList<Detection> EvalUtils::getDetections(const DetectionKey &key, const File &f, bool isTruth) |
| 48 | { | 48 | { |
| 49 | + QString pose = f.get<QString>("Pose"); | ||
| 50 | + if (pose.contains("Angle")) | ||
| 51 | + pose = "Frontal"; | ||
| 52 | + | ||
| 49 | const QString filePath = f.path() + "/" + f.fileName(); | 53 | const QString filePath = f.path() + "/" + f.fileName(); |
| 50 | QList<Detection> dets; | 54 | QList<Detection> dets; |
| 51 | if (key.type == DetectionKey::RectList) { | 55 | if (key.type == DetectionKey::RectList) { |
| @@ -60,10 +64,10 @@ QList<Detection> EvalUtils::getDetections(const DetectionKey &key, const File &f | @@ -60,10 +64,10 @@ QList<Detection> EvalUtils::getDetections(const DetectionKey &key, const File &f | ||
| 60 | dets.append(Detection(rects[i], filePath, confidences[i])); | 64 | dets.append(Detection(rects[i], filePath, confidences[i])); |
| 61 | } | 65 | } |
| 62 | } else if (key.type == DetectionKey::Rect) { | 66 | } else if (key.type == DetectionKey::Rect) { |
| 63 | - dets.append(Detection(f.get<QRectF>(key), filePath, isTruth ? -1 : f.get<float>("Confidence", -1), f.get<bool>("Ignore", false), f.get<QString>("Pose", "Frontal"))); | 67 | + dets.append(Detection(f.get<QRectF>(key), filePath, isTruth ? -1 : f.get<float>("Confidence", -1), f.get<bool>("Ignore", false), pose)); |
| 64 | } else if (key.type == DetectionKey::XYWidthHeight) { | 68 | } else if (key.type == DetectionKey::XYWidthHeight) { |
| 65 | const QRectF rect(f.get<float>(key+"_X"), f.get<float>(key+"_Y"), f.get<float>(key+"_Width"), f.get<float>(key+"_Height")); | 69 | const QRectF rect(f.get<float>(key+"_X"), f.get<float>(key+"_Y"), f.get<float>(key+"_Width"), f.get<float>(key+"_Height")); |
| 66 | - dets.append(Detection(rect, filePath, isTruth ? -1 : f.get<float>("Confidence", -1), f.get<bool>("Ignore", false), f.get<QString>("Pose", "Frontal"))); | 70 | + dets.append(Detection(rect, filePath, isTruth ? -1 : f.get<float>("Confidence", -1), f.get<bool>("Ignore", false), pose)); |
| 67 | } | 71 | } |
| 68 | return dets; | 72 | return dets; |
| 69 | } | 73 | } |
| @@ -228,13 +232,11 @@ QStringList EvalUtils::computeDetectionResults(const QList<ResolvedDetection> &d | @@ -228,13 +232,11 @@ QStringList EvalUtils::computeDetectionResults(const QList<ResolvedDetection> &d | ||
| 228 | QDebug debug = qDebug(); | 232 | QDebug debug = qDebug(); |
| 229 | debug.noquote(); | 233 | debug.noquote(); |
| 230 | 234 | ||
| 231 | - if (discrete) { | ||
| 232 | - debug << endl << QString("+")+QString("-").repeated(12)+QString("+")+QString("-").repeated(12)+QString("+")+QString("-").repeated(12)+QString("+")+QString("-").repeated(12)+QString("+") << endl; | ||
| 233 | - debug << QString("|") << QString("FAR").leftJustified(10, ' ') << QString("|") << QString("TAR").leftJustified(10, ' ') << QString("|") << QString("Confidence").leftJustified(10, ' ') << QString("|") << QString("Pose Match").leftJustified(10, ' ') << QString("|") << endl; | ||
| 234 | - debug << QString("+")+QString("-").repeated(12)+QString("+")+QString("-").repeated(12)+QString("+")+QString("-").repeated(12)+QString("+")+QString("-").repeated(12)+QString("+") << endl; | ||
| 235 | - } | 235 | + debug << endl << QString("+")+QString("-").repeated(12)+QString("+")+QString("-").repeated(12)+QString("+")+QString("-").repeated(12)+QString("+")+QString("-").repeated(12)+QString("+") << endl; |
| 236 | + debug << QString("|") << QString("FAR").leftJustified(10, ' ') << QString("|") << QString("TAR").leftJustified(10, ' ') << QString("|") << QString("Confidence").leftJustified(10, ' ') << QString("|") << QString("Pose Match").leftJustified(10, ' ') << QString("|") << endl; | ||
| 237 | + debug << QString("+")+QString("-").repeated(12)+QString("+")+QString("-").repeated(12)+QString("+")+QString("-").repeated(12)+QString("+")+QString("-").repeated(12)+QString("+") << endl; | ||
| 236 | 238 | ||
| 237 | - int poseMatch = 0; | 239 | + float poseMatch = 0; |
| 238 | int detectionsToKeep = 50; | 240 | int detectionsToKeep = 50; |
| 239 | QList<ResolvedDetection> topFalsePositives, bottomTruePositives; | 241 | QList<ResolvedDetection> topFalsePositives, bottomTruePositives; |
| 240 | for (int i=0; i<detections.size(); i++) { | 242 | for (int i=0; i<detections.size(); i++) { |
| @@ -246,24 +248,25 @@ QStringList EvalUtils::computeDetectionResults(const QList<ResolvedDetection> &d | @@ -246,24 +248,25 @@ QStringList EvalUtils::computeDetectionResults(const QList<ResolvedDetection> &d | ||
| 246 | if (detection.poseMatch) | 248 | if (detection.poseMatch) |
| 247 | poseMatch++; | 249 | poseMatch++; |
| 248 | } | 250 | } |
| 249 | - else FP++; | 251 | + else |
| 252 | + FP++; | ||
| 250 | } else { | 253 | } else { |
| 251 | TP += detection.overlap; | 254 | TP += detection.overlap; |
| 255 | + if (detection.poseMatch) | ||
| 256 | + poseMatch += detection.overlap; | ||
| 252 | FP += 1 - detection.overlap; | 257 | FP += 1 - detection.overlap; |
| 253 | } | 258 | } |
| 254 | if ((i == detections.size()-1) || (detection.confidence > detections[i+1].confidence)) { | 259 | if ((i == detections.size()-1) || (detection.confidence > detections[i+1].confidence)) { |
| 255 | if (FP > prevFP || (i == detections.size()-1)) { | 260 | if (FP > prevFP || (i == detections.size()-1)) { |
| 256 | - if (discrete) { | ||
| 257 | - foreach (float FAR, FARsToOutput) | ||
| 258 | - if (prevFP / numImages < FAR && FP / numImages >= FAR) { | ||
| 259 | - debug << QString("|") << QString::number(FAR, 'f', 4).leftJustified(10, ' '); | ||
| 260 | - debug << QString("|") << QString::number(TP / totalTrueDetections, 'f', 4).leftJustified(10, ' '); | ||
| 261 | - debug << QString("|") << QString::number(detection.confidence, 'f', 4).leftJustified(10, ' '); | ||
| 262 | - debug << QString("|") << QString::number(poseMatch / TP, 'f', 4).leftJustified(10, ' '); | ||
| 263 | - debug << QString("|") << endl; | ||
| 264 | - break; | ||
| 265 | - } | ||
| 266 | - } | 261 | + foreach (float FAR, FARsToOutput) |
| 262 | + if (prevFP / numImages < FAR && FP / numImages >= FAR) { | ||
| 263 | + debug << QString("|") << QString::number(FAR, 'f', 4).leftJustified(10, ' '); | ||
| 264 | + debug << QString("|") << QString::number(TP / totalTrueDetections, 'f', 4).leftJustified(10, ' '); | ||
| 265 | + debug << QString("|") << QString::number(detection.confidence, 'f', 4).leftJustified(10, ' '); | ||
| 266 | + debug << QString("|") << QString::number(poseMatch / TP, 'f', 4).leftJustified(10, ' '); | ||
| 267 | + debug << QString("|") << endl; | ||
| 268 | + break; | ||
| 269 | + } | ||
| 267 | 270 | ||
| 268 | if (detection.overlap < 0.5 && topFalsePositives.size() < detectionsToKeep) | 271 | if (detection.overlap < 0.5 && topFalsePositives.size() < detectionsToKeep) |
| 269 | topFalsePositives.append(detection); | 272 | topFalsePositives.append(detection); |
| @@ -281,23 +284,19 @@ QStringList EvalUtils::computeDetectionResults(const QList<ResolvedDetection> &d | @@ -281,23 +284,19 @@ QStringList EvalUtils::computeDetectionResults(const QList<ResolvedDetection> &d | ||
| 281 | } | 284 | } |
| 282 | } | 285 | } |
| 283 | 286 | ||
| 284 | - if (discrete) { | ||
| 285 | - debug << QString("+")+QString("-").repeated(12)+QString("+")+QString("-").repeated(12)+QString("+")+QString("-").repeated(12)+QString("+")+QString("-").repeated(12)+QString("+") << endl; | ||
| 286 | - | ||
| 287 | - debug << endl << QString("Total TP vs. FP:").leftJustified(25, ' ') << QString("%1 vs. %2").arg(QString::number((int)TP)).arg(QString::number((int)FP)) << endl; | ||
| 288 | - debug << QString("Total TP vs. possible TP:") << QString("%1 vs. %2").arg(QString::number((int)TP)).arg(QString::number(totalTrueDetections)) << endl; | ||
| 289 | - debug << QString("Pose matches:").leftJustified(25, ' ') << QString::number(poseMatch); | 287 | + debug << QString("+")+QString("-").repeated(12)+QString("+")+QString("-").repeated(12)+QString("+")+QString("-").repeated(12)+QString("+")+QString("-").repeated(12)+QString("+") << endl; |
| 290 | 288 | ||
| 289 | + if (discrete) { | ||
| 291 | if (Globals->verbose) { | 290 | if (Globals->verbose) { |
| 292 | QtUtils::touchDir(QDir("./falsePos")); | 291 | QtUtils::touchDir(QDir("./falsePos")); |
| 293 | qDebug("Highest Scoring False Positives:"); | 292 | qDebug("Highest Scoring False Positives:"); |
| 294 | detectionsToKeep = std::min(detectionsToKeep,topFalsePositives.size()); | 293 | detectionsToKeep = std::min(detectionsToKeep,topFalsePositives.size()); |
| 295 | for (int i=0; i<detectionsToKeep; i++) { | 294 | for (int i=0; i<detectionsToKeep; i++) { |
| 296 | Mat img = imread(qPrintable(Globals->path + "/" + topFalsePositives[i].filePath)); | 295 | Mat img = imread(qPrintable(Globals->path + "/" + topFalsePositives[i].filePath)); |
| 297 | - qDebug() << topFalsePositives[i]; | ||
| 298 | - const Scalar color(0,255,0); | ||
| 299 | - rectangle(img, OpenCVUtils::toRect(topFalsePositives[i].boundingBox), Scalar(0,0,255), 1); | ||
| 300 | - rectangle(img, OpenCVUtils::toRect(topFalsePositives[i].groundTruthBoundingBox), Scalar(0,255,0), 1); | 296 | + const Rect falseRect = OpenCVUtils::toRect(topFalsePositives[i].boundingBox); |
| 297 | + rectangle(img, falseRect, Scalar(0, 0, 255), 1); | ||
| 298 | + rectangle(img, OpenCVUtils::toRect(topFalsePositives[i].groundTruthBoundingBox), Scalar(0, 255, 0), 1); | ||
| 299 | + putText(img, qPrintable("Overlap:"+QString::number(topFalsePositives[i].overlap)), falseRect.tl(), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 0, 255), 1); | ||
| 301 | imwrite(qPrintable(QString("./falsePos/falsePos%1.jpg").arg(QString::number(i))), img); | 300 | imwrite(qPrintable(QString("./falsePos/falsePos%1.jpg").arg(QString::number(i))), img); |
| 302 | } | 301 | } |
| 303 | qDebug("Lowest Scoring True Positives:"); | 302 | qDebug("Lowest Scoring True Positives:"); |
| @@ -305,6 +304,10 @@ QStringList EvalUtils::computeDetectionResults(const QList<ResolvedDetection> &d | @@ -305,6 +304,10 @@ QStringList EvalUtils::computeDetectionResults(const QList<ResolvedDetection> &d | ||
| 305 | } | 304 | } |
| 306 | } | 305 | } |
| 307 | 306 | ||
| 307 | + debug << QString("Minimum %1 Precision:").arg(discrete ? "Discrete" : "Continuous").leftJustified(32, ' ') << QString("%1").arg(QString::number(points.last().Precision)) << endl; | ||
| 308 | + debug << QString("Maximum %1 Recall:").arg(discrete ? "Discrete" : "Continuous").leftJustified(32, ' ') << QString("%1").arg(QString::number(points.last().Recall)) << endl; | ||
| 309 | + debug << QString("%1 F1 Score:").arg(discrete ? "Discrete" : "Continuous").leftJustified(32, ' ') << QString("%1").arg(QString::number(2 * (points.last().Recall * points.last().Precision) / (points.last().Recall + points.last().Precision))) << endl; | ||
| 310 | + | ||
| 308 | const int keep = qMin(points.size(), Max_Points); | 311 | const int keep = qMin(points.size(), Max_Points); |
| 309 | if (keep < 1) qFatal("Insufficient points."); | 312 | if (keep < 1) qFatal("Insufficient points."); |
| 310 | 313 |