Commit 23de1e31e82563ffe95413f68432b590fe9eb92c
Merge branch 'master' of https://github.com/biometrics/openbr
Showing
6 changed files
with
114 additions
and
14 deletions
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 &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 | ... | ... |