diff --git a/CMakeLists.txt b/CMakeLists.txt index 52069c6..2b1995a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,10 +19,15 @@ set(PACKAGE_YEAR 2013) if(${CMAKE_VERSION} VERSION_EQUAL 2.8.11) cmake_policy(SET CMP0020 OLD) - cmake_policy(SET CMP0022 OLD) endif() if(${CMAKE_VERSION} VERSION_GREATER 2.8.11) cmake_policy(SET CMP0020 OLD) +endif() + +if(${CMAKE_VERSION} VERSION_EQUAL 2.8.12) + cmake_policy(SET CMP0022 OLD) +endif() +if(${CMAKE_VERSION} VERSION_GREATER 2.8.12) cmake_policy(SET CMP0022 OLD) endif() diff --git a/openbr/core/eval.cpp b/openbr/core/eval.cpp index 15246cc..d83f8f5 100644 --- a/openbr/core/eval.cpp +++ b/openbr/core/eval.cpp @@ -394,6 +394,7 @@ static QStringList computeDetectionResults(const QList &detec for (int i=0; i= 0.5) TP++; else FP++; } else { @@ -507,11 +508,13 @@ float EvalDetection(const QString &predictedGallery, const QString &truthGallery QMap allDetections = getDetections(predicted, truth); QList resolvedDetections, falseNegativeDetections; - foreach (Detections detections, allDetections.values()) { + foreach (Detections detections, allDetections.values()) { // For every file + // Try to associate ground truth detections with predicted detections while (!detections.truth.isEmpty() && !detections.predicted.isEmpty()) { - const Detection truth = detections.truth.takeFirst(); + const Detection truth = detections.truth.takeFirst(); // Take removes the detection int bestIndex = -1; float bestOverlap = -std::numeric_limits::max(); + // Find the nearest predicted detection to this ground truth detection for (int i=0; i bestOverlap) { @@ -519,6 +522,9 @@ float EvalDetection(const QString &predictedGallery, const QString &truthGallery bestIndex = i; } } + // Removing the detection prevents us from considering it twice. + // We don't want to associate two ground truth detections with the + // same prediction, over vice versa. const Detection predicted = detections.predicted.takeAt(bestIndex); resolvedDetections.append(ResolvedDetection(predicted.confidence, bestOverlap)); } diff --git a/openbr/plugins/landmarks.cpp b/openbr/plugins/landmarks.cpp index 7885408..1cb4445 100644 --- a/openbr/plugins/landmarks.cpp +++ b/openbr/plugins/landmarks.cpp @@ -386,7 +386,7 @@ class NamePointsTransform : public UntrainableMetaTransform for (int i=0; i filtered; + foreach (Template t, src) { + if (!t.file.contains(attributeName)) + continue; + bool pass = t.file.get(attributeName) > threshold; + if (isGreaterThan ? pass : !pass) + filtered.append(t); + } + dst = TemplateList(filtered); + } + + void project(const Template &src, Template &dst) const + { + (void) src; (void) dst; qFatal("shouldn't be here"); + } +}; + +BR_REGISTER(Transform, FilterOnMetadataTransform) + } // namespace br #include "meta.moc" diff --git a/openbr/plugins/slidingwindow.cpp b/openbr/plugins/slidingwindow.cpp index 8d38226..d801be8 100644 --- a/openbr/plugins/slidingwindow.cpp +++ b/openbr/plugins/slidingwindow.cpp @@ -164,6 +164,7 @@ static TemplateList cropTrainingSamples(const TemplateList &data, const float as continue; result += Template(tmpl.file, Mat(tmpl, posRect)); + result.last().file.set("Label", QString("pos")); // Add random negative samples Mat m = tmpl.m(); diff --git a/openbr/plugins/stasm4.cpp b/openbr/plugins/stasm4.cpp index 20e39dd..10aaef1 100644 --- a/openbr/plugins/stasm4.cpp +++ b/openbr/plugins/stasm4.cpp @@ -85,7 +85,7 @@ class StasmTransform : public UntrainableTransform // Two use cases are accounted for: // 1. Pin eyes without normalization: in this case the string list should contain the KEYS for right then left eyes, respectively. // 2. Pin eyes with normalization: in this case the string list should contain the COORDINATES of the right then left eyes, respectively. - // Note that for case 2, if Affine_0 and Affine_1 are not present (indicating no normalization has taken place), we default to stasm_search_single. + // If both cases fail, we default to stasm_search_single. bool ok = false; QPointF rightEye; @@ -97,8 +97,12 @@ class StasmTransform : public UntrainableTransform } if (!ok) { - rightEye = QtUtils::toPoint(src.file.get(pinEyes.at(0), QString()),&ok); - leftEye = QtUtils::toPoint(src.file.get(pinEyes.at(1), QString()),&ok); + if (src.file.contains(pinEyes.at(0)) && src.file.contains(pinEyes.at(1))) + { + rightEye = src.file.get(pinEyes.at(0), QPointF()); + leftEye = src.file.get(pinEyes.at(1), QPointF()); + ok = true; + } } float eyes[2 * stasm_NLANDMARKS]; diff --git a/openbr/plugins/stream.cpp b/openbr/plugins/stream.cpp index 43673d1..440ab1c 100644 --- a/openbr/plugins/stream.cpp +++ b/openbr/plugins/stream.cpp @@ -477,13 +477,17 @@ public: if (frameNumber == final_frame) { // We just received the last frame, better pulse allReturned = true; - lastReturned.wakeAll(); rval = true; } return rval; } + void wake() + { + lastReturned.wakeAll(); + } + bool waitLast() { QMutexLocker lock(&last_frame_update); @@ -627,9 +631,9 @@ public: } virtual ~ProcessingStage() {} - virtual FrameData* run(FrameData * input, bool & should_continue)=0; + virtual FrameData* run(FrameData * input, bool & should_continue, bool & final)=0; - virtual bool tryAcquireNextStage(FrameData *& input)=0; + virtual bool tryAcquireNextStage(FrameData *& input, bool & final)=0; int stage_id; @@ -648,23 +652,6 @@ protected: }; -void BasicLoop::run() -{ - int current_idx = start_idx; - FrameData * target_item = startItem; - bool should_continue = true; - forever - { - target_item = stages->at(current_idx)->run(target_item, should_continue); - if (!should_continue) { - break; - } - current_idx++; - current_idx = current_idx % stages->size(); - } - this->reportFinished(); -} - class MultiThreadStage : public ProcessingStage { public: @@ -672,7 +659,7 @@ public: // Not much to worry about here, we will project the input // and try to continue to the next stage. - FrameData * run(FrameData * input, bool & should_continue) + FrameData * run(FrameData * input, bool & should_continue, bool & final) { if (input == NULL) { qFatal("null input to multi-thread stage"); @@ -680,16 +667,17 @@ public: input->data >> *transform; - should_continue = nextStage->tryAcquireNextStage(input); + should_continue = nextStage->tryAcquireNextStage(input, final); return input; } // Called from a different thread than run. Nothing to worry about // we offer no restrictions on when loops may enter this stage. - virtual bool tryAcquireNextStage(FrameData *& input) + virtual bool tryAcquireNextStage(FrameData *& input, bool & final) { (void) input; + final = false; return true; } @@ -744,7 +732,7 @@ public: QReadWriteLock statusLock; Status currentStatus; - FrameData * run(FrameData * input, bool & should_continue) + FrameData * run(FrameData * input, bool & should_continue, bool & final) { if (input == NULL) qFatal("NULL input to stage %d", this->stage_id); @@ -758,7 +746,10 @@ public: // Project the input we got transform->projectUpdate(input->data); - should_continue = nextStage->tryAcquireNextStage(input); + should_continue = nextStage->tryAcquireNextStage(input,final); + + if (final) + return input; // Is there anything on our input buffer? If so we should start a thread with that. QWriteLocker lock(&statusLock); @@ -792,8 +783,9 @@ public: // Calledfrom a different thread than run. - bool tryAcquireNextStage(FrameData *& input) + bool tryAcquireNextStage(FrameData *& input, bool & final) { + final = false; inputBuffer->addItem(input); QReadLocker lock(&statusLock); @@ -865,13 +857,13 @@ public: SingleThreadStage::reset(); } - FrameData * run(FrameData * input, bool & should_continue) + FrameData * run(FrameData * input, bool & should_continue, bool & final) { if (input == NULL) qFatal("NULL frame in input stage"); // Can we enter the next stage? - should_continue = nextStage->tryAcquireNextStage(input); + should_continue = nextStage->tryAcquireNextStage(input, final); // Try to get a frame from the datasource, we keep working on // the frame we have, but we will queue another job for the next @@ -893,14 +885,14 @@ public: } // The last stage, trying to access the first stage - bool tryAcquireNextStage(FrameData *& input) + bool tryAcquireNextStage(FrameData *& input, bool & final) { // Return the frame, was it the last one? - bool was_last = dataSource.returnFrame(input); + final = dataSource.returnFrame(input); input = NULL; // OK we won't continue. - if (was_last) { + if (final) { return false; } @@ -943,6 +935,29 @@ public: } }; +void BasicLoop::run() +{ + int current_idx = start_idx; + FrameData * target_item = startItem; + bool should_continue = true; + bool the_end = false; + forever + { + target_item = stages->at(current_idx)->run(target_item, should_continue, the_end); + if (!should_continue) { + break; + } + current_idx++; + current_idx = current_idx % stages->size(); + } + if (the_end) { + dynamic_cast (stages->at(0))->dataSource.wake(); + } + + this->reportFinished(); + +} + class DirectStreamTransform : public CompositeTransform { Q_OBJECT