Commit c2634f0f043353582755dcc3889ac15da0210e76

Authored by Josh Klontz
2 parents 6023480a fea31bb9

Merge branch 'master' into janus

.gitignore
... ... @@ -4,6 +4,7 @@
4 4 data/*/img
5 5 data/*/vid
6 6 data/PCSO/*
  7 +data/lfpw
7 8 build*
8 9 scripts/results
9 10  
... ... @@ -38,3 +39,4 @@ scripts/results
38 39 ### autogenerated sigsets ###
39 40 data/INRIAPerson/sigset
40 41 data/KTH/sigset
  42 +
... ...
openbr/core/core.cpp
... ... @@ -70,7 +70,7 @@ struct AlgorithmCore
70 70  
71 71 if (!distance.isNull()) {
72 72 qDebug("Projecting Enrollment");
73   - data >> *transform;
  73 + data >> *downcast;
74 74  
75 75 qDebug("Training Comparison");
76 76 distance->train(data);
... ... @@ -490,9 +490,18 @@ void br::Cat(const QStringList &inputGalleries, const QString &outputGallery)
490 490 }
491 491 }
492 492  
493   -QSharedPointer<br::Transform> br::Transform::fromAlgorithm(const QString &algorithm)
  493 +QSharedPointer<br::Transform> br::Transform::fromAlgorithm(const QString &algorithm, bool preprocess)
494 494 {
495   - return AlgorithmManager::getAlgorithm(algorithm)->transform;
  495 + if (!preprocess)
  496 + return AlgorithmManager::getAlgorithm(algorithm)->transform;
  497 + else {
  498 + QSharedPointer<Transform> orig_tform = AlgorithmManager::getAlgorithm(algorithm)->transform;
  499 + QSharedPointer<Transform> newRoot = QSharedPointer<Transform>(Transform::make("Stream(Identity)", NULL));
  500 + WrapperTransform * downcast = dynamic_cast<WrapperTransform *> (newRoot.data());
  501 + downcast->transform = orig_tform.data();
  502 + downcast->init();
  503 + return newRoot;
  504 + }
496 505 }
497 506  
498 507 QSharedPointer<br::Distance> br::Distance::fromAlgorithm(const QString &algorithm)
... ...
openbr/openbr.cpp
... ... @@ -341,6 +341,12 @@ int br_img_channels(br_template tmpl)
341 341 return t->m().channels();
342 342 }
343 343  
  344 +bool br_img_is_empty(br_template tmpl)
  345 +{
  346 + Template *t = reinterpret_cast<Template*>(tmpl);
  347 + return t->m().empty();
  348 +}
  349 +
344 350 void br_set_filename(br_template tmpl, const char *filename)
345 351 {
346 352 Template *t = reinterpret_cast<Template*>(tmpl);
... ... @@ -356,6 +362,12 @@ br_template_list br_enroll_template(br_template tmpl)
356 362 return (br_template_list)tl;
357 363 }
358 364  
  365 +void br_enroll_template_list(br_template_list tl)
  366 +{
  367 + TemplateList *realTL = reinterpret_cast<TemplateList*>(tl);
  368 + Enroll(*realTL);
  369 +}
  370 +
359 371 br_template br_get_template(br_template_list tl, int index)
360 372 {
361 373 TemplateList *realTL = reinterpret_cast<TemplateList*>(tl);
... ...
openbr/openbr.h
... ... @@ -467,6 +467,10 @@ BR_EXPORT int br_img_cols(br_template tmpl);
467 467 */
468 468 BR_EXPORT int br_img_channels(br_template tmpl);
469 469 /*!
  470 + * \brief Returns if the image is empty.
  471 + */
  472 +BR_EXPORT bool br_img_is_empty(br_template tmpl);
  473 +/*!
470 474 * \brief Set the filename for a template.
471 475 */
472 476 BR_EXPORT void br_set_filename(br_template tmpl, const char *filename);
... ... @@ -476,6 +480,11 @@ BR_EXPORT void br_set_filename(br_template tmpl, const char *filename);
476 480 */
477 481 BR_EXPORT br_template_list br_enroll_template(br_template tmpl);
478 482 /*!
  483 + * \brief Enroll a br::TemplateList from the C API!
  484 + * \param tmpl Pointer to a br::TemplateList.
  485 + */
  486 +BR_EXPORT void br_enroll_template_list(br_template_list tl);
  487 +/*!
479 488 * \brief Get a pointer to a br::Template at a specified index.
480 489 * \param tl Pointer to a br::TemplateList.
481 490 * \param index The index of the br::Template.
... ...
openbr/openbr_plugin.cpp
... ... @@ -1184,10 +1184,6 @@ Transform *Transform::make(QString str, QObject *parent)
1184 1184 if (Globals->abbreviations.contains(str))
1185 1185 return make(Globals->abbreviations[str], parent);
1186 1186  
1187   - { // Check for use of '!' as shorthand for Expand
1188   - str.replace("!","+Expand+");
1189   - }
1190   -
1191 1187 //! [Make a pipe]
1192 1188 { // Check for use of '+' as shorthand for Pipe(...)
1193 1189 QStringList words = parse(str, '+');
... ...
openbr/openbr_plugin.h
... ... @@ -1105,7 +1105,7 @@ public:
1105 1105  
1106 1106 virtual ~Transform() {}
1107 1107 static Transform *make(QString str, QObject *parent); /*!< \brief Make a transform from a string. */
1108   - static QSharedPointer<Transform> fromAlgorithm(const QString &algorithm); /*!< \brief Retrieve an algorithm's transform. */
  1108 + static QSharedPointer<Transform> fromAlgorithm(const QString &algorithm, bool preprocess=true); /*!< \brief Retrieve an algorithm's transform. If preprocess is true, attaches a stream transform as the root of the algorithm*/
