Commit 23de1e31e82563ffe95413f68432b590fe9eb92c

Authored by Brendan Klare
2 parents 40f8c19a 758cbc35

Merge branch 'master' of https://github.com/biometrics/openbr

openbr/core/eval.cpp
... ... @@ -434,9 +434,16 @@ QList<Detection> getDetections(QString key, const Template &t, bool isList, bool
434 434 File f = t.file;
435 435 QList<Detection> dets;
436 436 if (isList) {
437   - // TODO: handle Confidence for multiple detections in a template
438   - foreach (const QRectF &rect, f.rects())
439   - dets.append(Detection(rect));
  437 + QList<QRectF> rects = f.rects();
  438 + QList<float> confidences = f.getList<float>("Confidences", QList<float>());
  439 + if (!isTruth && rects.size() != confidences.size())
  440 + qFatal("You don't have enough confidence. I mean, your detections don't all have confidence measures.");
  441 + for (int i=0; i<rects.size(); i++) {
  442 + if (isTruth)
  443 + dets.append(Detection(rects.at(i)));
  444 + else
  445 + dets.append(Detection(rects.at(i), confidences.at(i)));
  446 + }
440 447 } else {
441 448 if (isTruth) {
442 449 dets.append(Detection(f.get<QRectF>(key)));
... ...
openbr/core/qtutils.cpp
... ... @@ -399,13 +399,33 @@ void showFile(const QString &amp;file)
399 399  
400 400 QString toString(const QVariant &variant)
401 401 {
402   - if (variant.canConvert(QVariant::String)) return variant.toString();
403   - else if(variant.canConvert(QVariant::PointF)) return QString("(%1,%2)").arg(QString::number(qvariant_cast<QPointF>(variant).x()),
404   - QString::number(qvariant_cast<QPointF>(variant).y()));
405   - else if (variant.canConvert(QVariant::RectF)) return QString("(%1,%2,%3,%4)").arg(QString::number(qvariant_cast<QRectF>(variant).x()),
406   - QString::number(qvariant_cast<QRectF>(variant).y()),
407   - QString::number(qvariant_cast<QRectF>(variant).width()),
408   - QString::number(qvariant_cast<QRectF>(variant).height()));
  402 + if (variant.canConvert(QVariant::String))
  403 + return variant.toString();
  404 + else if(variant.canConvert(QVariant::PointF)) {
  405 + QPointF pt = qvariant_cast<QPointF>(variant);
  406 + return QString("(%1,%2)").arg(QString::number(pt.x()),
  407 + QString::number(pt.y()));
  408 + }
  409 + else if (variant.canConvert(QVariant::RectF)) {
  410 + QRectF rect = qvariant_cast<QRectF>(variant);
  411 + return QString("(%1,%2,%3,%4)").arg(QString::number(rect.x()),
  412 + QString::number(rect.y()),
  413 + QString::number(rect.width()),
  414 + QString::number(rect.height()));
  415 + }
  416 + else if (variant.canConvert(QVariant::List)) {
  417 + QString ret = QString("[");
  418 + bool first = true;
  419 + foreach (const QVariant &i, variant.toList()) {
  420 + if (!first)
  421 + ret += ",";
  422 + else
  423 + first = false;
  424 + ret += toString(i);
  425 + }
  426 + ret += "]";
  427 + return ret;
  428 + }
409 429 return QString();
410 430 }
411 431  
... ...
openbr/openbr_plugin.h
... ... @@ -41,6 +41,8 @@
41 41 #include <QVector>
42 42 #include <opencv2/core/core.hpp>
43 43 #include <openbr/openbr.h>
  44 +#include <openbr/core/qtutils.h>
  45 +#include <openbr/core/opencvutils.h>
44 46  
45 47 /*!
46 48 * \defgroup cpp_plugin_sdk C++ Plugin SDK
... ... @@ -215,6 +217,14 @@ struct BR_EXPORT File
215 217 static QVariant parse(const QString &value); /*!< \brief Try to convert the QString to a QPointF or QRectF if possible. */
216 218 inline void set(const QString &key, const QVariant &value) { m_metadata.insert(key, value); } /*!< \brief Insert or overwrite the metadata key with the specified value. */
217 219 void set(const QString &key, const QString &value); /*!< \brief Insert or overwrite the metadata key with the specified value. */
  220 +
  221 + /*!< \brief Specialization for list type. Insert or overwrite the metadata key with the specified value. */
  222 + template <typename T>
  223 + void setList(const QString &key, const QList<T> &value)
  224 + {
  225 + set(key, QtUtils::toVariantList(value));
  226 + }
  227 +
218 228 inline void remove(const QString &key) { m_metadata.remove(key); } /*!< \brief Remove the metadata key. */
219 229  
220 230 /*!< \brief Returns a value for the key, throwing an error if the key does not exist. */
... ... @@ -253,6 +263,19 @@ struct BR_EXPORT File
253 263 return list;
254 264 }
255 265  
  266 + /*!< \brief Specialization for list type. Returns a list of type T for the key, returning \em defaultValue if the key does not exist or can't be converted. */
  267 + template <typename T>
  268 + QList<T> getList(const QString &key, const QList<T> defaultValue) const
  269 + {
  270 + if (!contains(key)) return defaultValue;
  271 + QList<T> list;
  272 + foreach (const QVariant &item, m_metadata[key].toList()) {
  273 + if (item.canConvert<T>()) list.append(item.value<T>());
  274 + else return defaultValue;
  275 + }
  276 + return list;
  277 + }
  278 +
256 279 /*!< \brief Returns the value for the specified key for every file in the list. */
257 280 template<class U>
258 281 static QList<QVariant> values(const QList<U> &fileList, const QString &key)
... ... @@ -292,9 +315,12 @@ struct BR_EXPORT File
292 315 QList<QRectF> namedRects() const; /*!< \brief Returns rects convertible from metadata values. */
293 316 QList<QRectF> rects() const; /*!< \brief Returns the file's rects list. */
294 317 void appendRect(const QRectF &rect); /*!< \brief Adds a rect to the file's rect list. */
  318 + void appendRect(const cv::Rect &rect) { appendRect(OpenCVUtils::fromRect(rect)); } /*!< \brief Adds a rect to the file's rect list. */
295 319 void appendRects(const QList<QRectF> &rects); /*!< \brief Adds rects to the file's rect list. */
  320 + void appendRects(const QList<cv::Rect> &rects) { appendRects(OpenCVUtils::fromRects(rects)); } /*!< \brief Adds rects to the file's rect list. */
296 321 inline void clearRects() { m_metadata["Rects"] = QList<QVariant>(); } /*!< \brief Clears the file's rect list. */
297 322 inline void setRects(const QList<QRectF> &rects) { clearRects(); appendRects(rects); } /*!< \brief Overwrites the file's rect list. */
  323 + inline void setRects(const QList<cv::Rect> &rects) { clearRects(); appendRects(rects); } /*!< \brief Overwrites the file's rect list. */
298 324  
299 325 private:
300 326 QMap<QString,QVariant> m_metadata;
... ...
openbr/plugins/landmarks.cpp
... ... @@ -113,7 +113,7 @@ class ProcrustesTransform : public Transform
113 113 // R(0,0), R(1,0), R(1,1), R(0,1), mean_x, mean_y, norm
114 114 QList<float> procrustesStats;
115 115 procrustesStats << R(0,0) << R(1,0) << R(1,1) << R(0,1) << mean[0] << mean[1] << norm;
116   - dst.file.set("ProcrustesStats",QtUtils::toVariantList(procrustesStats));
  116 + dst.file.setList<float>("ProcrustesStats",procrustesStats);
117 117  
118 118 if (warp) {
119 119 Eigen::MatrixXf dstMat = srcMat*R;
... ... @@ -273,7 +273,7 @@ class DelaunayTransform : public UntrainableTransform
273 273 dst.file.setRects(QList<QRectF>() << OpenCVUtils::fromRect(boundingBox));
274 274 } else dst = src;
275 275  
276   - dst.file.set("DelaunayTriangles", QtUtils::toVariantList(validTriangles));
  276 + dst.file.setList<QPointF>("DelaunayTriangles", validTriangles);
277 277 }
278 278 };
279 279  
... ...
openbr/plugins/slidingwindow.cpp
1 1 #include "openbr_internal.h"
2 2 #include "openbr/core/opencvutils.h"
3 3 #include "openbr/core/common.h"
  4 +#include "openbr/core/qtutils.h"
  5 +#include <opencv2/objdetect/objdetect.hpp>
