Commit e69f6ae399efcec931cc7b217d05b66a881117c0
1 parent
07420612
refactored CascadeTransform to support ROC confidence values
Showing
1 changed file
with
48 additions
and
10 deletions
openbr/plugins/cascade.cpp
| @@ -49,19 +49,20 @@ private: | @@ -49,19 +49,20 @@ private: | ||
| 49 | } | 49 | } |
| 50 | }; | 50 | }; |
| 51 | 51 | ||
| 52 | - | ||
| 53 | /*! | 52 | /*! |
| 54 | * \ingroup transforms | 53 | * \ingroup transforms |
| 55 | * \brief Wraps OpenCV cascade classifier | 54 | * \brief Wraps OpenCV cascade classifier |
| 56 | * \author Josh Klontz \cite jklontz | 55 | * \author Josh Klontz \cite jklontz |
| 57 | */ | 56 | */ |
| 58 | -class CascadeTransform : public UntrainableTransform | 57 | +class CascadeTransform : public UntrainableMetaTransform |
| 59 | { | 58 | { |
| 60 | Q_OBJECT | 59 | Q_OBJECT |
| 61 | Q_PROPERTY(QString model READ get_model WRITE set_model RESET reset_model STORED false) | 60 | Q_PROPERTY(QString model READ get_model WRITE set_model RESET reset_model STORED false) |
| 62 | Q_PROPERTY(int minSize READ get_minSize WRITE set_minSize RESET reset_minSize STORED false) | 61 | Q_PROPERTY(int minSize READ get_minSize WRITE set_minSize RESET reset_minSize STORED false) |
| 62 | + Q_PROPERTY(bool ROCMode READ get_ROCMode WRITE set_ROCMode RESET reset_ROCMode STORED false) | ||
| 63 | BR_PROPERTY(QString, model, "FrontalFace") | 63 | BR_PROPERTY(QString, model, "FrontalFace") |
| 64 | BR_PROPERTY(int, minSize, 64) | 64 | BR_PROPERTY(int, minSize, 64) |
| 65 | + BR_PROPERTY(bool, ROCMode, false) | ||
| 65 | 66 | ||
| 66 | Resource<CascadeClassifier> cascadeResource; | 67 | Resource<CascadeClassifier> cascadeResource; |
| 67 | 68 | ||
| @@ -72,18 +73,55 @@ class CascadeTransform : public UntrainableTransform | @@ -72,18 +73,55 @@ class CascadeTransform : public UntrainableTransform | ||
| 72 | 73 | ||
| 73 | void project(const Template &src, Template &dst) const | 74 | void project(const Template &src, Template &dst) const |
| 74 | { | 75 | { |
| 76 | + TemplateList temp; | ||
| 77 | + project(TemplateList() << src, temp); | ||
| 78 | + if (!temp.isEmpty()) dst = temp.first(); | ||
| 79 | + } | ||
| 80 | + | ||
| 81 | + void project(const TemplateList &src, TemplateList &dst) const | ||
| 82 | + { | ||
| 83 | + static const int rejectLevelWeight = 1000.0; | ||
| 84 | + static const int stageSumWeight = 1.0; | ||
| 85 | + | ||
| 75 | CascadeClassifier *cascade = cascadeResource.acquire(); | 86 | CascadeClassifier *cascade = cascadeResource.acquire(); |
| 76 | - vector<Rect> rects; | ||
| 77 | - cascade->detectMultiScale(src, rects, 1.2, 5, src.file.get<bool>("enrollAll", false) ? 0 : CV_HAAR_FIND_BIGGEST_OBJECT, Size(minSize, minSize)); | 87 | + |
| 88 | + foreach (const Template &t, src) { | ||
| 89 | + const bool enrollAll = t.file.getBool("enrollAll"); | ||
| 90 | + | ||
| 91 | + for (int i=0; i<t.size(); i++) { | ||
| 92 | + const Mat &m = t[i]; | ||
| 93 | + vector<Rect> rects; | ||
| 94 | + vector<int> rejectLevels; | ||
| 95 | + vector<double> levelWeights; | ||
| 96 | + if (ROCMode) cascade->detectMultiScale(m, rects, rejectLevels, levelWeights, 1.2, 5, (enrollAll ? 0 : CV_HAAR_FIND_BIGGEST_OBJECT) | CV_HAAR_SCALE_IMAGE, Size(minSize, minSize), Size(), true); | ||
| 97 | + else cascade->detectMultiScale(m, rects, 1.2, 5, enrollAll ? 0 : CV_HAAR_FIND_BIGGEST_OBJECT, Size(minSize, minSize)); | ||
| 98 | + | ||
| 99 | + if (!enrollAll && rects.empty()) | ||
| 100 | + rects.push_back(Rect(0, 0, m.cols, m.rows)); | ||
| 101 | + | ||
| 102 | + for (size_t j=0; j<rects.size(); j++) { | ||
| 103 | + dst.append(Template(t.file, m)); | ||
| 104 | + if (rejectLevels.size() > j) | ||
| 105 | + dst.last().file.set("Confidence", rejectLevels[j]*rejectLevelWeight + levelWeights[j]*stageSumWeight); | ||
| 106 | + dst.last().file.appendRect(OpenCVUtils::fromRect(rects[j])); | ||
| 107 | + } | ||
| 108 | + } | ||
| 109 | + } | ||
| 110 | + | ||
| 78 | cascadeResource.release(cascade); | 111 | cascadeResource.release(cascade); |
| 112 | + } | ||
| 79 | 113 | ||
| 80 | - if (!src.file.get<bool>("enrollAll", false) && rects.empty()) | ||
| 81 | - rects.push_back(Rect(0, 0, src.m().cols, src.m().rows)); | 114 | + // TODO: Remove this code when ready to break binary compatibility |
| 115 | + void store(QDataStream &stream) const | ||
| 116 | + { | ||
| 117 | + int size = 1; | ||
| 118 | + stream << size; | ||
| 119 | + } | ||
| 82 | 120 | ||
| 83 | - foreach (const Rect &rect, rects) { | ||
| 84 | - dst += src; | ||
| 85 | - dst.file.appendRect(OpenCVUtils::fromRect(rect)); | ||
| 86 | - } | 121 | + void load(QDataStream &stream) |
| 122 | + { | ||
| 123 | + int size; | ||
| 124 | + stream >> size; | ||
| 87 | } | 125 | } |
| 88 | }; | 126 | }; |
| 89 | 127 |