Commit e69f6ae399efcec931cc7b217d05b66a881117c0

Authored by Josh Klontz
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 49 }
50 50 };
51 51  
52   -
53 52 /*!
54 53 * \ingroup transforms
55 54 * \brief Wraps OpenCV cascade classifier
56 55 * \author Josh Klontz \cite jklontz
57 56 */
58   -class CascadeTransform : public UntrainableTransform
  57 +class CascadeTransform : public UntrainableMetaTransform
59 58 {
60 59 Q_OBJECT
61 60 Q_PROPERTY(QString model READ get_model WRITE set_model RESET reset_model STORED false)
62 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 63 BR_PROPERTY(QString, model, "FrontalFace")
64 64 BR_PROPERTY(int, minSize, 64)
  65 + BR_PROPERTY(bool, ROCMode, false)
65 66  
66 67 Resource<CascadeClassifier> cascadeResource;
67 68  
... ... @@ -72,18 +73,55 @@ class CascadeTransform : public UntrainableTransform
72 73  
73 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 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 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  
... ...