Commit 7a2db13ce795e7cca4c993c57d3ed3ca0b46c0df
1 parent
98249fb4
No regression. Steps towards I/O.
Showing
7 changed files
with
89 additions
and
390 deletions
openbr/core/boost.cpp
| @@ -806,38 +806,6 @@ CvDTreeNode* CascadeBoostTree::predict( int sampleIdx ) const | @@ -806,38 +806,6 @@ CvDTreeNode* CascadeBoostTree::predict( int sampleIdx ) const | ||
| 806 | return node; | 806 | return node; |
| 807 | } | 807 | } |
| 808 | 808 | ||
| 809 | -<<<<<<< HEAD | ||
| 810 | - | ||
| 811 | -static void writeRecursive(FileStorage &fs, CvDTreeNode *node, int maxCatCount) | ||
| 812 | -{ | ||
| 813 | - bool hasChildren = node->left ? true : false; | ||
| 814 | - fs << "hasChildren" << hasChildren; | ||
| 815 | - | ||
| 816 | - if (!hasChildren) // Write the leaf value | ||
| 817 | - fs << "value" << node->value; // value of the node. Only relevant for leaf nodes | ||
| 818 | - else { // Write the splitting information and then the children | ||
| 819 | - if (maxCatCount > 1) { | ||
| 820 | - fs << "subset" << "[:"; | ||
| 821 | - for (int i = 0; i < ((maxCatCount + 31) / 32); i++) | ||
| 822 | - fs << node->split->subset[i]; // subset to split on (categorical features) | ||
| 823 | - fs << "]"; | ||
| 824 | - } else { | ||
| 825 | - fs << "threshold" << node->split->ord.c; // threshold to split on (ordered features) | ||
| 826 | - } | ||
| 827 | - | ||
| 828 | - fs << "feature_idx" << node->split->var_idx; // feature idx of node | ||
| 829 | - | ||
| 830 | - fs << "left" << "{"; writeRecursive(fs, node->left, maxCatCount); fs << "}"; // write left child | ||
| 831 | - fs << "right" << "{"; writeRecursive(fs, node->right, maxCatCount); fs << "}"; // write right child | ||
| 832 | - } | ||
| 833 | -} | ||
| 834 | - | ||
| 835 | -void CascadeBoostTree::write(FileStorage &fs) | ||
| 836 | -{ | ||
| 837 | - fs << "{"; | ||
| 838 | - writeRecursive(fs, root, ((CascadeBoostTrainData*)data)->featureEvaluator->getMaxCatCount()); | ||
| 839 | - fs << "}"; | ||
| 840 | -} | ||
| 841 | /* | 809 | /* |
| 842 | static void readRecursive(const FileNode &fn, CvDTreeNode *node, CvDTreeTrainData *data) | 810 | static void readRecursive(const FileNode &fn, CvDTreeNode *node, CvDTreeTrainData *data) |
| 843 | { | 811 | { |
| @@ -881,8 +849,6 @@ void CascadeBoostTree::read(const FileNode &fn, CvBoost* _ensemble, CvDTreeTrain | @@ -881,8 +849,6 @@ void CascadeBoostTree::read(const FileNode &fn, CvBoost* _ensemble, CvDTreeTrain | ||
| 881 | } | 849 | } |
| 882 | */ | 850 | */ |
| 883 | 851 | ||
| 884 | -======= | ||
| 885 | ->>>>>>> 4fab7f69ddc82d6ba40a73fc6233e3cc9871473e | ||
| 886 | void CascadeBoostTree::split_node_data( CvDTreeNode* node ) | 852 | void CascadeBoostTree::split_node_data( CvDTreeNode* node ) |
| 887 | { | 853 | { |
| 888 | int n = node->sample_count, nl, nr, scount = data->sample_count; | 854 | int n = node->sample_count, nl, nr, scount = data->sample_count; |
| @@ -1138,11 +1104,7 @@ bool CascadeBoost::train( const FeatureEvaluator* _featureEvaluator, | @@ -1138,11 +1104,7 @@ bool CascadeBoost::train( const FeatureEvaluator* _featureEvaluator, | ||
| 1138 | break; | 1104 | break; |
| 1139 | } | 1105 | } |
| 1140 | 1106 | ||
| 1141 | -<<<<<<< HEAD | ||
| 1142 | classifiers.append(tree); | 1107 | classifiers.append(tree); |
| 1143 | -======= | ||
| 1144 | - trees.append(tree); | ||
| 1145 | ->>>>>>> 4fab7f69ddc82d6ba40a73fc6233e3cc9871473e | ||
| 1146 | cvSeqPush( weak, &tree ); | 1108 | cvSeqPush( weak, &tree ); |
| 1147 | update_weights( tree ); | 1109 | update_weights( tree ); |
| 1148 | trim_weights(); | 1110 | trim_weights(); |
| @@ -1470,7 +1432,3 @@ bool CascadeBoost::isErrDesired() | @@ -1470,7 +1432,3 @@ bool CascadeBoost::isErrDesired() | ||
| 1470 | 1432 | ||
| 1471 | return falseAlarm <= maxFalseAlarm; | 1433 | return falseAlarm <= maxFalseAlarm; |
| 1472 | } | 1434 | } |
| 1473 | -<<<<<<< HEAD | ||
| 1474 | - | ||
| 1475 | -======= | ||
| 1476 | ->>>>>>> 4fab7f69ddc82d6ba40a73fc6233e3cc9871473e |
openbr/core/boost.h
| @@ -4,43 +4,6 @@ | @@ -4,43 +4,6 @@ | ||
| 4 | #include "ml.h" | 4 | #include "ml.h" |
| 5 | #include <openbr/openbr_plugin.h> | 5 | #include <openbr/openbr_plugin.h> |
| 6 | 6 | ||
| 7 | -#define CC_CASCADE_FILENAME "cascade.xml" | ||
| 8 | -#define CC_PARAMS_FILENAME "params.xml" | ||
| 9 | - | ||
| 10 | -#define CC_CASCADE_PARAMS "cascadeParams" | ||
| 11 | -#define CC_STAGE_TYPE "stageType" | ||
| 12 | -#define CC_FEATURE_TYPE "featureType" | ||
| 13 | -#define CC_HEIGHT "height" | ||
| 14 | -#define CC_WIDTH "width" | ||
| 15 | - | ||
| 16 | -#define CC_STAGE_NUM "stageNum" | ||
| 17 | -#define CC_STAGES "stages" | ||
| 18 | -#define CC_STAGE_PARAMS "stageParams" | ||
| 19 | - | ||
| 20 | -#define CC_BOOST "BOOST" | ||
| 21 | -#define CC_BOOST_TYPE "boostType" | ||
| 22 | -#define CC_DISCRETE_BOOST "DAB" | ||
| 23 | -#define CC_REAL_BOOST "RAB" | ||
| 24 | -#define CC_LOGIT_BOOST "LB" | ||
| 25 | -#define CC_GENTLE_BOOST "GAB" | ||
| 26 | -#define CC_MINHITRATE "minHitRate" | ||
| 27 | -#define CC_MAXFALSEALARM "maxFalseAlarm" | ||
| 28 | -#define CC_TRIM_RATE "weightTrimRate" | ||
| 29 | -#define CC_MAX_DEPTH "maxDeptrh" | ||
| 30 | -#define CC_WEAK_COUNT "maxWeakCount" | ||
| 31 | -#define CC_STAGE_THRESHOLD "stageThreshold" | ||
| 32 | -#define CC_WEAK_CLASSIFIERS "weakClassifiers" | ||
| 33 | -#define CC_INTERNAL_NODES "internalNodes" | ||
| 34 | -#define CC_LEAF_VALUES "leafValues" | ||
| 35 | - | ||
| 36 | -#define CC_FEATURES "features" | ||
| 37 | -#define CC_FEATURE_PARAMS "featureParams" | ||
| 38 | -#define CC_MAX_CAT_COUNT "maxCatCount" | ||
| 39 | -#define CC_FEATURE_SIZE "featSize" | ||
| 40 | - | ||
| 41 | -#define CC_LBP "LBP" | ||
| 42 | -#define CC_RECT "rect" | ||
| 43 | - | ||
| 44 | #ifdef _WIN32 | 7 | #ifdef _WIN32 |
| 45 | #define TIME( arg ) (((double) clock()) / CLOCKS_PER_SEC) | 8 | #define TIME( arg ) (((double) clock()) / CLOCKS_PER_SEC) |
| 46 | #else | 9 | #else |
| @@ -125,22 +88,14 @@ public: | @@ -125,22 +88,14 @@ public: | ||
| 125 | virtual float predict( int sampleIdx, bool returnSum = false ) const; | 88 | virtual float predict( int sampleIdx, bool returnSum = false ) const; |
| 126 | 89 | ||
| 127 | float getThreshold() const { return threshold; } | 90 | float getThreshold() const { return threshold; } |
| 128 | -<<<<<<< HEAD | ||
| 129 | - QList<CvBoostTree*> getClassifiers() const { return classifiers; } | ||
| 130 | -======= | ||
| 131 | - const QList<CvBoostTree*> getTrees() const { return trees; } | ||
| 132 | ->>>>>>> 4fab7f69ddc82d6ba40a73fc6233e3cc9871473e | 91 | + QList<CvBoostTree *> getClassifers() const { return classifiers; } |
| 133 | 92 | ||
| 134 | protected: | 93 | protected: |
| 135 | virtual bool set_params(const CvBoostParams& _params); | 94 | virtual bool set_params(const CvBoostParams& _params); |
| 136 | virtual void update_weights(CvBoostTree* tree); | 95 | virtual void update_weights(CvBoostTree* tree); |
| 137 | virtual bool isErrDesired(); | 96 | virtual bool isErrDesired(); |
| 138 | 97 | ||
| 139 | -<<<<<<< HEAD | ||
| 140 | - QList<CvBoostTree*> classifiers; | ||
| 141 | -======= | ||
| 142 | - QList<CvBoostTree*> trees; | ||
| 143 | ->>>>>>> 4fab7f69ddc82d6ba40a73fc6233e3cc9871473e | 98 | + QList<CvBoostTree *> classifiers; |
| 144 | 99 | ||
| 145 | float threshold; | 100 | float threshold; |
| 146 | float minHitRate, maxFalseAlarm; | 101 | float minHitRate, maxFalseAlarm; |
openbr/core/cascade.cpp
| @@ -124,9 +124,10 @@ void br::groupRectangles(vector<Rect>& rectList, vector<int>& rejectLevels, vect | @@ -124,9 +124,10 @@ void br::groupRectangles(vector<Rect>& rectList, vector<int>& rejectLevels, vect | ||
| 124 | static void loadRecursive(const FileNode &fn, _CascadeClassifier::Node *node, int maxCatCount) | 124 | static void loadRecursive(const FileNode &fn, _CascadeClassifier::Node *node, int maxCatCount) |
| 125 | { | 125 | { |
| 126 | bool hasChildren = (int)fn["hasChildren"]; | 126 | bool hasChildren = (int)fn["hasChildren"]; |
| 127 | - | ||
| 128 | - if (hasChildren) { | ||
| 129 | - if (maxCatCount > 1) { | 127 | + if (!hasChildren) |
| 128 | + node->value = (float)fn["value"]; | ||
| 129 | + else { | ||
| 130 | + if (maxCatCount > 0) { | ||
| 130 | FileNode subset_fn = fn["subset"]; | 131 | FileNode subset_fn = fn["subset"]; |
| 131 | for (FileNodeIterator subset_it = subset_fn.begin(); subset_it != subset_fn.end(); ++subset_it) | 132 | for (FileNodeIterator subset_it = subset_fn.begin(); subset_it != subset_fn.end(); ++subset_it) |
| 132 | node->subset.append((int)*subset_it); | 133 | node->subset.append((int)*subset_it); |
| @@ -134,14 +135,11 @@ static void loadRecursive(const FileNode &fn, _CascadeClassifier::Node *node, in | @@ -134,14 +135,11 @@ static void loadRecursive(const FileNode &fn, _CascadeClassifier::Node *node, in | ||
| 134 | node->threshold = (float)fn["threshold"]; | 135 | node->threshold = (float)fn["threshold"]; |
| 135 | } | 136 | } |
| 136 | 137 | ||
| 137 | - node->featureIdx = (int)fn["feature_idx"]; | 138 | + node->featureIdx = (int)fn["featureIdx"]; |
| 138 | 139 | ||
| 139 | - node->left = new _CascadeClassifier::Node; | 140 | + node->left = new _CascadeClassifier::Node; node->right = new _CascadeClassifier::Node; |
| 140 | loadRecursive(fn["left"], node->left, maxCatCount); | 141 | loadRecursive(fn["left"], node->left, maxCatCount); |
| 141 | - node->right = new _CascadeClassifier::Node; | ||
| 142 | loadRecursive(fn["right"], node->right, maxCatCount); | 142 | loadRecursive(fn["right"], node->right, maxCatCount); |
| 143 | - } else { | ||
| 144 | - node->value = (float)fn["value"]; | ||
| 145 | } | 143 | } |
| 146 | } | 144 | } |
| 147 | 145 | ||
| @@ -159,7 +157,6 @@ bool _CascadeClassifier::load(const string& filename) | @@ -159,7 +157,6 @@ bool _CascadeClassifier::load(const string& filename) | ||
| 159 | 157 | ||
| 160 | // load stages | 158 | // load stages |
| 161 | FileNode stages_fn = root["stages"]; | 159 | FileNode stages_fn = root["stages"]; |
| 162 | - | ||
| 163 | if( stages_fn.empty() ) | 160 | if( stages_fn.empty() ) |
| 164 | return false; | 161 | return false; |
| 165 | 162 | ||
| @@ -170,7 +167,6 @@ bool _CascadeClassifier::load(const string& filename) | @@ -170,7 +167,6 @@ bool _CascadeClassifier::load(const string& filename) | ||
| 170 | stage.threshold = (float)stage_fn["stageThreshold"] - THRESHOLD_EPS; | 167 | stage.threshold = (float)stage_fn["stageThreshold"] - THRESHOLD_EPS; |
| 171 | 168 | ||
| 172 | FileNode nodes_fn = stage_fn["weakClassifiers"]; | 169 | FileNode nodes_fn = stage_fn["weakClassifiers"]; |
| 173 | - | ||
| 174 | if(nodes_fn.empty()) | 170 | if(nodes_fn.empty()) |
| 175 | return false; | 171 | return false; |
| 176 | 172 |
openbr/plugins/classification/boostedforest.cpp
| 1 | #include <openbr/plugins/openbr_internal.h> | 1 | #include <openbr/plugins/openbr_internal.h> |
| 2 | #include <openbr/core/boost.h> | 2 | #include <openbr/core/boost.h> |
| 3 | 3 | ||
| 4 | +#define THRESHOLD_EPS 1e-5 | ||
| 5 | + | ||
| 4 | using namespace cv; | 6 | using namespace cv; |
| 5 | 7 | ||
| 6 | namespace br | 8 | namespace br |
| @@ -8,63 +10,33 @@ namespace br | @@ -8,63 +10,33 @@ namespace br | ||
| 8 | 10 | ||
| 9 | struct Node | 11 | struct Node |
| 10 | { | 12 | { |
| 11 | - Node() : left(NULL), right(NULL) {} | ||
| 12 | - | ||
| 13 | -<<<<<<< HEAD | ||
| 14 | - float value; | 13 | + float value; // for leaf nodes |
| 15 | 14 | ||
| 16 | - float threshold; // For ordered features | ||
| 17 | - QList<int> subset; // For categorical features | 15 | + float threshold; // for ordered features |
| 16 | + QList<int> subset; // for categorical features | ||
| 18 | int featureIdx; | 17 | int featureIdx; |
| 19 | 18 | ||
| 20 | -======= | ||
| 21 | - int featureIdx; | ||
| 22 | - float threshold; // for ordered features only | ||
| 23 | - QList<int> subset; // for categorical features only | ||
| 24 | - float value; // for leaf nodes only | ||
| 25 | ->>>>>>> 4fab7f69ddc82d6ba40a73fc6233e3cc9871473e | ||
| 26 | - Node *left; | ||
| 27 | - Node *right; | 19 | + Node *left, *right; |
| 28 | }; | 20 | }; |
| 29 | 21 | ||
| 30 | -<<<<<<< HEAD | ||
| 31 | static void buildTreeRecursive(Node *node, const CvDTreeNode *cv_node, int maxCatCount) | 22 | static void buildTreeRecursive(Node *node, const CvDTreeNode *cv_node, int maxCatCount) |
| 32 | { | 23 | { |
| 33 | - if (!cv_node->left) // Write the leaf value | ||
| 34 | - node->value = cv_node->value; // value of the node. Only relevant for leaf nodes | ||
| 35 | - else { // Write the splitting information and then the children | ||
| 36 | - if (maxCatCount > 1) | ||
| 37 | - for (int i = 0; i < ((maxCatCount + 31) / 32); i++) | ||
| 38 | - node->subset.append(cv_node->split->subset[i]); // subset to split on (categorical features) | 24 | + if (!cv_node->left) { |
| 25 | + node->value = cv_node->value; | ||
| 26 | + | ||
| 27 | + node->left = node->right = NULL; | ||
| 28 | + } else { | ||
| 29 | + if (maxCatCount > 0) | ||
| 30 | + for (int i = 0; i < (maxCatCount + 31)/32; i++) | ||
| 31 | + node->subset.append(cv_node->split->subset[i]); | ||
| 39 | else | 32 | else |
| 40 | - node->threshold = cv_node->split->ord.c; // threshold to split on (ordered features) | 33 | + node->threshold = cv_node->split->ord.c; |
| 41 | 34 | ||
| 42 | - node->featureIdx = cv_node->split->var_idx; // feature idx of node | 35 | + node->featureIdx = cv_node->split->var_idx; |
| 43 | 36 | ||
| 44 | - node->left = new Node; | 37 | + node->left = new Node; node->right = new Node; |
| 45 | buildTreeRecursive(node->left, cv_node->left, maxCatCount); | 38 | buildTreeRecursive(node->left, cv_node->left, maxCatCount); |
| 46 | - node->right = new Node; | ||
| 47 | buildTreeRecursive(node->right, cv_node->right, maxCatCount); | 39 | buildTreeRecursive(node->right, cv_node->right, maxCatCount); |
| 48 | -======= | ||
| 49 | -static void buildTreeRecursive(Node *node, const CvDTreeNode *tree_node, int maxCatCount) | ||
| 50 | -{ | ||
| 51 | - if (tree_node->left) { | ||
| 52 | - if (maxCatCount > 1) { | ||
| 53 | - for (int i = 0; i < (maxCatCount + 31)/32; i++) | ||
| 54 | - node->subset.append(tree_node->split->subset[i]); | ||
| 55 | - } else { | ||
| 56 | - node->threshold = tree_node->split->ord.c; | ||
| 57 | - } | ||
| 58 | - | ||
| 59 | - node->featureIdx = tree_node->split->var_idx; | ||
| 60 | - | ||
| 61 | - node->left = new Node; | ||
| 62 | - buildTreeRecursive(node->left, tree_node->left, maxCatCount); | ||
| 63 | - node->right = new Node; | ||
| 64 | - buildTreeRecursive(node->right, tree_node->right, maxCatCount); | ||
| 65 | - } else { | ||
| 66 | - node->value = tree_node->value; | ||
| 67 | ->>>>>>> 4fab7f69ddc82d6ba40a73fc6233e3cc9871473e | ||
| 68 | } | 40 | } |
| 69 | } | 41 | } |
| 70 | 42 | ||
| @@ -73,58 +45,25 @@ static void writeRecursive(FileStorage &fs, const Node *node, int maxCatCount) | @@ -73,58 +45,25 @@ static void writeRecursive(FileStorage &fs, const Node *node, int maxCatCount) | ||
| 73 | bool hasChildren = node->left ? true : false; | 45 | bool hasChildren = node->left ? true : false; |
| 74 | fs << "hasChildren" << hasChildren; | 46 | fs << "hasChildren" << hasChildren; |
| 75 | 47 | ||
| 76 | - if (!hasChildren) // Write the leaf value | ||
| 77 | -<<<<<<< HEAD | ||
| 78 | - fs << "value" << node->value; // value of the node. Only relevant for leaf nodes | ||
| 79 | - else { // Write the splitting information and then the children | ||
| 80 | - if (maxCatCount > 1) { | ||
| 81 | - fs << "subset" << "[:"; | ||
| 82 | -======= | ||
| 83 | - fs << "value" << node->value; // value of the node. | ||
| 84 | - else { // Write the splitting information and then the children | ||
| 85 | - if (maxCatCount > 1) { | 48 | + if (!hasChildren) |
| 49 | + fs << "value" << node->value; | ||
| 50 | + else { | ||
| 51 | + if (maxCatCount > 0) { | ||
| 86 | fs << "subset" << "["; | 52 | fs << "subset" << "["; |
| 87 | ->>>>>>> 4fab7f69ddc82d6ba40a73fc6233e3cc9871473e | ||
| 88 | - for (int i = 0; i < ((maxCatCount + 31) / 32); i++) | ||
| 89 | - fs << node->subset[i]; // subset to split on (categorical features) | 53 | + for (int i = 0; i < (maxCatCount + 31)/32; i++) |
| 54 | + fs << node->subset[i]; | ||
| 90 | fs << "]"; | 55 | fs << "]"; |
| 91 | } else { | 56 | } else { |
| 92 | - fs << "threshold" << node->threshold; // threshold to split on (ordered features) | ||
| 93 | - } | ||
| 94 | - | ||
| 95 | - fs << "feature_idx" << node->featureIdx; // feature idx of node | ||
| 96 | - | ||
| 97 | - fs << "left" << "{"; writeRecursive(fs, node->left, maxCatCount); fs << "}"; // write left child | ||
| 98 | - fs << "right" << "{"; writeRecursive(fs, node->right, maxCatCount); fs << "}"; // write right child | ||
| 99 | - } | ||
| 100 | -} | ||
| 101 | - | ||
| 102 | -<<<<<<< HEAD | ||
| 103 | -======= | ||
| 104 | -static void readRecursive(const FileNode &fn, Node *node, int maxCatCount) | ||
| 105 | -{ | ||
| 106 | - bool hasChildren = (int)fn["hasChildren"]; | ||
| 107 | - if (!hasChildren) { | ||
| 108 | - node->value = (float)fn["value"]; | ||
| 109 | - } else { | ||
| 110 | - if (maxCatCount > 1) { | ||
| 111 | - FileNode subset_fn = fn["subset"]; | ||
| 112 | - for (FileNodeIterator subset_it = subset_fn.begin(); subset_it != subset_fn.end(); ++subset_it) | ||
| 113 | - node->subset.append((int)*subset_it); | ||
| 114 | - } else { | ||
| 115 | - node->threshold = (float)fn["threshold"]; | 57 | + fs << "threshold" << node->threshold; |
| 116 | } | 58 | } |
| 117 | 59 | ||
| 118 | - node->featureIdx = (int)fn["feature_idx"]; | 60 | + fs << "featureIdx" << node->featureIdx; |
| 119 | 61 | ||
| 120 | - node->left = new Node; | ||
| 121 | - readRecursive(fn["left"], node->left, maxCatCount); | ||
| 122 | - node->right = new Node; | ||
| 123 | - readRecursive(fn["right"], node->right, maxCatCount); | 62 | + fs << "left" << "{"; writeRecursive(fs, node->left, maxCatCount); fs << "}"; |
| 63 | + fs << "right" << "{"; writeRecursive(fs, node->right, maxCatCount); fs << "}"; | ||
| 124 | } | 64 | } |
| 125 | } | 65 | } |
| 126 | 66 | ||
| 127 | ->>>>>>> 4fab7f69ddc82d6ba40a73fc6233e3cc9871473e | ||
| 128 | class BoostedForestClassifier : public Classifier | 67 | class BoostedForestClassifier : public Classifier |
| 129 | { | 68 | { |
| 130 | Q_OBJECT | 69 | Q_OBJECT |
| @@ -143,7 +82,7 @@ class BoostedForestClassifier : public Classifier | @@ -143,7 +82,7 @@ class BoostedForestClassifier : public Classifier | ||
| 143 | BR_PROPERTY(int, maxDepth, 1) | 82 | BR_PROPERTY(int, maxDepth, 1) |
| 144 | BR_PROPERTY(int, maxWeakCount, 100) | 83 | BR_PROPERTY(int, maxWeakCount, 100) |
| 145 | 84 | ||
| 146 | - QList<Node*> weakClassifiers; | 85 | + QList<Node*> classifiers; |
| 147 | float threshold; | 86 | float threshold; |
| 148 | 87 | ||
| 149 | void train(const QList<Mat> &images, const QList<float> &labels) | 88 | void train(const QList<Mat> &images, const QList<float> &labels) |
| @@ -157,65 +96,39 @@ class BoostedForestClassifier : public Classifier | @@ -157,65 +96,39 @@ class BoostedForestClassifier : public Classifier | ||
| 157 | featureEvaluator.setImage(images[i], labels[i], i); | 96 | featureEvaluator.setImage(images[i], labels[i], i); |
| 158 | 97 | ||
| 159 | CascadeBoost boost; | 98 | CascadeBoost boost; |
| 160 | - boost.train(&featureEvaluator, images.size(), 2048, 2048, params); | ||
| 161 | -<<<<<<< HEAD | ||
| 162 | - | ||
| 163 | - threshold = boost.getThreshold(); | ||
| 164 | - | ||
| 165 | - foreach (const CvBoostTree *tree, boost.getClassifiers()) { | ||
| 166 | -======= | 99 | + boost.train(&featureEvaluator, images.size(), 1024, 1024, params); |
| 167 | 100 | ||
| 168 | - // Convert into simpler, cleaner cascade after training | ||
| 169 | threshold = boost.getThreshold(); | 101 | threshold = boost.getThreshold(); |
| 170 | 102 | ||
| 171 | - foreach (const CvBoostTree *tree, boost.getTrees()) { | ||
| 172 | ->>>>>>> 4fab7f69ddc82d6ba40a73fc6233e3cc9871473e | 103 | + foreach (const CvBoostTree *classifier, boost.getClassifers()) { |
| 173 | Node *root = new Node; | 104 | Node *root = new Node; |
| 174 | - buildTreeRecursive(root, tree->get_root(), representation->maxCatCount()); | ||
| 175 | - weakClassifiers.append(root); | 105 | + buildTreeRecursive(root, classifier->get_root(), representation->maxCatCount()); |
| 106 | + classifiers.append(root); | ||
| 176 | } | 107 | } |
| 177 | } | 108 | } |
| 178 | 109 | ||
| 179 | - float classify(const Mat &image) const | 110 | + float classify(const Mat &_image) const |
| 180 | { | 111 | { |
| 181 | -<<<<<<< HEAD | ||
| 182 | - float sum = 0; | ||
| 183 | - foreach (const Node *root, weakClassifiers) { | ||
| 184 | - const Node *node = root; | ||
| 185 | - | ||
| 186 | - while (node->left) { | ||
| 187 | - if (representation->maxCatCount() > 1) { | ||
| 188 | - int c = (int)representation->evaluate(image, node->featureIdx); | ||
| 189 | - node = (node->subset[c >> 5] & (1 << (c & 31))) ? node->left : node->right; | ||
| 190 | - } else { | ||
| 191 | - float val = representation->evaluate(image, node->featureIdx); | ||
| 192 | -======= | ||
| 193 | - Mat pp; | ||
| 194 | - representation->preprocess(image, pp); | 112 | + Mat image; |
| 113 | + representation->preprocess(_image, image); | ||
| 195 | 114 | ||
| 196 | float sum = 0; | 115 | float sum = 0; |
| 116 | + for (int i = 0; i < classifiers.size(); i++) { | ||
| 117 | + Node *node = classifiers[i]; | ||
| 197 | 118 | ||
| 198 | - foreach (const Node *node, weakClassifiers) { | ||
| 199 | while (node->left) { | 119 | while (node->left) { |
| 200 | if (representation->maxCatCount() > 1) { | 120 | if (representation->maxCatCount() > 1) { |
| 201 | - int c = (int)representation->evaluate(pp, node->featureIdx); | ||
| 202 | - node = (node->subset[c >> 5] & (1 << (c & 31))) ? node->left : node->right; | 121 | + int c = (int)representation->evaluate(image, node->featureIdx); |
| 122 | + node = (2*((node->subset[c >> 5] & (1 << (c & 31))) == 0) - 1) < 0 ? node->left : node->right; | ||
| 203 | } else { | 123 | } else { |
| 204 | - double val = representation->evaluate(pp, node->featureIdx); | ||
| 205 | ->>>>>>> 4fab7f69ddc82d6ba40a73fc6233e3cc9871473e | ||
| 206 | - node = val < node->threshold ? node->left : node->right; | 124 | + double val = representation->evaluate(image, node->featureIdx); |
| 125 | + node = val <= node->threshold ? node->left : node->right; | ||
| 207 | } | 126 | } |
| 208 | } | 127 | } |
| 209 | sum += node->value; | 128 | sum += node->value; |
| 210 | } | 129 | } |
| 211 | -<<<<<<< HEAD | ||
| 212 | - return sum < threshold - FLT_EPSILON ? 0.0 : 1.0; | ||
| 213 | -======= | ||
| 214 | - | ||
| 215 | - if (sum < threshold) | ||
| 216 | - return 0.0f; //-std::abs(sum); | ||
| 217 | - return 1.0f; //std::abs(sum); | ||
| 218 | ->>>>>>> 4fab7f69ddc82d6ba40a73fc6233e3cc9871473e | 130 | + |
| 131 | + return sum < threshold - THRESHOLD_EPS ? 0.0f : 1.0f; | ||
| 219 | } | 132 | } |
| 220 | 133 | ||
| 221 | int numFeatures() const | 134 | int numFeatures() const |
| @@ -235,38 +148,15 @@ class BoostedForestClassifier : public Classifier | @@ -235,38 +148,15 @@ class BoostedForestClassifier : public Classifier | ||
| 235 | 148 | ||
| 236 | void write(FileStorage &fs) const | 149 | void write(FileStorage &fs) const |
| 237 | { | 150 | { |
| 238 | -<<<<<<< HEAD | ||
| 239 | - fs << "weakCount" << weakClassifiers.size(); | ||
| 240 | -======= | ||
| 241 | - fs << "numWeak" << weakClassifiers.size(); | ||
| 242 | ->>>>>>> 4fab7f69ddc82d6ba40a73fc6233e3cc9871473e | ||
| 243 | fs << "stageThreshold" << threshold; | 151 | fs << "stageThreshold" << threshold; |
| 152 | + fs << "weakSize" << classifiers.size(); | ||
| 244 | fs << "weakClassifiers" << "["; | 153 | fs << "weakClassifiers" << "["; |
| 245 | - foreach (const Node *root, weakClassifiers) { | 154 | + foreach (const Node *root, classifiers) { |
| 246 | fs << "{"; | 155 | fs << "{"; |
| 247 | writeRecursive(fs, root, representation->maxCatCount()); | 156 | writeRecursive(fs, root, representation->maxCatCount()); |
| 248 | fs << "}"; | 157 | fs << "}"; |
| 249 | } | 158 | } |
| 250 | fs << "]"; | 159 | fs << "]"; |
| 251 | -<<<<<<< HEAD | ||
| 252 | -======= | ||
| 253 | - } | ||
| 254 | - | ||
| 255 | - void read(const FileNode &node) | ||
| 256 | - { | ||
| 257 | - weakClassifiers.reserve((int)node["numWeak"]); | ||
| 258 | - threshold = (float)node["stageThreshold"]; | ||
| 259 | - | ||
| 260 | - FileNode weaks_fn = node["weakClassifiers"]; | ||
| 261 | - for (FileNodeIterator weaks_it = weaks_fn.begin(); weaks_it != weaks_fn.end(); ++weaks_it) { | ||
| 262 | - FileNode weak_fn = *weaks_it; | ||
| 263 | - | ||
| 264 | - Node *root = new Node; | ||
| 265 | - readRecursive(weak_fn, root, representation->maxCatCount()); | ||
| 266 | - | ||
| 267 | - weakClassifiers.append(root); | ||
| 268 | - } | ||
| 269 | ->>>>>>> 4fab7f69ddc82d6ba40a73fc6233e3cc9871473e | ||
| 270 | } | 160 | } |
| 271 | }; | 161 | }; |
| 272 | 162 |
openbr/plugins/classification/cascade.cpp
| 1 | #include <opencv2/imgproc/imgproc.hpp> | 1 | #include <opencv2/imgproc/imgproc.hpp> |
| 2 | 2 | ||
| 3 | #include <openbr/plugins/openbr_internal.h> | 3 | #include <openbr/plugins/openbr_internal.h> |
| 4 | -#include <openbr/core/boost.h> | ||
| 5 | 4 | ||
| 6 | using namespace cv; | 5 | using namespace cv; |
| 7 | 6 | ||
| @@ -112,14 +111,12 @@ class CascadeClassifier : public Classifier | @@ -112,14 +111,12 @@ class CascadeClassifier : public Classifier | ||
| 112 | Q_PROPERTY(int numPos READ get_numPos WRITE set_numPos RESET reset_numPos STORED false) | 111 | Q_PROPERTY(int numPos READ get_numPos WRITE set_numPos RESET reset_numPos STORED false) |
| 113 | Q_PROPERTY(int numNegs READ get_numNegs WRITE set_numNegs RESET reset_numNegs STORED false) | 112 | Q_PROPERTY(int numNegs READ get_numNegs WRITE set_numNegs RESET reset_numNegs STORED false) |
| 114 | Q_PROPERTY(float maxFAR READ get_maxFAR WRITE set_maxFAR RESET reset_maxFAR STORED false) | 113 | Q_PROPERTY(float maxFAR READ get_maxFAR WRITE set_maxFAR RESET reset_maxFAR STORED false) |
| 115 | - Q_PROPERTY(bool ROCMode READ get_ROCMode WRITE set_ROCMode RESET reset_ROCMode STORED false) | ||
| 116 | 114 | ||
| 117 | BR_PROPERTY(QString, stageDescription, "") | 115 | BR_PROPERTY(QString, stageDescription, "") |
| 118 | BR_PROPERTY(int, numStages, 20) | 116 | BR_PROPERTY(int, numStages, 20) |
| 119 | BR_PROPERTY(int, numPos, 1000) | 117 | BR_PROPERTY(int, numPos, 1000) |
| 120 | BR_PROPERTY(int, numNegs, 1000) | 118 | BR_PROPERTY(int, numNegs, 1000) |
| 121 | BR_PROPERTY(float, maxFAR, pow(0.5, numStages)) | 119 | BR_PROPERTY(float, maxFAR, pow(0.5, numStages)) |
| 122 | - BR_PROPERTY(bool, ROCMode, false) | ||
| 123 | 120 | ||
| 124 | QList<Classifier *> stages; | 121 | QList<Classifier *> stages; |
| 125 | 122 | ||
| @@ -158,21 +155,9 @@ class CascadeClassifier : public Classifier | @@ -158,21 +155,9 @@ class CascadeClassifier : public Classifier | ||
| 158 | float classify(const Mat &image) const | 155 | float classify(const Mat &image) const |
| 159 | { | 156 | { |
| 160 | foreach (const Classifier *stage, stages) | 157 | foreach (const Classifier *stage, stages) |
| 161 | - if (stage->classify(image) == 0) | 158 | + if (stage->classify(image) == 0.0f) |
| 162 | return 0.0f; | 159 | return 0.0f; |
| 163 | return 1.0f; | 160 | return 1.0f; |
| 164 | - | ||
| 165 | - /*if (stages.size() == 0) // special case for empty cascade | ||
| 166 | - return 1.0f; | ||
| 167 | - | ||
| 168 | - float result = 0.0f; | ||
| 169 | - for (int stageIdx = 0; stageIdx < stages.size(); stageIdx++) { | ||
| 170 | - result = stages[stageIdx]->classify(image); | ||
| 171 | - | ||
| 172 | - if (result < 0) | ||
| 173 | - return stageIdx > (stages.size() - 4) ? stageIdx * result : 0.0f; | ||
| 174 | - } | ||
| 175 | - return std::abs(stages.size() * result);*/ | ||
| 176 | } | 161 | } |
| 177 | 162 | ||
| 178 | int numFeatures() const | 163 | int numFeatures() const |
| @@ -192,13 +177,7 @@ class CascadeClassifier : public Classifier | @@ -192,13 +177,7 @@ class CascadeClassifier : public Classifier | ||
| 192 | 177 | ||
| 193 | void write(FileStorage &fs) const | 178 | void write(FileStorage &fs) const |
| 194 | { | 179 | { |
| 195 | -<<<<<<< HEAD | ||
| 196 | - fs << "stageCount" << stages.size(); | ||
| 197 | - | ||
| 198 | fs << "stages" << "["; | 180 | fs << "stages" << "["; |
| 199 | -======= | ||
| 200 | - fs << CC_STAGES << "["; | ||
| 201 | ->>>>>>> 4fab7f69ddc82d6ba40a73fc6233e3cc9871473e | ||
| 202 | foreach (const Classifier *stage, stages) { | 181 | foreach (const Classifier *stage, stages) { |
| 203 | fs << "{"; | 182 | fs << "{"; |
| 204 | stage->write(fs); | 183 | stage->write(fs); |
| @@ -217,7 +196,7 @@ private: | @@ -217,7 +196,7 @@ private: | ||
| 217 | if (!imgHandler.getPos(pos)) | 196 | if (!imgHandler.getPos(pos)) |
| 218 | qFatal("Cannot get another positive sample!"); | 197 | qFatal("Cannot get another positive sample!"); |
| 219 | 198 | ||
| 220 | - if (classify(pos) > 0.0f) { | 199 | + if (classify(pos) == 1.0f) { |
| 221 | printf("POS current samples: %d\r", images.size()); | 200 | printf("POS current samples: %d\r", images.size()); |
| 222 | images.append(pos); | 201 | images.append(pos); |
| 223 | labels.append(1.0f); | 202 | labels.append(1.0f); |
| @@ -233,7 +212,7 @@ private: | @@ -233,7 +212,7 @@ private: | ||
| 233 | if (!imgHandler.getNeg(neg)) | 212 | if (!imgHandler.getNeg(neg)) |
| 234 | qFatal("Cannot get another negative sample!"); | 213 | qFatal("Cannot get another negative sample!"); |
| 235 | 214 | ||
| 236 | - if (classify(neg) > 0.0f) { | 215 | + if (classify(neg) == 1.0f) { |
| 237 | printf("NEG current samples: %d\r", images.size() - posCount); | 216 | printf("NEG current samples: %d\r", images.size() - posCount); |
| 238 | images.append(neg); | 217 | images.append(neg); |
| 239 | labels.append(0.0f); | 218 | labels.append(0.0f); |
openbr/plugins/imgproc/slidingwindow.cpp
| @@ -21,8 +21,6 @@ | @@ -21,8 +21,6 @@ | ||
| 21 | #include <openbr/core/qtutils.h> | 21 | #include <openbr/core/qtutils.h> |
| 22 | 22 | ||
| 23 | #include <opencv2/highgui/highgui.hpp> | 23 | #include <opencv2/highgui/highgui.hpp> |
| 24 | -#include <opencv2/imgproc/imgproc.hpp> | ||
| 25 | -#include <opencv2/objdetect/objdetect.hpp> | ||
| 26 | 24 | ||
| 27 | using namespace cv; | 25 | using namespace cv; |
| 28 | 26 | ||
| @@ -41,23 +39,11 @@ class SlidingWindowTransform : public Transform | @@ -41,23 +39,11 @@ class SlidingWindowTransform : public Transform | ||
| 41 | Q_OBJECT | 39 | Q_OBJECT |
| 42 | 40 | ||
| 43 | Q_PROPERTY(br::Classifier *classifier READ get_classifier WRITE set_classifier RESET reset_classifier STORED false) | 41 | Q_PROPERTY(br::Classifier *classifier READ get_classifier WRITE set_classifier RESET reset_classifier STORED false) |
| 44 | - Q_PROPERTY(int minSize READ get_minSize WRITE set_minSize RESET reset_minSize STORED false) | ||
| 45 | - Q_PROPERTY(int maxSize READ get_maxSize WRITE set_maxSize RESET reset_maxSize STORED false) | ||
| 46 | - Q_PROPERTY(float scaleFactor READ get_scaleFactor WRITE set_scaleFactor RESET reset_scaleFactor STORED false) | ||
| 47 | - Q_PROPERTY(int minNeighbors READ get_minNeighbors WRITE set_minNeighbors RESET reset_minNeighbors STORED false) | ||
| 48 | - Q_PROPERTY(float eps READ get_eps WRITE set_eps RESET reset_eps STORED false) | ||
| 49 | - | ||
| 50 | Q_PROPERTY(QString cascadeDir READ get_cascadeDir WRITE set_cascadeDir RESET reset_cascadeDir STORED false) | 42 | Q_PROPERTY(QString cascadeDir READ get_cascadeDir WRITE set_cascadeDir RESET reset_cascadeDir STORED false) |
| 51 | Q_PROPERTY(QString vecFile READ get_vecFile WRITE set_vecFile RESET reset_vecFile STORED false) | 43 | Q_PROPERTY(QString vecFile READ get_vecFile WRITE set_vecFile RESET reset_vecFile STORED false) |
| 52 | Q_PROPERTY(QString negFile READ get_negFile WRITE set_negFile RESET reset_negFile STORED false) | 44 | Q_PROPERTY(QString negFile READ get_negFile WRITE set_negFile RESET reset_negFile STORED false) |
| 53 | 45 | ||
| 54 | BR_PROPERTY(br::Classifier *, classifier, NULL) | 46 | BR_PROPERTY(br::Classifier *, classifier, NULL) |
| 55 | - BR_PROPERTY(int, minSize, 24) | ||
| 56 | - BR_PROPERTY(int, maxSize, -1) | ||
| 57 | - BR_PROPERTY(float, scaleFactor, 1.2) | ||
| 58 | - BR_PROPERTY(int, minNeighbors, 5) | ||
| 59 | - BR_PROPERTY(float, eps, 0.2) | ||
| 60 | - | ||
| 61 | BR_PROPERTY(QString, cascadeDir, "") | 47 | BR_PROPERTY(QString, cascadeDir, "") |
| 62 | BR_PROPERTY(QString, vecFile, "vec.vec") | 48 | BR_PROPERTY(QString, vecFile, "vec.vec") |
| 63 | BR_PROPERTY(QString, negFile, "neg.txt") | 49 | BR_PROPERTY(QString, negFile, "neg.txt") |
| @@ -135,11 +121,6 @@ class SlidingWindowTransform : public Transform | @@ -135,11 +121,6 @@ class SlidingWindowTransform : public Transform | ||
| 135 | return negs; | 121 | return negs; |
| 136 | } | 122 | } |
| 137 | 123 | ||
| 138 | - void init() | ||
| 139 | - { | ||
| 140 | - cascadeDir = Globals->sdkPath + "/share/openbr/models/openbrcascades/" + cascadeDir; | ||
| 141 | - } | ||
| 142 | - | ||
| 143 | void train(const TemplateList &_data) | 124 | void train(const TemplateList &_data) |
| 144 | { | 125 | { |
| 145 | (void)_data; | 126 | (void)_data; |
| @@ -159,109 +140,34 @@ class SlidingWindowTransform : public Transform | @@ -159,109 +140,34 @@ class SlidingWindowTransform : public Transform | ||
| 159 | } | 140 | } |
| 160 | 141 | ||
| 161 | classifier->train(images, labels); | 142 | classifier->train(images, labels); |
| 143 | + } | ||
| 144 | + | ||
| 145 | + void project(const Template &src, Template &dst) const | ||
| 146 | + { | ||
| 147 | + (void)src; (void)dst; | ||
| 148 | + } | ||
| 149 | + | ||
| 150 | + void load(QDataStream &stream) | ||
| 151 | + { | ||
| 152 | + (void) stream; | ||
| 153 | + return; | ||
| 154 | + } | ||
| 162 | 155 | ||
| 163 | - // save the cascade | ||
| 164 | - std::string filename = cascadeDir.toStdString() + "/cascade.xml"; | ||
| 165 | - FileStorage fs(filename, FileStorage::WRITE ); | 156 | + void store(QDataStream &stream) const |
| 157 | + { | ||
| 158 | + (void) stream; | ||
| 166 | 159 | ||
| 160 | + QString filename = Globals->sdkPath + "/share/openbr/models/openbrcascades/" + cascadeDir + "/cascade.xml"; | ||
| 161 | + FileStorage fs(filename.toStdString(), FileStorage::WRITE); | ||
| 167 | if ( !fs.isOpened() ) | 162 | if ( !fs.isOpened() ) |
| 168 | return; | 163 | return; |
| 169 | 164 | ||
| 170 | - fs << FileStorage::getDefaultObjectName(filename) << "{"; | 165 | + fs << FileStorage::getDefaultObjectName(filename.toStdString()) << "{"; |
| 171 | 166 | ||
| 172 | classifier->write(fs); | 167 | classifier->write(fs); |
| 173 | 168 | ||
| 174 | fs << "}"; | 169 | fs << "}"; |
| 175 | } | 170 | } |
| 176 | - | ||
| 177 | - void project(const Template &src, Template &dst) const | ||
| 178 | - { | ||
| 179 | - TemplateList temp; | ||
| 180 | - project(TemplateList() << src, temp); | ||
| 181 | - if (!temp.isEmpty()) dst = temp.first(); | ||
| 182 | - } | ||
| 183 | - | ||
| 184 | - void project(const TemplateList &src, TemplateList &dst) const | ||
| 185 | - { | ||
| 186 | - foreach (const Template &t, src) { | ||
| 187 | - const bool enrollAll = t.file.getBool("enrollAll"); | ||
| 188 | - | ||
| 189 | - // Mirror the behavior of ExpandTransform in the special case | ||
| 190 | - // of an empty template. | ||
| 191 | - if (t.empty() && !enrollAll) { | ||
| 192 | - dst.append(t); | ||
| 193 | - continue; | ||
| 194 | - } | ||
| 195 | - | ||
| 196 | - for (int i = 0; i < t.size(); i++) { | ||
| 197 | - Mat image; | ||
| 198 | - OpenCVUtils::cvtUChar(t[i], image); | ||
| 199 | - | ||
| 200 | - std::vector<Rect> rects; | ||
| 201 | - std::vector<int> rejectLevels; | ||
| 202 | - std::vector<double> levelWeights; | ||
| 203 | - | ||
| 204 | - Size minObjectSize(minSize, minSize); | ||
| 205 | - Size maxObjectSize(maxSize, maxSize); | ||
| 206 | - if (maxObjectSize.height == 0 || maxObjectSize.width == 0) | ||
| 207 | - maxObjectSize = image.size(); | ||
| 208 | - | ||
| 209 | - Mat imageBuffer(image.rows + 1, image.cols + 1, CV_8U); | ||
| 210 | - | ||
| 211 | - for (double factor = 1; ; factor *= scaleFactor) { | ||
| 212 | - Size originalWindowSize = classifier->windowSize(); | ||
| 213 | - | ||
| 214 | - Size windowSize(cvRound(originalWindowSize.width*factor), cvRound(originalWindowSize.height*factor) ); | ||
| 215 | - Size scaledImageSize(cvRound(image.cols/factor ), cvRound(image.rows/factor)); | ||
| 216 | - Size processingRectSize(scaledImageSize.width - originalWindowSize.width, scaledImageSize.height - originalWindowSize.height); | ||
| 217 | - | ||
| 218 | - if (processingRectSize.width <= 0 || processingRectSize.height <= 0) | ||
| 219 | - break; | ||
| 220 | - if (windowSize.width > maxObjectSize.width || windowSize.height > maxObjectSize.height) | ||
| 221 | - break; | ||
| 222 | - if (windowSize.width < minObjectSize.width || windowSize.height < minObjectSize.height) | ||
| 223 | - continue; | ||
| 224 | - | ||
| 225 | - Mat scaledImage(scaledImageSize, CV_8U, imageBuffer.data); | ||
| 226 | - resize(image, scaledImage, scaledImageSize, 0, 0, CV_INTER_LINEAR); | ||
| 227 | - | ||
| 228 | - int yStep = factor > 2. ? 1 : 2; | ||
| 229 | - for (int y = 0; y < processingRectSize.height; y += yStep) { | ||
| 230 | - for (int x = 0; x < processingRectSize.width; x += yStep) { | ||
| 231 | - Mat window = scaledImage(Rect(Point(x, y), classifier->windowSize())).clone(); | ||
| 232 | - | ||
| 233 | - float result = classifier->classify(window); | ||
| 234 | - | ||
| 235 | - if (result > 0) { | ||
| 236 | - rects.push_back(Rect(cvRound(x*factor), cvRound(y*factor), windowSize.width, windowSize.height)); | ||
| 237 | - rejectLevels.push_back(1); | ||
| 238 | - levelWeights.push_back(result); | ||
| 239 | - } | ||
| 240 | - if (result == 0) | ||
| 241 | - x += yStep; | ||
| 242 | - } | ||
| 243 | - } | ||
| 244 | - } | ||
| 245 | - | ||
| 246 | - groupRectangles(rects, rejectLevels, levelWeights, minNeighbors, eps); | ||
| 247 | - | ||
| 248 | - if (!enrollAll && rects.empty()) | ||
| 249 | - rects.push_back(Rect(0, 0, image.cols, image.rows)); | ||
| 250 | - | ||
| 251 | - for (size_t j = 0; j < rects.size(); j++) { | ||
| 252 | - Template u(t.file, image); | ||
| 253 | - if (rejectLevels.size() > j) | ||
| 254 | - u.file.set("Confidence", rejectLevels[j]*levelWeights[j]); | ||
| 255 | - else | ||
| 256 | - u.file.set("Confidence", 1); | ||
| 257 | - const QRectF rect = OpenCVUtils::fromRect(rects[j]); | ||
| 258 | - u.file.appendRect(rect); | ||
| 259 | - u.file.set("Face", rect); | ||
| 260 | - dst.append(u); | ||
| 261 | - } | ||
| 262 | - } | ||
| 263 | - } | ||
| 264 | - } | ||
| 265 | }; | 171 | }; |
| 266 | 172 | ||
| 267 | BR_REGISTER(Transform, SlidingWindowTransform) | 173 | BR_REGISTER(Transform, SlidingWindowTransform) |
openbr/plugins/representation/mblbp.cpp
| @@ -58,6 +58,7 @@ class MBLBPRepresentation : public Representation | @@ -58,6 +58,7 @@ class MBLBPRepresentation : public Representation | ||
| 58 | return result; | 58 | return result; |
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | + void write(FileStorage &fs, const Mat &featureMap); | ||
| 61 | int numFeatures() const { return features.size(); } | 62 | int numFeatures() const { return features.size(); } |
| 62 | Size preWindowSize() const { return Size(winWidth, winHeight); } | 63 | Size preWindowSize() const { return Size(winWidth, winHeight); } |
| 63 | Size postWindowSize() const { return Size(winWidth + 1, winHeight + 1); } | 64 | Size postWindowSize() const { return Size(winWidth + 1, winHeight + 1); } |
| @@ -78,6 +79,20 @@ class MBLBPRepresentation : public Representation | @@ -78,6 +79,20 @@ class MBLBPRepresentation : public Representation | ||
| 78 | 79 | ||
| 79 | BR_REGISTER(Representation, MBLBPRepresentation) | 80 | BR_REGISTER(Representation, MBLBPRepresentation) |
| 80 | 81 | ||
| 82 | +void MBLBPRepresentation::write(FileStorage &fs, const Mat &featureMap) | ||
| 83 | +{ | ||
| 84 | + fs << "features" << "["; | ||
| 85 | + const Mat_<int>& featureMap_ = (const Mat_<int>&)featureMap; | ||
| 86 | + for ( int fi = 0; fi < featureMap.cols; fi++ ) | ||
| 87 | + if ( featureMap_(0, fi) >= 0 ) | ||
| 88 | + { | ||
| 89 | + fs << "{"; | ||
| 90 | + features[fi].write( fs ); | ||
| 91 | + fs << "}"; | ||
| 92 | + } | ||
| 93 | + fs << "]"; | ||
| 94 | +} | ||
| 95 | + | ||
| 81 | MBLBPRepresentation::Feature::Feature( int offset, int x, int y, int _blockWidth, int _blockHeight ) | 96 | MBLBPRepresentation::Feature::Feature( int offset, int x, int y, int _blockWidth, int _blockHeight ) |
| 82 | { | 97 | { |
| 83 | Rect tr = rect = cvRect(x, y, _blockWidth, _blockHeight); | 98 | Rect tr = rect = cvRect(x, y, _blockWidth, _blockHeight); |