4 6  
5 7 using namespace cv;
6 8  
... ... @@ -117,8 +119,12 @@ private:
117 119 Template detect;
118 120 transform->project(windowMat, detect);
119 121 // the result will be in the Label
120   - if (detect.file.get<QString>(QString("Label")) == "pos") {
  122 + if (detect.file.get<QString>("Label") == "pos") {
121 123 dst.file.appendRect(OpenCVUtils::fromRect(window));
  124 + float confidence = detect.file.get<float>("Dist");
  125 + QList<float> confidences = dst.file.getList<float>("Confidences", QList<float>());
  126 + confidences.append(confidence);
  127 + dst.file.setList<float>("Confidences", confidences);
122 128 if (takeLargestScale) return;
123 129 }
124 130 }
... ... @@ -129,6 +135,36 @@ private:
129 135  
130 136 BR_REGISTER(Transform, SlidingWindowTransform)
131 137  
  138 +/*!
  139 + * \ingroup transforms
  140 + * \brief Detects objects with OpenCV's built-in HOG detection.
  141 + * \author Austin Blanton \cite imaus10
  142 + */
  143 +class HOGDetectTransform : public UntrainableTransform
  144 +{
  145 + Q_OBJECT
  146 +
  147 + HOGDescriptor hog;
  148 +
  149 + void init()
  150 + {
  151 + hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());
  152 + }
  153 +
  154 + void project(const Template &src, Template &dst) const
  155 + {
  156 + dst = src;
  157 + std::vector<Rect> objLocs;
  158 + QList<Rect> rects;
  159 + hog.detectMultiScale(src, objLocs);
  160 + foreach (const Rect &obj, objLocs)
  161 + rects.append(obj);
  162 + dst.file.setRects(rects);
  163 + }
  164 +};
  165 +
  166 +BR_REGISTER(Transform, HOGDetectTransform)
  167 +
