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,9 +434,16 @@ QList<Detection> getDetections(QString key, const Template &t, bool isList, bool
434 File f = t.file; 434 File f = t.file;
435 QList<Detection> dets; 435 QList<Detection> dets;
436 if (isList) { 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 } else { 447 } else {
441 if (isTruth) { 448 if (isTruth) {
442 dets.append(Detection(f.get<QRectF>(key))); 449 dets.append(Detection(f.get<QRectF>(key)));
openbr/core/qtutils.cpp
@@ -399,13 +399,33 @@ void showFile(const QString &amp;file) @@ -399,13 +399,33 @@ void showFile(const QString &amp;file)
399 399
400 QString toString(const QVariant &variant) 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 return QString(); 429 return QString();
410 } 430 }
411 431
openbr/openbr_plugin.h
@@ -41,6 +41,8 @@ @@ -41,6 +41,8 @@
41 #include <QVector> 41 #include <QVector>
42 #include <opencv2/core/core.hpp> 42 #include <opencv2/core/core.hpp>
43 #include <openbr/openbr.h> 43 #include <openbr/openbr.h>
  44 +#include <openbr/core/qtutils.h>
  45 +#include <openbr/core/opencvutils.h>
44 46
45 /*! 47 /*!
46 * \defgroup cpp_plugin_sdk C++ Plugin SDK 48 * \defgroup cpp_plugin_sdk C++ Plugin SDK
@@ -215,6 +217,14 @@ struct BR_EXPORT File @@ -215,6 +217,14 @@ struct BR_EXPORT File
215 static QVariant parse(const QString &value); /*!< \brief Try to convert the QString to a QPointF or QRectF if possible. */ 217 static QVariant parse(const QString &value); /*!< \brief Try to convert the QString to a QPointF or QRectF if possible. */
216 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. */ 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 void set(const QString &key, const QString &value); /*!< \brief Insert or overwrite the metadata key with the specified value. */ 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 inline void remove(const QString &key) { m_metadata.remove(key); } /*!< \brief Remove the metadata key. */ 228 inline void remove(const QString &key) { m_metadata.remove(key); } /*!< \brief Remove the metadata key. */
219 229
220 /*!< \brief Returns a value for the key, throwing an error if the key does not exist. */ 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,6 +263,19 @@ struct BR_EXPORT File
253 return list; 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 /*!< \brief Returns the value for the specified key for every file in the list. */ 279 /*!< \brief Returns the value for the specified key for every file in the list. */
257 template<class U> 280 template<class U>
258 static QList<QVariant> values(const QList<U> &fileList, const QString &key) 281 static QList<QVariant> values(const QList<U> &fileList, const QString &key)
@@ -292,9 +315,12 @@ struct BR_EXPORT File @@ -292,9 +315,12 @@ struct BR_EXPORT File
292 QList<QRectF> namedRects() const; /*!< \brief Returns rects convertible from metadata values. */ 315 QList<QRectF> namedRects() const; /*!< \brief Returns rects convertible from metadata values. */
293 QList<QRectF> rects() const; /*!< \brief Returns the file's rects list. */ 316 QList<QRectF> rects() const; /*!< \brief Returns the file's rects list. */
294 void appendRect(const QRectF &rect); /*!< \brief Adds a rect to the file's rect list. */ 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 void appendRects(const QList<QRectF> &rects); /*!< \brief Adds rects to the file's rect list. */ 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 inline void clearRects() { m_metadata["Rects"] = QList<QVariant>(); } /*!< \brief Clears the file's rect list. */ 321 inline void clearRects() { m_metadata["Rects"] = QList<QVariant>(); } /*!< \brief Clears the file's rect list. */
297 inline void setRects(const QList<QRectF> &rects) { clearRects(); appendRects(rects); } /*!< \brief Overwrites the file's rect list. */ 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 private: 325 private:
300 QMap<QString,QVariant> m_metadata; 326 QMap<QString,QVariant> m_metadata;
openbr/plugins/landmarks.cpp
@@ -113,7 +113,7 @@ class ProcrustesTransform : public Transform @@ -113,7 +113,7 @@ class ProcrustesTransform : public Transform
113 // R(0,0), R(1,0), R(1,1), R(0,1), mean_x, mean_y, norm 113 // R(0,0), R(1,0), R(1,1), R(0,1), mean_x, mean_y, norm
114 QList<float> procrustesStats; 114 QList<float> procrustesStats;
115 procrustesStats << R(0,0) << R(1,0) << R(1,1) << R(0,1) << mean[0] << mean[1] << norm; 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 if (warp) { 118 if (warp) {
119 Eigen::MatrixXf dstMat = srcMat*R; 119 Eigen::MatrixXf dstMat = srcMat*R;
@@ -273,7 +273,7 @@ class DelaunayTransform : public UntrainableTransform @@ -273,7 +273,7 @@ class DelaunayTransform : public UntrainableTransform
273 dst.file.setRects(QList<QRectF>() << OpenCVUtils::fromRect(boundingBox)); 273 dst.file.setRects(QList<QRectF>() << OpenCVUtils::fromRect(boundingBox));
274 } else dst = src; 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 #include "openbr_internal.h" 1 #include "openbr_internal.h"
2 #include "openbr/core/opencvutils.h" 2 #include "openbr/core/opencvutils.h"
3 #include "openbr/core/common.h" 3 #include "openbr/core/common.h"
  4 +#include "openbr/core/qtutils.h"
  5 +#include <opencv2/objdetect/objdetect.hpp>
4 6
5 using namespace cv; 7 using namespace cv;
6 8
@@ -117,8 +119,12 @@ private: @@ -117,8 +119,12 @@ private:
117 Template detect; 119 Template detect;
118 transform->project(windowMat, detect); 120 transform->project(windowMat, detect);
119 // the result will be in the Label 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 dst.file.appendRect(OpenCVUtils::fromRect(window)); 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 if (takeLargestScale) return; 128 if (takeLargestScale) return;
123 } 129 }
124 } 130 }
@@ -129,6 +135,36 @@ private: @@ -129,6 +135,36 @@ private:
129 135
130 BR_REGISTER(Transform, SlidingWindowTransform) 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 } // namespace br 168 } // namespace br
133 169
134 #include "slidingwindow.moc" 170 #include "slidingwindow.moc"
openbr/plugins/svm.cpp
@@ -103,6 +103,7 @@ class SVMTransform : public Transform @@ -103,6 +103,7 @@ class SVMTransform : public Transform
103 Q_PROPERTY(float gamma READ get_gamma WRITE set_gamma RESET reset_gamma STORED false) 103 Q_PROPERTY(float gamma READ get_gamma WRITE set_gamma RESET reset_gamma STORED false)
104 Q_PROPERTY(QString inputVariable READ get_inputVariable WRITE set_inputVariable RESET reset_inputVariable STORED false) 104 Q_PROPERTY(QString inputVariable READ get_inputVariable WRITE set_inputVariable RESET reset_inputVariable STORED false)
105 Q_PROPERTY(QString outputVariable READ get_outputVariable WRITE set_outputVariable RESET reset_outputVariable STORED false) 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 public: 108 public:
108 enum Kernel { Linear = CvSVM::LINEAR, 109 enum Kernel { Linear = CvSVM::LINEAR,
@@ -123,6 +124,7 @@ private: @@ -123,6 +124,7 @@ private:
123 BR_PROPERTY(float, gamma, -1) 124 BR_PROPERTY(float, gamma, -1)
124 BR_PROPERTY(QString, inputVariable, "") 125 BR_PROPERTY(QString, inputVariable, "")
125 BR_PROPERTY(QString, outputVariable, "") 126 BR_PROPERTY(QString, outputVariable, "")
  127 + BR_PROPERTY(bool, returnDFVal, false)
126 128
127 129
128 SVM svm; 130 SVM svm;
@@ -149,8 +151,17 @@ private: @@ -149,8 +151,17 @@ private:
149 151
150 void project(const Template &src, Template &dst) const 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 dst = src; 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 if (type == EPS_SVR || type == NU_SVR) 165 if (type == EPS_SVR || type == NU_SVR)
155 dst.file.set(outputVariable, prediction); 166 dst.file.set(outputVariable, prediction);
156 else 167 else