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 | 46 | // return a list of detections independent of the detection key format |
| 47 | 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 | 53 | const QString filePath = f.path() + "/" + f.fileName(); |
| 50 | 54 | QList<Detection> dets; |
| 51 | 55 | if (key.type == DetectionKey::RectList) { |
| ... | ... | @@ -60,10 +64,10 @@ QList<Detection> EvalUtils::getDetections(const DetectionKey &key, const File &f |
| 60 | 64 | dets.append(Detection(rects[i], filePath, confidences[i])); |
| 61 | 65 | } |
| 62 | 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 | 68 | } else if (key.type == DetectionKey::XYWidthHeight) { |
| 65 | 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 | 72 | return dets; |
| 69 | 73 | } |
| ... | ... | @@ -228,13 +232,11 @@ QStringList EvalUtils::computeDetectionResults(const QList<ResolvedDetection> &d |
| 228 | 232 | QDebug debug = qDebug(); |
| 229 | 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 | 240 | int detectionsToKeep = 50; |
| 239 | 241 | QList<ResolvedDetection> topFalsePositives, bottomTruePositives; |
| 240 | 242 | for (int i=0; i<detections.size(); i++) { |
| ... | ... | @@ -246,24 +248,25 @@ QStringList EvalUtils::computeDetectionResults(const QList<ResolvedDetection> &d |
| 246 | 248 | if (detection.poseMatch) |
| 247 | 249 | poseMatch++; |
| 248 | 250 | } |
| 249 | - else FP++; | |
| 251 | + else | |
| 252 | + FP++; | |
| 250 | 253 | } else { |
| 251 | 254 | TP += detection.overlap; |
| 255 | + if (detection.poseMatch) | |
| 256 | + poseMatch += detection.overlap; | |
| 252 | 257 | FP += 1 - detection.overlap; |
| 253 | 258 | } |
| 254 | 259 | if ((i == detections.size()-1) || (detection.confidence > detections[i+1].confidence)) { |
| 255 | 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 | 271 | if (detection.overlap < 0.5 && topFalsePositives.size() < detectionsToKeep) |
| 269 | 272 | topFalsePositives.append(detection); |
| ... | ... | @@ -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 | 290 | if (Globals->verbose) { |
| 292 | 291 | QtUtils::touchDir(QDir("./falsePos")); |
| 293 | 292 | qDebug("Highest Scoring False Positives:"); |
| 294 | 293 | detectionsToKeep = std::min(detectionsToKeep,topFalsePositives.size()); |
| 295 | 294 | for (int i=0; i<detectionsToKeep; i++) { |
| 296 | 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 | 300 | imwrite(qPrintable(QString("./falsePos/falsePos%1.jpg").arg(QString::number(i))), img); |
| 302 | 301 | } |
| 303 | 302 | qDebug("Lowest Scoring True Positives:"); |
| ... | ... | @@ -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 | 311 | const int keep = qMin(points.size(), Max_Points); |
| 309 | 312 | if (keep < 1) qFatal("Insufficient points."); |
| 310 | 313 | ... | ... |