132 168 } // namespace br
133 169  
134 170 #include "slidingwindow.moc"
... ...
openbr/plugins/svm.cpp
... ... @@ -103,6 +103,7 @@ class SVMTransform : public Transform
103 103 Q_PROPERTY(float gamma READ get_gamma WRITE set_gamma RESET reset_gamma STORED false)
104 104 Q_PROPERTY(QString inputVariable READ get_inputVariable WRITE set_inputVariable RESET reset_inputVariable STORED false)
105 105 Q_PROPERTY(QString outputVariable READ get_outputVariable WRITE set_outputVariable RESET reset_outputVariable STORED false)
  106 + Q_PROPERTY(bool returnDFVal READ get_returnDFVal WRITE set_returnDFVal RESET reset_returnDFVal STORED false)
106 107  
107 108 public:
108 109 enum Kernel { Linear = CvSVM::LINEAR,
... ... @@ -123,6 +124,7 @@ private:
123 124 BR_PROPERTY(float, gamma, -1)
124 125 BR_PROPERTY(QString, inputVariable, "")
125 126 BR_PROPERTY(QString, outputVariable, "")
  127 + BR_PROPERTY(bool, returnDFVal, false)
126 128  
127 129  
128 130 SVM svm;
... ... @@ -149,8 +151,17 @@ private:
149 151  
150 152 void project(const Template &src, Template &dst) const
151 153 {
  154 + if (returnDFVal && reverseLookup.size() > 2)
  155 + qFatal("Decision function for multiclass classification not implemented.");
  156 +
152 157 dst = src;
153   - float prediction = svm.predict(src.m().reshape(1, 1));
  158 + float prediction = svm.predict(src.m().reshape(1, 1), returnDFVal);
  159 + if (returnDFVal) {
  160 + dst.file.set("Dist", prediction);
  161 + // positive values ==> first class
  162 + // negative values ==> second class
  163 + prediction = prediction > 0 ? 0 : 1;
  164 + }
154 165 if (type == EPS_SVR || type == NU_SVR)
155 166 dst.file.set(outputVariable, prediction);
156 167 else
... ...