1109 1109  
1110 1110 virtual Transform *clone() const; /*!< \brief Copy the transform. */
1111 1111  
... ... @@ -1124,6 +1124,7 @@ public:
1124 1124  
1125 1125 /*!< \brief Apply the transform to a single template. Typically used by independent transforms */
1126 1126 virtual void project(const Template &src, Template &dst) const = 0;
  1127 +
1127 1128 /*!< \brief Apply the transform, taking the full template list as input.
1128 1129 * A TemplateList is what is typically passed from transform to transform. Transforms that just
1129 1130 * need to operatoe on a single template at a time (and want to output exactly 1 template) can implement
... ... @@ -1208,7 +1209,9 @@ public:
1208 1209 * and copy enough of their state that projectUpdate can safely be called on the original
1209 1210 * instance, and the copy concurrently.
1210 1211 */
1211   - virtual Transform * smartCopy() { return this;}
  1212 + virtual Transform * smartCopy(bool & newTransform) { newTransform=false; return this;}
  1213 +
  1214 + virtual Transform * smartCopy() {bool junk; return smartCopy(junk);}
1212 1215  
1213 1216 /*!
1214 1217 * \brief Recursively retrieve a named event, returns NULL if an event is not found.
... ...
openbr/plugins/algorithms.cpp
... ... @@ -31,14 +31,14 @@ class AlgorithmsInitializer : public Initializer
31 31 void initialize() const
32 32 {
33 33 // Face
34   - Globals->abbreviations.insert("FaceRecognition", "FaceDetection!<FaceRecognitionRegistration>!<FaceRecognitionExtraction>+<FaceRecognitionEmbedding>+<FaceRecognitionQuantization>:MatchProbability(ByteL1)");
35   - Globals->abbreviations.insert("GenderClassification", "FaceDetection!<FaceClassificationRegistration>!<FaceClassificationExtraction>+<GenderClassifier>+Discard");
36   - Globals->abbreviations.insert("AgeRegression", "FaceDetection!<FaceClassificationRegistration>!<FaceClassificationExtraction>+<AgeRegressor>+Discard");
37   - Globals->abbreviations.insert("FaceQuality", "Open!Cascade(FrontalFace)+ASEFEyes+Affine(64,64,0.25,0.35)+ImageQuality+Cvt(Gray)+DFFS+Discard");
38   - Globals->abbreviations.insert("MedianFace", "Open!Cascade(FrontalFace)+ASEFEyes+Affine(256,256,0.37,0.45)+Center(Median)");
  34 + Globals->abbreviations.insert("FaceRecognition", "FaceDetection+Expand+<FaceRecognitionRegistration>+Expand+<FaceRecognitionExtraction>+<FaceRecognitionEmbedding>+<FaceRecognitionQuantization>:MatchProbability(ByteL1)");
  35 + Globals->abbreviations.insert("GenderClassification", "FaceDetection+Expand+<FaceClassificationRegistration>+Expand+<FaceClassificationExtraction>+<GenderClassifier>+Discard");
  36 + Globals->abbreviations.insert("AgeRegression", "FaceDetection+Expand+<FaceClassificationRegistration>+Expand+<FaceClassificationExtraction>+<AgeRegressor>+Discard");
  37 + Globals->abbreviations.insert("FaceQuality", "Open+Expand+Cascade(FrontalFace)+ASEFEyes+Affine(64,64,0.25,0.35)+ImageQuality+Cvt(Gray)+DFFS+Discard");
  38 + Globals->abbreviations.insert("MedianFace", "Open+Expand+Cascade(FrontalFace)+ASEFEyes+Affine(256,256,0.37,0.45)+Center(Median)");
39 39 Globals->abbreviations.insert("BlurredFaceDetection", "Open+LimitSize(1024)+SkinMask/(Cvt(Gray)+GradientMask)+And+Morph(Erode,16)+LargestConvexArea");
40   - Globals->abbreviations.insert("DrawFaceDetection", "Open+Cascade(FrontalFace)!ASEFEyes+Draw");
41   - Globals->abbreviations.insert("ShowFaceDetection", "DrawFaceDetection!Show");
  40 + Globals->abbreviations.insert("DrawFaceDetection", "Open+Cascade(FrontalFace)+Expand+ASEFEyes+Draw");
  41 + Globals->abbreviations.insert("ShowFaceDetection", "DrawFaceDetection+Expand+Show");
42 42 Globals->abbreviations.insert("OpenBR", "FaceRecognition");
43 43 Globals->abbreviations.insert("GenderEstimation", "GenderClassification");
44 44 Globals->abbreviations.insert("AgeEstimation", "AgeRegression");
... ... @@ -60,7 +60,7 @@ class AlgorithmsInitializer : public Initializer
60 60 Globals->abbreviations.insert("SURF", "Open+KeyPointDetector(SURF)+KeyPointDescriptor(SURF):KeyPointMatcher(BruteForce)");
61 61 Globals->abbreviations.insert("SmallSIFT", "Open+LimitSize(512)+KeyPointDetector(SIFT)+KeyPointDescriptor(SIFT):KeyPointMatcher(BruteForce)");
62 62 Globals->abbreviations.insert("SmallSURF", "Open+LimitSize(512)+KeyPointDetector(SURF)+KeyPointDescriptor(SURF):KeyPointMatcher(BruteForce)");
63   - Globals->abbreviations.insert("ColorHist", "Open+LimitSize(512)!EnsureChannels(3)+SplitChannels+Hist(256,0,8)+Cat+Normalize(L1):L2");
  63 + Globals->abbreviations.insert("ColorHist", "Open+LimitSize(512)+Expand+EnsureChannels(3)+SplitChannels+Hist(256,0,8)+Cat+Normalize(L1):L2");
64 64 Globals->abbreviations.insert("ImageClassification", "Open+CropSquare+LimitSize(256)+Cvt(Gray)+Gradient+Bin(0,360,9,true)+Merge+Integral+RecursiveIntegralSampler(4,2,8,Singleton(KMeans(256)))+Cat+CvtFloat+Hist(256)+KNN(5,Dist(L1),false,5)+Rename(KNN,Subject)");
65 65 Globals->abbreviations.insert("TanTriggs", "Blur(1.1)+Gamma(0.2)+DoG(1,2)+ContrastEq(0.1,10)");
66 66  
... ...
openbr/plugins/crop.cpp
... ... @@ -57,10 +57,16 @@ BR_REGISTER(Transform, CropTransform)
57 57 class ROITransform : public UntrainableTransform
58 58 {
59 59 Q_OBJECT
  60 + Q_PROPERTY(QString propName READ get_propName WRITE set_propName RESET reset_propName STORED false)
  61 + BR_PROPERTY(QString, propName, "")
60 62  
61 63 void project(const Template &src, Template &dst) const
62 64 {
63   - if (src.file.rects().empty()) {
  65 + if (!propName.isEmpty()) {
  66 + QRectF rect = src.file.get<QRectF>(propName);
  67 + dst += src.m()(OpenCVUtils::toRect(rect));
  68 + }
  69 + else if (src.file.rects().empty()) {
64 70 dst = src;
65 71 if (Globals->verbose) qWarning("No rects present in file.");
66 72 }
... ...
openbr/plugins/draw.cpp
... ... @@ -56,7 +56,7 @@ class DrawTransform : public UntrainableTransform
56 56 for (int i=0; i<pointsList.size(); i++) {
57 57 const Point2f &point = pointsList[i];
58 58 circle(dst, point, 3, color, -1);
59   - if (verbose) putText(dst, QString::number(i).toStdString(), point, FONT_HERSHEY_SIMPLEX, 0.5, verboseColor, 1);
  59 + if (verbose) putText(dst, QString("%1,(%2,%3)").arg(QString::number(i),QString::number(point.x),QString::number(point.y)).toStdString(), point, FONT_HERSHEY_SIMPLEX, 0.5, verboseColor, 1);
60 60 }
61 61 }
62 62 if (rects) {
... ... @@ -336,8 +336,7 @@ class AdjacentOverlayTransform : public Transform
336 336  
337 337 void init()
338 338 {
339   - opener = br::Transform::fromAlgorithm("Cache(Open)");
340   -
  339 + opener = QSharedPointer<br::Transform>(br::Transform::make("Cache(Open)", NULL));
341 340 }
342 341  
343 342 };
... ...
openbr/plugins/gui.cpp
... ... @@ -176,6 +176,10 @@ public:
176 176 setFixedSize(200,200);
177 177 QApplication::instance()->installEventFilter(this);
178 178 }
  179 + ~DisplayWindow()
  180 + {
  181 + QApplication::instance()->removeEventFilter(this);
  182 + }
179 183  
180 184 public slots:
181 185 void showImage(const QPixmap & input)
... ... @@ -193,7 +197,6 @@ public slots:
193 197 setFixedSize(temp);
194 198 }
195 199  
196   -
197 200 bool eventFilter(QObject * obj, QEvent * event)
198 201 {
199 202 if (event->type() == QEvent::KeyPress)
... ... @@ -420,7 +423,10 @@ public:
420 423 ~ShowTransform()
421 424 {
422 425 delete displayBuffer;
423   - delete window;
  426 + if (QThread::currentThread() == QCoreApplication::instance()->thread())
  427 + delete window;
  428 + else
  429 + emit destroyWindow();
424 430 }
425 431  
426 432 void train(const TemplateList &data) { (void) data; }
... ... @@ -494,6 +500,7 @@ public:
494 500 connect(this, SIGNAL(updateImage(QPixmap)), window,SLOT(showImage(QPixmap)));
495 501 connect(this, SIGNAL(changeTitle(QString)), window, SLOT(setWindowTitle(QString)));
496 502 connect(this, SIGNAL(hideWindow()), window, SLOT(hide()));
  503 + connect(this, SIGNAL(destroyWindow()), window, SLOT(deleteLater()), Qt::BlockingQueuedConnection);
497 504 }
498 505  
499 506 protected:
... ... @@ -506,6 +513,7 @@ signals:
506 513 void updateImage(const QPixmap & input);
507 514 void changeTitle(const QString & input);
508 515 void hideWindow();
  516 + void destroyWindow();
509 517 };
510 518 BR_REGISTER(Transform, ShowTransform)
511 519  
... ...
openbr/plugins/landmarks.cpp
... ... @@ -305,6 +305,116 @@ class DrawDelaunayTransform : public UntrainableTransform
305 305  
306 306 BR_REGISTER(Transform, DrawDelaunayTransform)
307 307  
  308 +/*!
  309 + * \ingroup transforms
  310 + * \brief Read landmarks from a file and associate them with the correct templates.
  311 + * \author Scott Klum \cite sklum
  312 + *
  313 + * Example of the format:
  314 + * \code
  315 + * image_001.jpg:146.000000,190.000000,227.000000,186.000000,202.000000,256.000000
  316 + * image_002.jpg:75.000000,235.000000,140.000000,225.000000,91.000000,300.000000
  317 + * image_003.jpg:158.000000,186.000000,246.000000,188.000000,208.000000,233.000000
  318 + * \endcode
  319 + */
  320 +class ReadLandmarksTransform : public UntrainableTransform
  321 +{
  322 + Q_OBJECT
  323 +
  324 + Q_PROPERTY(QString file READ get_file WRITE set_file RESET reset_file STORED false)
  325 + Q_PROPERTY(QString imageDelimiter READ get_imageDelimiter WRITE set_imageDelimiter RESET reset_imageDelimiter STORED false)
  326 + Q_PROPERTY(QString landmarkDelimiter READ get_landmarkDelimiter WRITE set_landmarkDelimiter RESET reset_landmarkDelimiter STORED false)
  327 + BR_PROPERTY(QString, file, QString())
  328 + BR_PROPERTY(QString, imageDelimiter, ":")
  329 + BR_PROPERTY(QString, landmarkDelimiter, ",")
  330 +
  331 + QHash<QString, QList<QPointF> > landmarks;
  332 +
  333 + void init()
  334 + {
  335 + if (file.isEmpty())
  336 + return;
  337 +
  338 + QFile f(file);
  339 + if (!f.open(QFile::ReadOnly | QFile::Text))
  340 + qFatal("Failed to open %s for reading.", qPrintable(f.fileName()));
  341 +
  342 + while (!f.atEnd()) {
  343 + const QStringList words = QString(f.readLine()).split(imageDelimiter);
  344 + const QStringList lm = words[1].split(landmarkDelimiter);
  345 +
  346 + QList<QPointF> points;
  347 + bool ok;
  348 + for (int i=0; i<lm.size(); i+=2)
  349 + points.append(QPointF(lm[i].toFloat(&ok),lm[i+1].toFloat(&ok)));
  350 + if (!ok) qFatal("Failed to read landmark.");
  351 +
  352 + landmarks.insert(words[0],points);
  353 + }
  354 + }
  355 +
  356 + void project(const Template &src, Template &dst) const
  357 + {
  358 + dst = src;
  359 +
  360 + dst.file.appendPoints(landmarks[dst.file.fileName()]);
  361 + }
  362 +};
  363 +
  364 +BR_REGISTER(Transform, ReadLandmarksTransform)
  365 +
  366 +/*!
  367 + * \ingroup transforms
  368 + * \brief Name a point
  369 + * \author Scott Klum \cite sklum
  370 + */
  371 +class NamePointsTransform : public UntrainableMetaTransform
  372 +{
  373 + Q_OBJECT
  374 + Q_PROPERTY(QList<int> indices READ get_indices WRITE set_indices RESET reset_indices STORED false)
  375 + Q_PROPERTY(QStringList names READ get_names WRITE set_names RESET reset_names STORED false)
  376 + BR_PROPERTY(QList<int>, indices, QList<int>())
  377 + BR_PROPERTY(QStringList, names, QStringList())
  378 +
  379 + void project(const Template &src, Template &dst) const
  380 + {
  381 + if (indices.size() != names.size()) qFatal("Point/name size mismatch");
  382 +
  383 + dst = src;
  384 +
  385 + QList<QPointF> points = src.file.points();
  386 +
  387 + for (int i=0; i<indices.size(); i++) {
  388 + if (indices[i] < points.size()) dst.file.set(names[i], points[indices[i]]);
  389 + else qFatal("Idex out of range.");
  390 + }
  391 + }
  392 +};
  393 +
  394 +BR_REGISTER(Transform, NamePointsTransform)
  395 +
  396 +/*!
  397 + * \ingroup transforms
  398 + * \brief Remove a name from a point
  399 + * \author Scott Klum \cite sklum
  400 + */
  401 +class AnonymizePointsTransform : public UntrainableMetaTransform
  402 +{
  403 + Q_OBJECT
  404 + Q_PROPERTY(QStringList names READ get_names WRITE set_names RESET reset_names STORED false)
  405 + BR_PROPERTY(QStringList, names, QStringList())
  406 +
  407 + void project(const Template &src, Template &dst) const
  408 + {
  409 + dst = src;
  410 +
  411 + foreach (const QString &name, names)
  412 + if (src.file.contains(name)) dst.file.appendPoint(src.file.get<QPointF>(name));
  413 + }
  414 +};
  415 +
  416 +BR_REGISTER(Transform, AnonymizePointsTransform)
  417 +
