diff --git a/openbr/core/boost.cpp b/openbr/core/boost.cpp index 6a76366..ec3ed1b 100644 --- a/openbr/core/boost.cpp +++ b/openbr/core/boost.cpp @@ -806,38 +806,6 @@ CvDTreeNode* CascadeBoostTree::predict( int sampleIdx ) const return node; } -<<<<<<< HEAD - -static void writeRecursive(FileStorage &fs, CvDTreeNode *node, int maxCatCount) -{ - bool hasChildren = node->left ? true : false; - fs << "hasChildren" << hasChildren; - - if (!hasChildren) // Write the leaf value - fs << "value" << node->value; // value of the node. Only relevant for leaf nodes - else { // Write the splitting information and then the children - if (maxCatCount > 1) { - fs << "subset" << "[:"; - for (int i = 0; i < ((maxCatCount + 31) / 32); i++) - fs << node->split->subset[i]; // subset to split on (categorical features) - fs << "]"; - } else { - fs << "threshold" << node->split->ord.c; // threshold to split on (ordered features) - } - - fs << "feature_idx" << node->split->var_idx; // feature idx of node - - fs << "left" << "{"; writeRecursive(fs, node->left, maxCatCount); fs << "}"; // write left child - fs << "right" << "{"; writeRecursive(fs, node->right, maxCatCount); fs << "}"; // write right child - } -} - -void CascadeBoostTree::write(FileStorage &fs) -{ - fs << "{"; - writeRecursive(fs, root, ((CascadeBoostTrainData*)data)->featureEvaluator->getMaxCatCount()); - fs << "}"; -} /* static void readRecursive(const FileNode &fn, CvDTreeNode *node, CvDTreeTrainData *data) { @@ -881,8 +849,6 @@ void CascadeBoostTree::read(const FileNode &fn, CvBoost* _ensemble, CvDTreeTrain } */ -======= ->>>>>>> 4fab7f69ddc82d6ba40a73fc6233e3cc9871473e void CascadeBoostTree::split_node_data( CvDTreeNode* node ) { int n = node->sample_count, nl, nr, scount = data->sample_count; @@ -1138,11 +1104,7 @@ bool CascadeBoost::train( const FeatureEvaluator* _featureEvaluator, break; } -<<<<<<< HEAD classifiers.append(tree); -======= - trees.append(tree); ->>>>>>> 4fab7f69ddc82d6ba40a73fc6233e3cc9871473e cvSeqPush( weak, &tree ); update_weights( tree ); trim_weights(); @@ -1470,7 +1432,3 @@ bool CascadeBoost::isErrDesired() return falseAlarm <= maxFalseAlarm; } -<<<<<<< HEAD - -======= ->>>>>>> 4fab7f69ddc82d6ba40a73fc6233e3cc9871473e diff --git a/openbr/core/boost.h b/openbr/core/boost.h index 39fa827..7127f23 100644 --- a/openbr/core/boost.h +++ b/openbr/core/boost.h @@ -4,43 +4,6 @@ #include "ml.h" #include -#define CC_CASCADE_FILENAME "cascade.xml" -#define CC_PARAMS_FILENAME "params.xml" - -#define CC_CASCADE_PARAMS "cascadeParams" -#define CC_STAGE_TYPE "stageType" -#define CC_FEATURE_TYPE "featureType" -#define CC_HEIGHT "height" -#define CC_WIDTH "width" - -#define CC_STAGE_NUM "stageNum" -#define CC_STAGES "stages" -#define CC_STAGE_PARAMS "stageParams" - -#define CC_BOOST "BOOST" -#define CC_BOOST_TYPE "boostType" -#define CC_DISCRETE_BOOST "DAB" -#define CC_REAL_BOOST "RAB" -#define CC_LOGIT_BOOST "LB" -#define CC_GENTLE_BOOST "GAB" -#define CC_MINHITRATE "minHitRate" -#define CC_MAXFALSEALARM "maxFalseAlarm" -#define CC_TRIM_RATE "weightTrimRate" -#define CC_MAX_DEPTH "maxDeptrh" -#define CC_WEAK_COUNT "maxWeakCount" -#define CC_STAGE_THRESHOLD "stageThreshold" -#define CC_WEAK_CLASSIFIERS "weakClassifiers" -#define CC_INTERNAL_NODES "internalNodes" -#define CC_LEAF_VALUES "leafValues" - -#define CC_FEATURES "features" -#define CC_FEATURE_PARAMS "featureParams" -#define CC_MAX_CAT_COUNT "maxCatCount" -#define CC_FEATURE_SIZE "featSize" - -#define CC_LBP "LBP" -#define CC_RECT "rect" - #ifdef _WIN32 #define TIME( arg ) (((double) clock()) / CLOCKS_PER_SEC) #else @@ -125,22 +88,14 @@ public: virtual float predict( int sampleIdx, bool returnSum = false ) const; float getThreshold() const { return threshold; } -<<<<<<< HEAD - QList getClassifiers() const { return classifiers; } -======= - const QList getTrees() const { return trees; } ->>>>>>> 4fab7f69ddc82d6ba40a73fc6233e3cc9871473e + QList getClassifers() const { return classifiers; } protected: virtual bool set_params(const CvBoostParams& _params); virtual void update_weights(CvBoostTree* tree); virtual bool isErrDesired(); -<<<<<<< HEAD - QList classifiers; -======= - QList trees; ->>>>>>> 4fab7f69ddc82d6ba40a73fc6233e3cc9871473e + QList classifiers; float threshold; float minHitRate, maxFalseAlarm; diff --git a/openbr/core/cascade.cpp b/openbr/core/cascade.cpp index b5f7107..bf32e84 100644 --- a/openbr/core/cascade.cpp +++ b/openbr/core/cascade.cpp @@ -124,9 +124,10 @@ void br::groupRectangles(vector& rectList, vector& rejectLevels, vect static void loadRecursive(const FileNode &fn, _CascadeClassifier::Node *node, int maxCatCount) { bool hasChildren = (int)fn["hasChildren"]; - - if (hasChildren) { - if (maxCatCount > 1) { + if (!hasChildren) + node->value = (float)fn["value"]; + else { + if (maxCatCount > 0) { FileNode subset_fn = fn["subset"]; for (FileNodeIterator subset_it = subset_fn.begin(); subset_it != subset_fn.end(); ++subset_it) node->subset.append((int)*subset_it); @@ -134,14 +135,11 @@ static void loadRecursive(const FileNode &fn, _CascadeClassifier::Node *node, in node->threshold = (float)fn["threshold"]; } - node->featureIdx = (int)fn["feature_idx"]; + node->featureIdx = (int)fn["featureIdx"]; - node->left = new _CascadeClassifier::Node; + node->left = new _CascadeClassifier::Node; node->right = new _CascadeClassifier::Node; loadRecursive(fn["left"], node->left, maxCatCount); - node->right = new _CascadeClassifier::Node; loadRecursive(fn["right"], node->right, maxCatCount); - } else { - node->value = (float)fn["value"]; } } @@ -159,7 +157,6 @@ bool _CascadeClassifier::load(const string& filename) // load stages FileNode stages_fn = root["stages"]; - if( stages_fn.empty() ) return false; @@ -170,7 +167,6 @@ bool _CascadeClassifier::load(const string& filename) stage.threshold = (float)stage_fn["stageThreshold"] - THRESHOLD_EPS; FileNode nodes_fn = stage_fn["weakClassifiers"]; - if(nodes_fn.empty()) return false; diff --git a/openbr/plugins/classification/boostedforest.cpp b/openbr/plugins/classification/boostedforest.cpp index b16a361..88e06a3 100644 --- a/openbr/plugins/classification/boostedforest.cpp +++ b/openbr/plugins/classification/boostedforest.cpp @@ -1,6 +1,8 @@ #include #include +#define THRESHOLD_EPS 1e-5 + using namespace cv; namespace br @@ -8,63 +10,33 @@ namespace br struct Node { - Node() : left(NULL), right(NULL) {} - -<<<<<<< HEAD - float value; + float value; // for leaf nodes - float threshold; // For ordered features - QList subset; // For categorical features + float threshold; // for ordered features + QList subset; // for categorical features int featureIdx; -======= - int featureIdx; - float threshold; // for ordered features only - QList subset; // for categorical features only - float value; // for leaf nodes only ->>>>>>> 4fab7f69ddc82d6ba40a73fc6233e3cc9871473e - Node *left; - Node *right; + Node *left, *right; }; -<<<<<<< HEAD static void buildTreeRecursive(Node *node, const CvDTreeNode *cv_node, int maxCatCount) { - if (!cv_node->left) // Write the leaf value - node->value = cv_node->value; // value of the node. Only relevant for leaf nodes - else { // Write the splitting information and then the children - if (maxCatCount > 1) - for (int i = 0; i < ((maxCatCount + 31) / 32); i++) - node->subset.append(cv_node->split->subset[i]); // subset to split on (categorical features) + if (!cv_node->left) { + node->value = cv_node->value; + + node->left = node->right = NULL; + } else { + if (maxCatCount > 0) + for (int i = 0; i < (maxCatCount + 31)/32; i++) + node->subset.append(cv_node->split->subset[i]); else - node->threshold = cv_node->split->ord.c; // threshold to split on (ordered features) + node->threshold = cv_node->split->ord.c; - node->featureIdx = cv_node->split->var_idx; // feature idx of node + node->featureIdx = cv_node->split->var_idx; - node->left = new Node; + node->left = new Node; node->right = new Node; buildTreeRecursive(node->left, cv_node->left, maxCatCount); - node->right = new Node; buildTreeRecursive(node->right, cv_node->right, maxCatCount); -======= -static void buildTreeRecursive(Node *node, const CvDTreeNode *tree_node, int maxCatCount) -{ - if (tree_node->left) { - if (maxCatCount > 1) { - for (int i = 0; i < (maxCatCount + 31)/32; i++) - node->subset.append(tree_node->split->subset[i]); - } else { - node->threshold = tree_node->split->ord.c; - } - - node->featureIdx = tree_node->split->var_idx; - - node->left = new Node; - buildTreeRecursive(node->left, tree_node->left, maxCatCount); - node->right = new Node; - buildTreeRecursive(node->right, tree_node->right, maxCatCount); - } else { - node->value = tree_node->value; ->>>>>>> 4fab7f69ddc82d6ba40a73fc6233e3cc9871473e } } @@ -73,58 +45,25 @@ static void writeRecursive(FileStorage &fs, const Node *node, int maxCatCount) bool hasChildren = node->left ? true : false; fs << "hasChildren" << hasChildren; - if (!hasChildren) // Write the leaf value -<<<<<<< HEAD - fs << "value" << node->value; // value of the node. Only relevant for leaf nodes - else { // Write the splitting information and then the children - if (maxCatCount > 1) { - fs << "subset" << "[:"; -======= - fs << "value" << node->value; // value of the node. - else { // Write the splitting information and then the children - if (maxCatCount > 1) { + if (!hasChildren) + fs << "value" << node->value; + else { + if (maxCatCount > 0) { fs << "subset" << "["; ->>>>>>> 4fab7f69ddc82d6ba40a73fc6233e3cc9871473e - for (int i = 0; i < ((maxCatCount + 31) / 32); i++) - fs << node->subset[i]; // subset to split on (categorical features) + for (int i = 0; i < (maxCatCount + 31)/32; i++) + fs << node->subset[i]; fs << "]"; } else { - fs << "threshold" << node->threshold; // threshold to split on (ordered features) - } - - fs << "feature_idx" << node->featureIdx; // feature idx of node - - fs << "left" << "{"; writeRecursive(fs, node->left, maxCatCount); fs << "}"; // write left child - fs << "right" << "{"; writeRecursive(fs, node->right, maxCatCount); fs << "}"; // write right child - } -} - -<<<<<<< HEAD -======= -static void readRecursive(const FileNode &fn, Node *node, int maxCatCount) -{ - bool hasChildren = (int)fn["hasChildren"]; - if (!hasChildren) { - node->value = (float)fn["value"]; - } else { - if (maxCatCount > 1) { - FileNode subset_fn = fn["subset"]; - for (FileNodeIterator subset_it = subset_fn.begin(); subset_it != subset_fn.end(); ++subset_it) - node->subset.append((int)*subset_it); - } else { - node->threshold = (float)fn["threshold"]; + fs << "threshold" << node->threshold; } - node->featureIdx = (int)fn["feature_idx"]; + fs << "featureIdx" << node->featureIdx; - node->left = new Node; - readRecursive(fn["left"], node->left, maxCatCount); - node->right = new Node; - readRecursive(fn["right"], node->right, maxCatCount); + fs << "left" << "{"; writeRecursive(fs, node->left, maxCatCount); fs << "}"; + fs << "right" << "{"; writeRecursive(fs, node->right, maxCatCount); fs << "}"; } } ->>>>>>> 4fab7f69ddc82d6ba40a73fc6233e3cc9871473e class BoostedForestClassifier : public Classifier { Q_OBJECT @@ -143,7 +82,7 @@ class BoostedForestClassifier : public Classifier BR_PROPERTY(int, maxDepth, 1) BR_PROPERTY(int, maxWeakCount, 100) - QList weakClassifiers; + QList classifiers; float threshold; void train(const QList &images, const QList &labels) @@ -157,65 +96,39 @@ class BoostedForestClassifier : public Classifier featureEvaluator.setImage(images[i], labels[i], i); CascadeBoost boost; - boost.train(&featureEvaluator, images.size(), 2048, 2048, params); -<<<<<<< HEAD - - threshold = boost.getThreshold(); - - foreach (const CvBoostTree *tree, boost.getClassifiers()) { -======= + boost.train(&featureEvaluator, images.size(), 1024, 1024, params); - // Convert into simpler, cleaner cascade after training threshold = boost.getThreshold(); - foreach (const CvBoostTree *tree, boost.getTrees()) { ->>>>>>> 4fab7f69ddc82d6ba40a73fc6233e3cc9871473e + foreach (const CvBoostTree *classifier, boost.getClassifers()) { Node *root = new Node; - buildTreeRecursive(root, tree->get_root(), representation->maxCatCount()); - weakClassifiers.append(root); + buildTreeRecursive(root, classifier->get_root(), representation->maxCatCount()); + classifiers.append(root); } } - float classify(const Mat &image) const + float classify(const Mat &_image) const { -<<<<<<< HEAD - float sum = 0; - foreach (const Node *root, weakClassifiers) { - const Node *node = root; - - while (node->left) { - if (representation->maxCatCount() > 1) { - int c = (int)representation->evaluate(image, node->featureIdx); - node = (node->subset[c >> 5] & (1 << (c & 31))) ? node->left : node->right; - } else { - float val = representation->evaluate(image, node->featureIdx); -======= - Mat pp; - representation->preprocess(image, pp); + Mat image; + representation->preprocess(_image, image); float sum = 0; + for (int i = 0; i < classifiers.size(); i++) { + Node *node = classifiers[i]; - foreach (const Node *node, weakClassifiers) { while (node->left) { if (representation->maxCatCount() > 1) { - int c = (int)representation->evaluate(pp, node->featureIdx); - node = (node->subset[c >> 5] & (1 << (c & 31))) ? node->left : node->right; + int c = (int)representation->evaluate(image, node->featureIdx); + node = (2*((node->subset[c >> 5] & (1 << (c & 31))) == 0) - 1) < 0 ? node->left : node->right; } else { - double val = representation->evaluate(pp, node->featureIdx); ->>>>>>> 4fab7f69ddc82d6ba40a73fc6233e3cc9871473e - node = val < node->threshold ? node->left : node->right; + double val = representation->evaluate(image, node->featureIdx); + node = val <= node->threshold ? node->left : node->right; } } sum += node->value; } -<<<<<<< HEAD - return sum < threshold - FLT_EPSILON ? 0.0 : 1.0; -======= - - if (sum < threshold) - return 0.0f; //-std::abs(sum); - return 1.0f; //std::abs(sum); ->>>>>>> 4fab7f69ddc82d6ba40a73fc6233e3cc9871473e + + return sum < threshold - THRESHOLD_EPS ? 0.0f : 1.0f; } int numFeatures() const @@ -235,38 +148,15 @@ class BoostedForestClassifier : public Classifier void write(FileStorage &fs) const { -<<<<<<< HEAD - fs << "weakCount" << weakClassifiers.size(); -======= - fs << "numWeak" << weakClassifiers.size(); ->>>>>>> 4fab7f69ddc82d6ba40a73fc6233e3cc9871473e fs << "stageThreshold" << threshold; + fs << "weakSize" << classifiers.size(); fs << "weakClassifiers" << "["; - foreach (const Node *root, weakClassifiers) { + foreach (const Node *root, classifiers) { fs << "{"; writeRecursive(fs, root, representation->maxCatCount()); fs << "}"; } fs << "]"; -<<<<<<< HEAD -======= - } - - void read(const FileNode &node) - { - weakClassifiers.reserve((int)node["numWeak"]); - threshold = (float)node["stageThreshold"]; - - FileNode weaks_fn = node["weakClassifiers"]; - for (FileNodeIterator weaks_it = weaks_fn.begin(); weaks_it != weaks_fn.end(); ++weaks_it) { - FileNode weak_fn = *weaks_it; - - Node *root = new Node; - readRecursive(weak_fn, root, representation->maxCatCount()); - - weakClassifiers.append(root); - } ->>>>>>> 4fab7f69ddc82d6ba40a73fc6233e3cc9871473e } }; diff --git a/openbr/plugins/classification/cascade.cpp b/openbr/plugins/classification/cascade.cpp index 5e2b520..da35269 100644 --- a/openbr/plugins/classification/cascade.cpp +++ b/openbr/plugins/classification/cascade.cpp @@ -1,7 +1,6 @@ #include #include -#include using namespace cv; @@ -112,14 +111,12 @@ class CascadeClassifier : public Classifier Q_PROPERTY(int numPos READ get_numPos WRITE set_numPos RESET reset_numPos STORED false) Q_PROPERTY(int numNegs READ get_numNegs WRITE set_numNegs RESET reset_numNegs STORED false) Q_PROPERTY(float maxFAR READ get_maxFAR WRITE set_maxFAR RESET reset_maxFAR STORED false) - Q_PROPERTY(bool ROCMode READ get_ROCMode WRITE set_ROCMode RESET reset_ROCMode STORED false) BR_PROPERTY(QString, stageDescription, "") BR_PROPERTY(int, numStages, 20) BR_PROPERTY(int, numPos, 1000) BR_PROPERTY(int, numNegs, 1000) BR_PROPERTY(float, maxFAR, pow(0.5, numStages)) - BR_PROPERTY(bool, ROCMode, false) QList stages; @@ -158,21 +155,9 @@ class CascadeClassifier : public Classifier float classify(const Mat &image) const { foreach (const Classifier *stage, stages) - if (stage->classify(image) == 0) + if (stage->classify(image) == 0.0f) return 0.0f; return 1.0f; - - /*if (stages.size() == 0) // special case for empty cascade - return 1.0f; - - float result = 0.0f; - for (int stageIdx = 0; stageIdx < stages.size(); stageIdx++) { - result = stages[stageIdx]->classify(image); - - if (result < 0) - return stageIdx > (stages.size() - 4) ? stageIdx * result : 0.0f; - } - return std::abs(stages.size() * result);*/ } int numFeatures() const @@ -192,13 +177,7 @@ class CascadeClassifier : public Classifier void write(FileStorage &fs) const { -<<<<<<< HEAD - fs << "stageCount" << stages.size(); - fs << "stages" << "["; -======= - fs << CC_STAGES << "["; ->>>>>>> 4fab7f69ddc82d6ba40a73fc6233e3cc9871473e foreach (const Classifier *stage, stages) { fs << "{"; stage->write(fs); @@ -217,7 +196,7 @@ private: if (!imgHandler.getPos(pos)) qFatal("Cannot get another positive sample!"); - if (classify(pos) > 0.0f) { + if (classify(pos) == 1.0f) { printf("POS current samples: %d\r", images.size()); images.append(pos); labels.append(1.0f); @@ -233,7 +212,7 @@ private: if (!imgHandler.getNeg(neg)) qFatal("Cannot get another negative sample!"); - if (classify(neg) > 0.0f) { + if (classify(neg) == 1.0f) { printf("NEG current samples: %d\r", images.size() - posCount); images.append(neg); labels.append(0.0f); diff --git a/openbr/plugins/imgproc/slidingwindow.cpp b/openbr/plugins/imgproc/slidingwindow.cpp index dd8a9fe..6ef2aef 100644 --- a/openbr/plugins/imgproc/slidingwindow.cpp +++ b/openbr/plugins/imgproc/slidingwindow.cpp @@ -21,8 +21,6 @@ #include #include -#include -#include using namespace cv; @@ -41,23 +39,11 @@ class SlidingWindowTransform : public Transform Q_OBJECT Q_PROPERTY(br::Classifier *classifier READ get_classifier WRITE set_classifier RESET reset_classifier STORED false) - Q_PROPERTY(int minSize READ get_minSize WRITE set_minSize RESET reset_minSize STORED false) - Q_PROPERTY(int maxSize READ get_maxSize WRITE set_maxSize RESET reset_maxSize STORED false) - Q_PROPERTY(float scaleFactor READ get_scaleFactor WRITE set_scaleFactor RESET reset_scaleFactor STORED false) - Q_PROPERTY(int minNeighbors READ get_minNeighbors WRITE set_minNeighbors RESET reset_minNeighbors STORED false) - Q_PROPERTY(float eps READ get_eps WRITE set_eps RESET reset_eps STORED false) - Q_PROPERTY(QString cascadeDir READ get_cascadeDir WRITE set_cascadeDir RESET reset_cascadeDir STORED false) Q_PROPERTY(QString vecFile READ get_vecFile WRITE set_vecFile RESET reset_vecFile STORED false) Q_PROPERTY(QString negFile READ get_negFile WRITE set_negFile RESET reset_negFile STORED false) BR_PROPERTY(br::Classifier *, classifier, NULL) - BR_PROPERTY(int, minSize, 24) - BR_PROPERTY(int, maxSize, -1) - BR_PROPERTY(float, scaleFactor, 1.2) - BR_PROPERTY(int, minNeighbors, 5) - BR_PROPERTY(float, eps, 0.2) - BR_PROPERTY(QString, cascadeDir, "") BR_PROPERTY(QString, vecFile, "vec.vec") BR_PROPERTY(QString, negFile, "neg.txt") @@ -135,11 +121,6 @@ class SlidingWindowTransform : public Transform return negs; } - void init() - { - cascadeDir = Globals->sdkPath + "/share/openbr/models/openbrcascades/" + cascadeDir; - } - void train(const TemplateList &_data) { (void)_data; @@ -159,109 +140,34 @@ class SlidingWindowTransform : public Transform } classifier->train(images, labels); + } + + void project(const Template &src, Template &dst) const + { + (void)src; (void)dst; + } + + void load(QDataStream &stream) + { + (void) stream; + return; + } - // save the cascade - std::string filename = cascadeDir.toStdString() + "/cascade.xml"; - FileStorage fs(filename, FileStorage::WRITE ); + void store(QDataStream &stream) const + { + (void) stream; + QString filename = Globals->sdkPath + "/share/openbr/models/openbrcascades/" + cascadeDir + "/cascade.xml"; + FileStorage fs(filename.toStdString(), FileStorage::WRITE); if ( !fs.isOpened() ) return; - fs << FileStorage::getDefaultObjectName(filename) << "{"; + fs << FileStorage::getDefaultObjectName(filename.toStdString()) << "{"; classifier->write(fs); fs << "}"; } - - void project(const Template &src, Template &dst) const - { - TemplateList temp; - project(TemplateList() << src, temp); - if (!temp.isEmpty()) dst = temp.first(); - } - - void project(const TemplateList &src, TemplateList &dst) const - { - foreach (const Template &t, src) { - const bool enrollAll = t.file.getBool("enrollAll"); - - // Mirror the behavior of ExpandTransform in the special case - // of an empty template. - if (t.empty() && !enrollAll) { - dst.append(t); - continue; - } - - for (int i = 0; i < t.size(); i++) { - Mat image; - OpenCVUtils::cvtUChar(t[i], image); - - std::vector rects; - std::vector rejectLevels; - std::vector levelWeights; - - Size minObjectSize(minSize, minSize); - Size maxObjectSize(maxSize, maxSize); - if (maxObjectSize.height == 0 || maxObjectSize.width == 0) - maxObjectSize = image.size(); - - Mat imageBuffer(image.rows + 1, image.cols + 1, CV_8U); - - for (double factor = 1; ; factor *= scaleFactor) { - Size originalWindowSize = classifier->windowSize(); - - Size windowSize(cvRound(originalWindowSize.width*factor), cvRound(originalWindowSize.height*factor) ); - Size scaledImageSize(cvRound(image.cols/factor ), cvRound(image.rows/factor)); - Size processingRectSize(scaledImageSize.width - originalWindowSize.width, scaledImageSize.height - originalWindowSize.height); - - if (processingRectSize.width <= 0 || processingRectSize.height <= 0) - break; - if (windowSize.width > maxObjectSize.width || windowSize.height > maxObjectSize.height) - break; - if (windowSize.width < minObjectSize.width || windowSize.height < minObjectSize.height) - continue; - - Mat scaledImage(scaledImageSize, CV_8U, imageBuffer.data); - resize(image, scaledImage, scaledImageSize, 0, 0, CV_INTER_LINEAR); - - int yStep = factor > 2. ? 1 : 2; - for (int y = 0; y < processingRectSize.height; y += yStep) { - for (int x = 0; x < processingRectSize.width; x += yStep) { - Mat window = scaledImage(Rect(Point(x, y), classifier->windowSize())).clone(); - - float result = classifier->classify(window); - - if (result > 0) { - rects.push_back(Rect(cvRound(x*factor), cvRound(y*factor), windowSize.width, windowSize.height)); - rejectLevels.push_back(1); - levelWeights.push_back(result); - } - if (result == 0) - x += yStep; - } - } - } - - groupRectangles(rects, rejectLevels, levelWeights, minNeighbors, eps); - - if (!enrollAll && rects.empty()) - rects.push_back(Rect(0, 0, image.cols, image.rows)); - - for (size_t j = 0; j < rects.size(); j++) { - Template u(t.file, image); - if (rejectLevels.size() > j) - u.file.set("Confidence", rejectLevels[j]*levelWeights[j]); - else - u.file.set("Confidence", 1); - const QRectF rect = OpenCVUtils::fromRect(rects[j]); - u.file.appendRect(rect); - u.file.set("Face", rect); - dst.append(u); - } - } - } - } }; BR_REGISTER(Transform, SlidingWindowTransform) diff --git a/openbr/plugins/representation/mblbp.cpp b/openbr/plugins/representation/mblbp.cpp index 66d8137..be74148 100644 --- a/openbr/plugins/representation/mblbp.cpp +++ b/openbr/plugins/representation/mblbp.cpp @@ -58,6 +58,7 @@ class MBLBPRepresentation : public Representation return result; } + void write(FileStorage &fs, const Mat &featureMap); int numFeatures() const { return features.size(); } Size preWindowSize() const { return Size(winWidth, winHeight); } Size postWindowSize() const { return Size(winWidth + 1, winHeight + 1); } @@ -78,6 +79,20 @@ class MBLBPRepresentation : public Representation BR_REGISTER(Representation, MBLBPRepresentation) +void MBLBPRepresentation::write(FileStorage &fs, const Mat &featureMap) +{ + fs << "features" << "["; + const Mat_& featureMap_ = (const Mat_&)featureMap; + for ( int fi = 0; fi < featureMap.cols; fi++ ) + if ( featureMap_(0, fi) >= 0 ) + { + fs << "{"; + features[fi].write( fs ); + fs << "}"; + } + fs << "]"; +} + MBLBPRepresentation::Feature::Feature( int offset, int x, int y, int _blockWidth, int _blockHeight ) { Rect tr = rect = cvRect(x, y, _blockWidth, _blockHeight);