308 418 } // namespace br
309 419  
310 420 #include "landmarks.moc"
... ...
openbr/plugins/meta.cpp
... ... @@ -248,8 +248,8 @@ class ExpandTransform : public UntrainableMetaTransform
248 248  
249 249 virtual void project(const Template & src, Template & dst) const
250 250 {
251   - qFatal("this has gone bad");
252   - (void) src; (void) dst;
  251 + dst = src;
  252 + qDebug("Called Expand project(Template,Template), nothing will happen");
253 253 }
254 254 };
255 255  
... ... @@ -614,13 +614,20 @@ class DistributeTemplateTransform : public MetaTransform
614 614  
615 615 public:
616 616  
617   - Transform * smartCopy()
  617 + Transform * smartCopy(bool & newTransform)
618 618 {
619   - if (!transform->timeVarying())
  619 + if (!transform->timeVarying()) {
  620 + newTransform = false;
620 621 return this;
  622 + }
  623 + newTransform = true;
621 624  
622 625 DistributeTemplateTransform * output = new DistributeTemplateTransform;
623   - output->transform = transform->smartCopy();
  626 + bool newChild = false;
  627 + output->transform = transform->smartCopy(newChild);
  628 + if (newChild)
  629 + output->transform->setParent(output);
  630 +
624 631 return output;
625 632 }
626 633  
... ...
openbr/plugins/openbr_internal.h
... ... @@ -139,8 +139,9 @@ public:
139 139 *\brief For transforms that don't do any training, this default implementation
140 140 * which creates a new copy of the Transform from its description string is sufficient.
141 141 */
142   - virtual Transform * smartCopy()
  142 + virtual Transform * smartCopy(bool & newTransform)
143 143 {
  144 + newTransform = true;
144 145 return this->clone();
145 146 }
146 147  
... ... @@ -250,10 +251,13 @@ public:
250 251 * it creates a new copy of its own class, and gives that copy the child transforms
251 252 * returned by calling smartCopy on this transforms children
252 253 */
253   - Transform * smartCopy()
  254 + Transform * smartCopy(bool & newTransform)
254 255 {
255   - if (!timeVarying())
  256 + if (!timeVarying()) {
  257 + newTransform = false;
256 258 return this;
  259 + }
  260 + newTransform = true;
257 261  
258 262 QString name = metaObject()->className();
259 263 name.replace("Transform","");
... ... @@ -266,8 +270,9 @@ public:
266 270  
267 271 foreach(Transform* t, transforms )
268 272 {
269   - Transform * maybe_copy = t->smartCopy();
270   - if (maybe_copy->parent() == NULL)
  273 + bool newItem = false;
  274 + Transform * maybe_copy = t->smartCopy(newItem);
  275 + if (newItem)
271 276 maybe_copy->setParent(output);
272 277 output->transforms.append(maybe_copy);
273 278 }
... ...
openbr/plugins/slidingwindow.cpp
... ... @@ -380,8 +380,10 @@ private:
380 380 QList<Rect> rects;
381 381 QList<float> confidences;
382 382 foreach (const Template &t, src) {
383   - rects.append(OpenCVUtils::toRect(t.file.get<QRectF>("Detection")));
384   - confidences.append(t.file.get<float>("Confidence"));
  383 + if (t.file.contains("Detection")) {
  384 + rects.append(OpenCVUtils::toRect(t.file.get<QRectF>("Detection")));
  385 + confidences.append(t.file.get<float>("Confidence"));
  386 + }
385 387 }
386 388  
387 389 // Compute overlap between rectangles and create discrete Laplacian matrix
... ...
openbr/plugins/stream.cpp
... ... @@ -1007,14 +1007,24 @@ public:
1007 1007  
1008 1008 void project(const Template &src, Template &dst) const
1009 1009 {
1010   - (void) src; (void) dst;
1011   - qFatal("nope");
  1010 + TemplateList in;
  1011 + in.append(src);
  1012 + TemplateList out;
  1013 + CompositeTransform::project(in,out);
  1014 + dst = out.first();
  1015 + if (out.size() > 1)
  1016 + qDebug("Returning first output template only");
1012 1017 }
1013 1018  
1014 1019 void projectUpdate(const Template &src, Template &dst)
1015 1020 {
1016   - (void) src; (void) dst;
1017   - qFatal("whatever");
  1021 + TemplateList in;
  1022 + in.append(src);
  1023 + TemplateList out;
  1024 + projectUpdate(in,out);
  1025 + dst = out.first();
  1026 + if (out.size() > 1)
  1027 + qDebug("Returning first output template only");
1018 1028 }
1019 1029  
1020 1030  
... ... @@ -1082,10 +1092,6 @@ public:
1082 1092  
1083 1093 // dst is set to all output received by the final stage, along
1084 1094 // with anything output via the calls to finalize.
1085   - //dst = collectionStage->getOutput();
1086   -
1087   - // dst is set to all output received by the final stage, along
1088   - // with anything output via the calls to finalize.
1089 1095 foreach(const TemplateList & list, collector->sets) {
1090 1096 dst.append(list);
1091 1097 }
... ... @@ -1368,10 +1374,10 @@ public:
1368 1374 basis.init();
1369 1375 }
1370 1376  
1371   - Transform * smartCopy()
  1377 + Transform * smartCopy(bool & newTransform)
1372 1378 {
1373 1379 // We just want the DirectStream to begin with, so just return a copy of that.
1374   - DirectStreamTransform * res = (DirectStreamTransform *) basis.smartCopy();
  1380 + DirectStreamTransform * res = (DirectStreamTransform *) basis.smartCopy(newTransform);
1375 1381 res->activeFrames = this->activeFrames;
1376 1382 return res;
1377 1383 }
... ...
openbr/plugins/template.cpp
... ... @@ -50,58 +50,6 @@ class RemoveTemplatesTransform : public UntrainableMetaTransform
50 50  
51 51 BR_REGISTER(Transform, RemoveTemplatesTransform)
52 52  
53   -/*!
54   - * \ingroup transforms
55   - * \brief Name a point
56   - * \author Scott Klum \cite sklum
57   - */
58   -class NamePointsTransform : public UntrainableMetaTransform
59   -{
60   - Q_OBJECT
61   - Q_PROPERTY(QList<int> indices READ get_indices WRITE set_indices RESET reset_indices STORED false)
62   - Q_PROPERTY(QStringList names READ get_names WRITE set_names RESET reset_names STORED false)
63   - BR_PROPERTY(QList<int>, indices, QList<int>())
64   - BR_PROPERTY(QStringList, names, QStringList())
65   -
66   - void project(const Template &src, Template &dst) const
67   - {
68   - if (indices.size() != names.size()) qFatal("Point/name size mismatch");
69   -
70   - dst = src;
71   -
72   - QList<QPointF> points = src.file.points();
73   -
74   - for (int i=0; i<indices.size(); i++) {
75   - if (indices[i] < points.size()) dst.file.set(names[i], points[indices[i]]);
76   - else qFatal("Idex out of range.");
77   - }
78   - }
79   -};
80   -
81   -BR_REGISTER(Transform, NamePointsTransform)
82   -
83   -/*!
84   - * \ingroup transforms
85   - * \brief Remove a name from a point
86   - * \author Scott Klum \cite sklum
87   - */
88   -class AnonymizePointsTransform : public UntrainableMetaTransform
89   -{
90   - Q_OBJECT
91   - Q_PROPERTY(QStringList names READ get_names WRITE set_names RESET reset_names STORED false)
92   - BR_PROPERTY(QStringList, names, QStringList())
93   -
94   - void project(const Template &src, Template &dst) const
95   - {
96   - dst = src;
97   -
98   - foreach (const QString &name, names)
99   - if (src.file.contains(name)) dst.file.appendPoint(src.file.get<QPointF>(name));
100   - }
101   -};
102   -
103   -BR_REGISTER(Transform, AnonymizePointsTransform)
104   -
105 53 } // namespace br
106 54  
107 55 #include "template.moc"
... ...
scripts/evalFaceRecognition-LFW.sh 0 → 100755
  1 +#!/bin/bash
  2 +
  3 +ALGORITHM=FaceRecognition
  4 +
  5 +if [ ! -f evalFaceRecognition-LFW.sh ]; then
  6 + echo "Run this script from the scripts folder!"
  7 + exit
  8 +fi
  9 +
  10 +if ! hash br 2>/dev/null; then
  11 + echo "Can't find 'br'. Did you forget to build and install OpenBR? Here's some help: http://openbiometrics.org/doxygen/latest/installation.html"
  12 + exit
  13 +fi
  14 +
  15 +# Get the data
  16 +./downloadDatasets.sh
  17 +
  18 +if [ ! -e Algorithm_Dataset ]; then
  19 + mkdir Algorithm_Dataset
  20 +fi
  21 +
  22 +# Run the LFW test protocol
  23 +br -useGui 0 -algorithm $ALGORITHM -path ../data/LFW/img/ -crossValidate 10 -pairwiseCompare ../data/LFW/sigset/test_image_restricted_target.xml ../data/LFW/sigset/test_image_restricted_query.xml ${ALGORITHM}_LFW.mtx -convert Output ${ALGORITHM}_lfw.mtx Algorithm_Dataset/${ALGORITHM}_LFW%1.eval
  24 +
  25 +# Plot results
  26 +br -useGui 0 -plot Algorithm_Dataset/* 'lfw_results.pdf[smooth=Dataset,rocOptions[yLimits=(0,1)]]'
... ...
scripts/evalGenderClassification-PCSO.sh
... ... @@ -5,12 +5,11 @@ if [ ! -f evalGenderClassification-PCSO.sh ]; then
5 5 fi
6 6  
7 7 export BR=../build/app/br/br
8   -export genderAlg=GenderClassification
9   -
10   -export PCSO_DIR=/user/pripshare/Databases/FaceDatabases/PCSO/PCSO/
  8 +export ALGORITHM=GenderClassification
  9 +export PCSO_DIR=../data/PCSO/img
11 10  
12 11 # Create a file list by querying the database
13 12 $BR -useGui 0 -quiet -algorithm Identity -enroll "$PCSO_DIR/PCSO.db[query='SELECT File,Gender,PersonID FROM PCSO', subset=1:8000]" terminal.txt > Input.txt
14 13  
15 14 # Enroll the file list and evaluate performance
16   -$BR -useGui 0 -algorithm $genderAlg -path $PCSO_DIR/Images -enroll Input.txt Output.txt -evalClassification Output.txt Input.txt Gender
17 15 \ No newline at end of file
  16 +$BR -useGui 0 -algorithm $ALGORITHM -path $PCSO_DIR -enroll Input.txt Output.txt -evalClassification Output.txt Input.txt Gender
18 17 \ No newline at end of file
... ...
1   -Subproject commit a73d51013ea05f263e88a28539393159fff2183e
  1 +Subproject commit bcbff8c485f19daddb2e6b2abd5a505ed8c1e526
... ...