Commit cbd44c29672060a50b16bcb4e0f226db97246096

Authored by dgcrouse
1 parent f9c35526

Requested fixes

Tabs to spaces, used OpenCV folder separator function, capitalized
struct name, re-added missing bracket
Showing 1 changed file with 335 additions and 342 deletions
openbr/plugins/cascade.cpp
@@ -19,165 +19,158 @@ @@ -19,165 +19,158 @@
19 #include "openbr_internal.h" 19 #include "openbr_internal.h"
20 #include "openbr/core/opencvutils.h" 20 #include "openbr/core/opencvutils.h"
21 #include "openbr/core/resource.h" 21 #include "openbr/core/resource.h"
22 -#include <QtXml>  
23 #include <stdlib.h> 22 #include <stdlib.h>
24 23
25 -#ifndef _win32  
26 - const QString foldersep = "/";  
27 -#else  
28 - const QString foldersep = "\\";  
29 -#endif  
30 -  
31 using namespace cv; 24 using namespace cv;
  25 +
  26 + struct TrainParams{
  27 +
  28 + public:
  29 + QString data; // REQUIRED: Filepath to store trained classifier
  30 + QString vec; // REQUIRED: Filepath to store vector of positive samples, default "vector"
  31 + QString img; // Filepath to source object image. Either this or info is REQUIRED
  32 + QString info; // Description file of source images. Either this or img is REQUIRED
  33 + QString bg; // REQUIRED: Filepath to background list file
  34 + int num; // Number of samples to generate
  35 + int bgcolor; // Background color supplied image (via img)
  36 + int bgthresh; // Threshold to determine bgcolor match
  37 + bool inv; // Invert colors
  38 + bool randinv; // Randomly invert colors
  39 + int maxidev; // Max intensity deviation of foreground pixels
  40 + double maxxangle; // Maximum rotation angle (X)
  41 + double maxyangle; // Maximum rotation angle (Y)
  42 + double maxzangle; // Maximum rotation angle (Z)
  43 + bool show; // Show generated samples
  44 + int w; // REQUIRED: Sample width
  45 + int h; // REQUIRED: Sample height
  46 + int numPos; // Number of positive samples
  47 + int numNeg; // Number of negative samples
  48 + int numStages; // Number of stages
  49 + int precalcValBufSize; // Precalculated val buffer size in Mb
  50 + int precalcIdxBufSize; // Precalculated index buffer size in Mb
  51 + bool baseFormatSave; // Save in old format
  52 + QString stageType; // Stage type (BOOST)
  53 + QString featureType; // Feature type (HAAR, LBP)
  54 + QString bt; // Boosted classifier type (DAB, RAB, LB, GAB)
  55 + double minHitRate; // Minimal hit rate per stage
  56 + double maxFalseAlarmRate; // Max false alarm rate per stage
  57 + double weightTrimRate; // Weight for trimming
  58 + int maxDepth; // Max weak tree depth
  59 + int maxWeakCount; // Max weak tree count per stage
  60 + QString mode; // Haar feature mode (BASIC, CORE, ALL)
  61 +
  62 + TrainParams(){
  63 + num = -1;
  64 + maxidev = -1;
  65 + maxxangle = -1;
  66 + maxyangle = -1;
  67 + maxzangle = -1;
  68 + w = -1;
  69 + h = -1;
  70 + numPos = -1;
  71 + numNeg = -1;
  72 + numStages = -1;
  73 + precalcValBufSize = -1;
  74 + precalcIdxBufSize = -1;
  75 + minHitRate = -1;
  76 + maxFalseAlarmRate = -1;
  77 + weightTrimRate = -1;
  78 + maxDepth = -1;
  79 + maxWeakCount = -1;
  80 + inv = false;
  81 + randinv = false;
  82 + show = false;
  83 + baseFormatSave = false;
  84 + vec = "vector.vec";
  85 + bgcolor = -1;
  86 + bgthresh = -1;
  87 + }
  88 + };
32 89
33 -namespace br  
34 -{  
35 -  
36 - struct trainParams{  
37 - public:  
38 - QString data; // REQUIRED: Filepath to store trained classifier  
39 - QString vec; // REQUIRED: Filepath to store vector of positive samples, default "vector"  
40 - QString img; // Filepath to source object image. Either this or info is REQUIRED  
41 - QString info; // Description file of source images. Either this or img is REQUIRED  
42 - QString bg; // REQUIRED: Filepath to background list file  
43 - int num; // Number of samples to generate  
44 - int bgcolor; // Background color supplied image (via img)  
45 - int bgthresh; // Threshold to determine bgcolor match  
46 - bool inv; // Invert colors  
47 - bool randinv; // Randomly invert colors  
48 - int maxidev; // Max intensity deviation of foreground pixels  
49 - double maxxangle; // Maximum rotation angle (X)  
50 - double maxyangle; // Maximum rotation angle (Y)  
51 - double maxzangle; // Maximum rotation angle (Z)  
52 - bool show; // Show generated samples  
53 - int w; // REQUIRED: Sample width  
54 - int h; // REQUIRED: Sample height  
55 - int numPos; // Number of positive samples  
56 - int numNeg; // Number of negative samples  
57 - int numStages; // Number of stages  
58 - int precalcValBufSize; // Precalculated val buffer size in Mb  
59 - int precalcIdxBufSize; // Precalculated index buffer size in Mb  
60 - bool baseFormatSave; // Save in old format  
61 - QString stageType; // Stage type (BOOST)  
62 - QString featureType; // Feature type (HAAR, LBP)  
63 - QString bt; // Boosted classifier type (DAB, RAB, LB, GAB)  
64 - double minHitRate; // Minimal hit rate per stage  
65 - double maxFalseAlarmRate; // Max false alarm rate per stage  
66 - double weightTrimRate; // Weight for trimming  
67 - int maxDepth; // Max weak tree depth  
68 - int maxWeakCount; // Max weak tree count per stage  
69 - QString mode; // Haar feature mode (BASIC, CORE, ALL)  
70 -  
71 - trainParams(){  
72 - num = -1;  
73 - maxidev = -1;  
74 - maxxangle = -1;  
75 - maxyangle = -1;  
76 - maxzangle = -1;  
77 - w = -1;  
78 - h = -1;  
79 - numPos = -1;  
80 - numNeg = -1;  
81 - numStages = -1;  
82 - precalcValBufSize = -1;  
83 - precalcIdxBufSize = -1;  
84 - minHitRate = -1;  
85 - maxFalseAlarmRate = -1;  
86 - weightTrimRate = -1;  
87 - maxDepth = -1;  
88 - maxWeakCount = -1;  
89 - inv = false;  
90 - randinv = false;  
91 - show = false;  
92 - baseFormatSave = false;  
93 - vec = "vector.vec";  
94 - bgcolor = -1;  
95 - bgthresh = -1;  
96 - }  
97 - };  
98 -  
99 - QString buildTrainingArgs(trainParams params){  
100 - QString args = "";  
101 - if (params.data != "") args += "-data " + params.data + " ";  
102 - else return "";  
103 - if (params.vec != "") args += "-vec " + params.vec + " ";  
104 - else return "";  
105 - if (params.bg != "") args += "-bg " + params.bg + " ";  
106 - else return "";  
107 - if (params.numPos >= 0) args += "-numPos " + QString::number(params.numPos) + " ";  
108 - if (params.numNeg >= 0) args += "-numNeg " + QString::number(params.numNeg) + " ";  
109 - if (params.numStages >= 0) args += "-numStages " + QString::number(params.numStages) + " ";  
110 - if (params.precalcValBufSize >= 0) args += "-precalcValBufSize " + QString::number(params.precalcValBufSize) + " ";  
111 - if (params.precalcIdxBufSize >= 0) args += "-precalcIdxBufSize " + QString::number(params.precalcIdxBufSize) + " ";  
112 - if (params.baseFormatSave) args += "-baseFormatSave ";  
113 - if (params.stageType != "") args += "-stageType " + params.stageType + " ";  
114 - if (params.featureType != "") args += "-featureType " + params.featureType + " ";  
115 - if (params.w >= 0) args += "-w " + QString::number(params.w) + " ";  
116 - else return "";  
117 - if (params.h >= 0) args += "-h " + QString::number(params.h) + " ";  
118 - else return "";  
119 - if (params.bt != "") args += "-bt " + params.bt + " ";  
120 - if (params.minHitRate >= 0) args += "-minHitRate " + QString::number(params.minHitRate) + " ";  
121 - if (params.maxFalseAlarmRate >= 0) args += "-maxFalseAlarmRate " + QString::number(params.maxFalseAlarmRate) + " ";  
122 - if (params.weightTrimRate >= 0) args += "-weightTrimRate " + QString::number(params.weightTrimRate) + " ";  
123 - if (params.maxDepth >= 0) args += "-maxDepth " + QString::number(params.maxDepth) + " ";  
124 - if (params.maxWeakCount >= 0) args += "-maxWeakCount " + QString::number(params.maxWeakCount) + " ";  
125 - if (params.mode != "") args += "-mode " + params.mode + " ";  
126 - return args;  
127 - }  
128 - 90 + QString buildTrainingArgs(TrainParams params){
  91 + QString args = "";
  92 + if (params.data != "") args += "-data " + params.data + " ";
  93 + else return "";
  94 + if (params.vec != "") args += "-vec " + params.vec + " ";
  95 + else return "";
  96 + if (params.bg != "") args += "-bg " + params.bg + " ";
  97 + else return "";
  98 + if (params.numPos >= 0) args += "-numPos " + QString::number(params.numPos) + " ";
  99 + if (params.numNeg >= 0) args += "-numNeg " + QString::number(params.numNeg) + " ";
  100 + if (params.numStages >= 0) args += "-numStages " + QString::number(params.numStages) + " ";
  101 + if (params.precalcValBufSize >= 0) args += "-precalcValBufSize " + QString::number(params.precalcValBufSize) + " ";
  102 + if (params.precalcIdxBufSize >= 0) args += "-precalcIdxBufSize " + QString::number(params.precalcIdxBufSize) + " ";
  103 + if (params.baseFormatSave) args += "-baseFormatSave ";
  104 + if (params.stageType != "") args += "-stageType " + params.stageType + " ";
  105 + if (params.featureType != "") args += "-featureType " + params.featureType + " ";
  106 + if (params.w >= 0) args += "-w " + QString::number(params.w) + " ";
  107 + else return "";
  108 + if (params.h >= 0) args += "-h " + QString::number(params.h) + " ";
  109 + else return "";
  110 + if (params.bt != "") args += "-bt " + params.bt + " ";
  111 + if (params.minHitRate >= 0) args += "-minHitRate " + QString::number(params.minHitRate) + " ";
  112 + if (params.maxFalseAlarmRate >= 0) args += "-maxFalseAlarmRate " + QString::number(params.maxFalseAlarmRate) + " ";
  113 + if (params.weightTrimRate >= 0) args += "-weightTrimRate " + QString::number(params.weightTrimRate) + " ";
  114 + if (params.maxDepth >= 0) args += "-maxDepth " + QString::number(params.maxDepth) + " ";
  115 + if (params.maxWeakCount >= 0) args += "-maxWeakCount " + QString::number(params.maxWeakCount) + " ";
  116 + if (params.mode != "") args += "-mode " + params.mode + " ";
  117 + return args;
  118 + }
129 119
130 - QString buildSampleArgs(trainParams params){  
131 - QString args = "";  
132 - if (params.vec != "") args += "-vec "+params.vec+" ";  
133 - else return "";  
134 - if (params.img != "") args += "-img " + params.img + " ";  
135 - else if (params.info != "") args += "-info " + params.info + " ";  
136 - else return "";  
137 - if (params.bg != "") args += "-bg " + params.bg + " ";  
138 - if (params.num > 0) args += "-num " + QString::number(params.num) + " ";  
139 - if (params.bgcolor >=0 ) args += "-bgcolor " + QString::number(params.bgcolor) + " ";  
140 - if (params.bgthresh >= 0) args += "-bgthresh " + QString::number(params.bgthresh) + " ";  
141 - if (params.maxidev >= 0) args += "-maxidev " + QString::number(params.maxidev) + " ";  
142 - if (params.maxxangle >= 0) args += "-maxxangle " + QString::number(params.maxxangle) + " ";  
143 - if (params.maxyangle >= 0) args += "-maxyangle " + QString::number(params.maxyangle) + " ";  
144 - if (params.maxzangle >= 0) args += "-maxzangle " + QString::number(params.maxzangle) + " ";  
145 - if (params.w >= 0) args += "-w " + QString::number(params.w) + " ";  
146 - if (params.h >= 0) args += "-h " + QString::number(params.h) + " ";  
147 - if (params.show) args += "-show ";  
148 - if (params.inv) args += "-inv ";  
149 - if (params.randinv) args += "-randinv ";  
150 - return args;  
151 - }  
152 120
153 - void execCommand(QString cmd, QString args){  
154 - #ifdef _WIN32  
155 - cmd += ".exe";  
156 - #endif  
157 - cmd += " " + args;  
158 - system(cmd.toLocal8Bit().data());  
159 - }  
160 -  
161 - void genSamples(trainParams params, QString argStr = ""){  
162 - QString cmdArgs = buildSampleArgs(params);  
163 - if (argStr != "") cmdArgs += " " + argStr;  
164 - execCommand("opencv_createsamples",cmdArgs);  
165 - } 121 + QString buildSampleArgs(TrainParams params){
  122 + QString args = "";
  123 + if (params.vec != "") args += "-vec "+params.vec+" ";
  124 + else return "";
  125 + if (params.img != "") args += "-img " + params.img + " ";
  126 + else if (params.info != "") args += "-info " + params.info + " ";
  127 + else return "";
  128 + if (params.bg != "") args += "-bg " + params.bg + " ";
  129 + if (params.num > 0) args += "-num " + QString::number(params.num) + " ";
  130 + if (params.bgcolor >=0 ) args += "-bgcolor " + QString::number(params.bgcolor) + " ";
  131 + if (params.bgthresh >= 0) args += "-bgthresh " + QString::number(params.bgthresh) + " ";
  132 + if (params.maxidev >= 0) args += "-maxidev " + QString::number(params.maxidev) + " ";
  133 + if (params.maxxangle >= 0) args += "-maxxangle " + QString::number(params.maxxangle) + " ";
  134 + if (params.maxyangle >= 0) args += "-maxyangle " + QString::number(params.maxyangle) + " ";
  135 + if (params.maxzangle >= 0) args += "-maxzangle " + QString::number(params.maxzangle) + " ";
  136 + if (params.w >= 0) args += "-w " + QString::number(params.w) + " ";
  137 + if (params.h >= 0) args += "-h " + QString::number(params.h) + " ";
  138 + if (params.show) args += "-show ";
  139 + if (params.inv) args += "-inv ";
  140 + if (params.randinv) args += "-randinv ";
  141 + return args;
  142 + }
166 143
  144 + void execCommand(QString cmd, QString args){
  145 + #ifdef _WIN32
  146 + cmd += ".exe";
  147 + #endif
  148 + cmd += " " + args;
  149 + system(cmd.toLocal8Bit().data());
  150 + }
  151 +
  152 + void genSamples(TrainParams params, QString argStr = ""){
  153 + QString cmdArgs = buildSampleArgs(params);
  154 + if (argStr != "") cmdArgs += " " + argStr;
  155 + execCommand("opencv_createsamples",cmdArgs);
  156 + }
167 157
168 - void trainCascade(trainParams params,QString argStr = ""){  
169 - QString cmdArgs = buildTrainingArgs(params);  
170 - if (argStr != "") cmdArgs += " " + argStr;  
171 -  
172 - execCommand("opencv_traincascade", cmdArgs);  
173 - }  
174 -  
175 -QString rectToString(QRectF r){  
176 - QString out = " " + QString::number(r.x()) + " " + QString::number(r.y()) + " " + QString::number(r.width()) + " "+ QString::number(r.height());  
177 - return out;  
178 -}  
179 -  
180 158
  159 + void trainCascade(TrainParams params,QString argStr = ""){
  160 + QString cmdArgs = buildTrainingArgs(params);
  161 + if (argStr != "") cmdArgs += " " + argStr;
  162 +
  163 + execCommand("opencv_traincascade", cmdArgs);
  164 + }
  165 +
  166 + QString rectToString(QRectF r){
  167 + QString out = " " + QString::number(r.x()) + " " + QString::number(r.y()) + " " + QString::number(r.width()) + " "+ QString::number(r.height());
  168 + return out;
  169 + }
  170 +
  171 + namespace br
  172 + {
  173 +
181 class CascadeResourceMaker : public ResourceMaker<CascadeClassifier> 174 class CascadeResourceMaker : public ResourceMaker<CascadeClassifier>
182 { 175 {
183 QString file; 176 QString file;
@@ -185,26 +178,26 @@ class CascadeResourceMaker : public ResourceMaker&lt;CascadeClassifier&gt; @@ -185,26 +178,26 @@ class CascadeResourceMaker : public ResourceMaker&lt;CascadeClassifier&gt;
185 public: 178 public:
186 CascadeResourceMaker(const QString &model) 179 CascadeResourceMaker(const QString &model)
187 { 180 {
188 - file = Globals->sdkPath + "/share/openbr/models/"; 181 + file = Globals->sdkPath + "/share/openbr/models/";
189 if (model == "Ear") file += "haarcascades/haarcascade_ear.xml"; 182 if (model == "Ear") file += "haarcascades/haarcascade_ear.xml";
190 else if (model == "Eye") file += "haarcascades/haarcascade_eye_tree_eyeglasses.xml"; 183 else if (model == "Eye") file += "haarcascades/haarcascade_eye_tree_eyeglasses.xml";
191 else if (model == "FrontalFace") file += "haarcascades/haarcascade_frontalface_alt2.xml"; 184 else if (model == "FrontalFace") file += "haarcascades/haarcascade_frontalface_alt2.xml";
192 else if (model == "ProfileFace") file += "haarcascades/haarcascade_profileface.xml"; 185 else if (model == "ProfileFace") file += "haarcascades/haarcascade_profileface.xml";
193 else{ 186 else{
194 - // Create temp folder if does not exist  
195 - file = model+foldersep+"cascade.xml";  
196 - QDir dir(model);  
197 - if (!dir.exists())  
198 - if (!QDir::current().mkdir(model)) qFatal("Cannot create model.");  
199 -  
200 - // Make sure file can be created  
201 - QFile pathTest(file);  
202 - if (pathTest.exists()) pathTest.remove();  
203 -  
204 - if (!pathTest.open(QIODevice::WriteOnly | QIODevice::Text)) qFatal("Cannot create model.");  
205 - pathTest.remove();  
206 - }  
207 - } 187 + // Create temp folder if does not exist
  188 + file = model+QDir::separator()+"cascade.xml";
  189 + QDir dir(model);
  190 + if (!dir.exists())
  191 + if (!QDir::current().mkdir(model)) qFatal("Cannot create model.");
  192 +
  193 + // Make sure file can be created
  194 + QFile pathTest(file);
  195 + if (pathTest.exists()) pathTest.remove();
  196 +
  197 + if (!pathTest.open(QIODevice::WriteOnly | QIODevice::Text)) qFatal("Cannot create model.");
  198 + pathTest.remove();
  199 + }
  200 + }
208 201
209 private: 202 private:
210 CascadeClassifier *make() const 203 CascadeClassifier *make() const
@@ -228,54 +221,54 @@ class CascadeTransform : public MetaTransform @@ -228,54 +221,54 @@ class CascadeTransform : public MetaTransform
228 Q_PROPERTY(QString model READ get_model WRITE set_model RESET reset_model STORED false) 221 Q_PROPERTY(QString model READ get_model WRITE set_model RESET reset_model STORED false)
229 Q_PROPERTY(int minSize READ get_minSize WRITE set_minSize RESET reset_minSize STORED false) 222 Q_PROPERTY(int minSize READ get_minSize WRITE set_minSize RESET reset_minSize STORED false)
230 Q_PROPERTY(bool ROCMode READ get_ROCMode WRITE set_ROCMode RESET reset_ROCMode STORED false) 223 Q_PROPERTY(bool ROCMode READ get_ROCMode WRITE set_ROCMode RESET reset_ROCMode STORED false)
231 -  
232 - // Training parameters  
233 - Q_PROPERTY(int numStages READ get_numStages WRITE set_numStages RESET reset_numStages STORED false)  
234 - Q_PROPERTY(int w READ get_w WRITE set_w RESET reset_w STORED false)  
235 - Q_PROPERTY(int h READ get_h WRITE set_h RESET reset_h STORED false)  
236 - Q_PROPERTY(int numPos READ get_numPos WRITE set_numPos RESET reset_numPos STORED false)  
237 - Q_PROPERTY(int numNeg READ get_numNeg WRITE set_numNeg RESET reset_numNeg STORED false)  
238 - Q_PROPERTY(int precalcValBufSize READ get_precalcValBufSize WRITE set_precalcValBufSize RESET reset_precalcValBufSize STORED false)  
239 - Q_PROPERTY(int precalcIdxBufSize READ get_precalcIdxBufSize WRITE set_precalcIdxBufSize RESET reset_precalcIdxBufSize STORED false)  
240 - Q_PROPERTY(double minHitRate READ get_minHitRate WRITE set_minHitRate RESET reset_minHitRate STORED false)  
241 - Q_PROPERTY(double maxFalseAlarmRate READ get_maxFalseAlarmRate WRITE set_maxFalseAlarmRate RESET reset_maxFalseAlarmRate STORED false)  
242 - Q_PROPERTY(double weightTrimRate READ get_weightTrimRate WRITE set_weightTrimRate RESET reset_weightTrimRate STORED false)  
243 - Q_PROPERTY(int maxDepth READ get_maxDepth WRITE set_maxDepth RESET reset_maxDepth STORED false)  
244 - Q_PROPERTY(int maxWeakCount READ get_maxWeakCount WRITE set_maxWeakCount RESET reset_maxWeakCount STORED false)  
245 - Q_PROPERTY(QString stageType READ get_stageType WRITE set_stageType RESET reset_stageType STORED false)  
246 - Q_PROPERTY(QString featureType READ get_featureType WRITE set_featureType RESET reset_featureType STORED false)  
247 - Q_PROPERTY(QString bt READ get_bt WRITE set_bt RESET reset_bt STORED false)  
248 - Q_PROPERTY(QString mode READ get_mode WRITE set_mode RESET reset_mode STORED false)  
249 - Q_PROPERTY(bool show READ get_show WRITE set_show RESET reset_show STORED false)  
250 - Q_PROPERTY(bool baseFormatSave READ get_baseFormatSave WRITE set_baseFormatSave RESET reset_baseFormatSave STORED false)  
251 - Q_PROPERTY(bool overwrite READ get_overwrite WRITE set_overwrite RESET reset_overwrite STORED false)  
252 -  
253 - 224 +
  225 + // Training parameters
  226 + Q_PROPERTY(int numStages READ get_numStages WRITE set_numStages RESET reset_numStages STORED false)
  227 + Q_PROPERTY(int w READ get_w WRITE set_w RESET reset_w STORED false)
  228 + Q_PROPERTY(int h READ get_h WRITE set_h RESET reset_h STORED false)
  229 + Q_PROPERTY(int numPos READ get_numPos WRITE set_numPos RESET reset_numPos STORED false)
  230 + Q_PROPERTY(int numNeg READ get_numNeg WRITE set_numNeg RESET reset_numNeg STORED false)
  231 + Q_PROPERTY(int precalcValBufSize READ get_precalcValBufSize WRITE set_precalcValBufSize RESET reset_precalcValBufSize STORED false)
  232 + Q_PROPERTY(int precalcIdxBufSize READ get_precalcIdxBufSize WRITE set_precalcIdxBufSize RESET reset_precalcIdxBufSize STORED false)
  233 + Q_PROPERTY(double minHitRate READ get_minHitRate WRITE set_minHitRate RESET reset_minHitRate STORED false)
  234 + Q_PROPERTY(double maxFalseAlarmRate READ get_maxFalseAlarmRate WRITE set_maxFalseAlarmRate RESET reset_maxFalseAlarmRate STORED false)
  235 + Q_PROPERTY(double weightTrimRate READ get_weightTrimRate WRITE set_weightTrimRate RESET reset_weightTrimRate STORED false)
  236 + Q_PROPERTY(int maxDepth READ get_maxDepth WRITE set_maxDepth RESET reset_maxDepth STORED false)
  237 + Q_PROPERTY(int maxWeakCount READ get_maxWeakCount WRITE set_maxWeakCount RESET reset_maxWeakCount STORED false)
  238 + Q_PROPERTY(QString stageType READ get_stageType WRITE set_stageType RESET reset_stageType STORED false)
  239 + Q_PROPERTY(QString featureType READ get_featureType WRITE set_featureType RESET reset_featureType STORED false)
  240 + Q_PROPERTY(QString bt READ get_bt WRITE set_bt RESET reset_bt STORED false)
  241 + Q_PROPERTY(QString mode READ get_mode WRITE set_mode RESET reset_mode STORED false)
  242 + Q_PROPERTY(bool show READ get_show WRITE set_show RESET reset_show STORED false)
  243 + Q_PROPERTY(bool baseFormatSave READ get_baseFormatSave WRITE set_baseFormatSave RESET reset_baseFormatSave STORED false)
  244 + Q_PROPERTY(bool overwrite READ get_overwrite WRITE set_overwrite RESET reset_overwrite STORED false)
  245 +
  246 +
254 BR_PROPERTY(QString, model, "FrontalFace") 247 BR_PROPERTY(QString, model, "FrontalFace")
255 BR_PROPERTY(int, minSize, 64) 248 BR_PROPERTY(int, minSize, 64)
256 BR_PROPERTY(bool, ROCMode, false) 249 BR_PROPERTY(bool, ROCMode, false)
257 -  
258 - // Training parameters - Default values provided trigger OpenCV defaults  
259 - BR_PROPERTY(int, numStages, -1)  
260 - BR_PROPERTY(int,w,-1)  
261 - BR_PROPERTY(int,h,-1)  
262 - BR_PROPERTY(int,numPos,-1)  
263 - BR_PROPERTY(int,numNeg,-1)  
264 - BR_PROPERTY(int,precalcValBufSize,-1)  
265 - BR_PROPERTY(int,precalcIdxBufSize,-1)  
266 - BR_PROPERTY(double,minHitRate,-1)  
267 - BR_PROPERTY(double,maxFalseAlarmRate,-1)  
268 - BR_PROPERTY(double,weightTrimRate,-1)  
269 - BR_PROPERTY(int,maxDepth,-1)  
270 - BR_PROPERTY(int,maxWeakCount,-1)  
271 - BR_PROPERTY(QString,stageType,"")  
272 - BR_PROPERTY(QString,featureType,"")  
273 - BR_PROPERTY(QString,bt,"")  
274 - BR_PROPERTY(QString,mode,"")  
275 - BR_PROPERTY(bool,show,false)  
276 - BR_PROPERTY(bool,baseFormatSave,false)  
277 - BR_PROPERTY(bool,overwrite,false)  
278 - 250 +
  251 + // Training parameters - Default values provided trigger OpenCV defaults
  252 + BR_PROPERTY(int, numStages, -1)
  253 + BR_PROPERTY(int,w,-1)
  254 + BR_PROPERTY(int,h,-1)
  255 + BR_PROPERTY(int,numPos,-1)
  256 + BR_PROPERTY(int,numNeg,-1)
  257 + BR_PROPERTY(int,precalcValBufSize,-1)
  258 + BR_PROPERTY(int,precalcIdxBufSize,-1)
  259 + BR_PROPERTY(double,minHitRate,-1)
  260 + BR_PROPERTY(double,maxFalseAlarmRate,-1)
  261 + BR_PROPERTY(double,weightTrimRate,-1)
  262 + BR_PROPERTY(int,maxDepth,-1)
  263 + BR_PROPERTY(int,maxWeakCount,-1)
  264 + BR_PROPERTY(QString,stageType,"")
  265 + BR_PROPERTY(QString,featureType,"")
  266 + BR_PROPERTY(QString,bt,"")
  267 + BR_PROPERTY(QString,mode,"")
  268 + BR_PROPERTY(bool,show,false)
  269 + BR_PROPERTY(bool,baseFormatSave,false)
  270 + BR_PROPERTY(bool,overwrite,false)
  271 +
279 272
280 Resource<CascadeClassifier> cascadeResource; 273 Resource<CascadeClassifier> cascadeResource;
281 274
@@ -283,138 +276,138 @@ class CascadeTransform : public MetaTransform @@ -283,138 +276,138 @@ class CascadeTransform : public MetaTransform
283 { 276 {
284 cascadeResource.setResourceMaker(new CascadeResourceMaker(model)); 277 cascadeResource.setResourceMaker(new CascadeResourceMaker(model));
285 } 278 }
286 -  
287 - // Train transform  
288 - void train(const TemplateList& data){  
289 - if (overwrite){  
290 - QDir dataDir(model);  
291 - if (dataDir.exists()){  
292 - dataDir.removeRecursively();  
293 - QDir::current().mkdir(model);  
294 - }  
295 - }  
296 -  
297 - FileList files = data.files();  
298 -  
299 -  
300 - // Open positive and negative list files  
301 - QString posFName = "pos.txt";  
302 - QString negFName = "neg.txt";  
303 - QFile posFile(posFName);  
304 - QFile negFile(negFName);  
305 - posFile.open(QIODevice::WriteOnly | QIODevice::Text);  
306 - negFile.open(QIODevice::WriteOnly | QIODevice::Text);  
307 - QTextStream posStream(&posFile);  
308 - QTextStream negStream(&negFile);  
309 -  
310 -  
311 - const QString endln = "\r\n";  
312 -  
313 - int posCount = 0;  
314 - int negCount = 0;  
315 -  
316 - bool buildPos = false; // If true, build positive vector from single image  
317 -  
318 - trainParams params;  
319 -  
320 - // Fill in from params (param defaults are same as struct defaults, so no checks are needed)  
321 - params.numStages = numStages;  
322 - params.w = w;  
323 - params.h = h;  
324 - params.numPos = numPos;  
325 - params.numNeg = numNeg;  
326 - params.precalcValBufSize = precalcValBufSize;  
327 - params.precalcIdxBufSize = precalcIdxBufSize;  
328 - params.minHitRate = minHitRate;  
329 - params.maxFalseAlarmRate = maxFalseAlarmRate;  
330 - params.weightTrimRate = weightTrimRate;  
331 - params.maxDepth = maxDepth;  
332 - params.maxWeakCount = maxWeakCount;  
333 - params.stageType = stageType;  
334 - params.featureType = featureType;  
335 - params.bt = bt;  
336 - params.mode = mode;  
337 - params.show = show;  
338 - params.baseFormatSave = baseFormatSave;  
339 - if (params.w < 0) params.w = minSize;  
340 - if (params.h < 0) params.h = minSize;  
341 -  
342 - for (int i = 0; i < files.length(); i++){  
343 - File f = files[i];  
344 - if (f.localKeys().contains("training-set")){  
345 - QString tset = f.localMetadata()["training-set"].toString().toLower();  
346 -  
347 - // Negative samples  
348 - if (tset == "neg"){  
349 - if (negCount > 0) negStream<<endln;  
350 - negStream << f.path() << foldersep << f.fileName();  
351 - negCount++;  
352 -  
353 - // Positive samples for crop/rescale  
354 - }else if (tset == "pos"){  
355 -  
356 - if (posCount > 0) posStream<<endln;  
357 - QString rects = "";  
358 -  
359 - // Extract rectangles  
360 - for (int j = 0; j < f.rects().length(); j++){  
361 - rects += rectToString(f.rects()[j]);  
362 - posCount++;  
363 - }  
364 - if (f.rects().length() > 0)  
365 - posStream << f.path() << foldersep << f.fileName() << " " << f.rects().length() << " " << rects;  
366 -  
367 - // Single positive sample for background removal and overlay on negatives  
368 - }else if (tset == "pos-base"){  
369 -  
370 - buildPos = true;  
371 - params.img = f.path() + foldersep + f.fileName();  
372 -  
373 - // Parse settings (unique to this one tag)  
374 - if (f.localKeys().contains("num")) params.num = f.localMetadata()["num"].toInt();  
375 - if (f.localKeys().contains("bgcolor")) params.bgcolor = f.localMetadata()["bgcolor"].toInt();  
376 - if (f.localKeys().contains("bgthresh")) params.bgthresh = f.localMetadata()["bgthresh"].toInt();  
377 - if (f.localKeys().contains("inv")) params.inv = f.localMetadata()["inv"].toBool();  
378 - if (f.localKeys().contains("randinv")) params.randinv = f.localMetadata()["randinv"].toBool();  
379 - if (f.localKeys().contains("maxidev")) params.maxidev = f.localMetadata()["maxidev"].toInt();  
380 - if (f.localKeys().contains("maxxangle")) params.maxxangle = f.localMetadata()["maxxangle"].toDouble();  
381 - if (f.localKeys().contains("maxyangle")) params.maxyangle = f.localMetadata()["maxyangle"].toDouble();  
382 - if (f.localKeys().contains("maxzangle")) params.maxzangle = f.localMetadata()["maxzangle"].toDouble();  
383 - }  
384 - }  
385 -  
386 -  
387 - // Fill in remaining params conditionally  
388 - posFile.close();  
389 - negFile.close();  
390 - if (buildPos){  
391 - if (params.numPos < 0){  
392 - if (params.num > 0) params.numPos = (int)(params.num*.95);  
393 - else params.numPos = 950;  
394 - posFile.remove();  
395 - }  
396 - }else{  
397 - params.info = posFName;  
398 - if (params.numPos < 0){  
399 - params.numPos = (int)(posCount*.95);  
400 - }  
401 - }  
402 - params.bg = negFName;  
403 - params.data = model;  
404 - if (params.num < 0){  
405 - params.num = posCount;  
406 - }  
407 - if (params.numNeg < 0){  
408 - params.numNeg = negCount*10;  
409 - }  
410 -  
411 -  
412 - genSamples(params);  
413 - trainCascade(params);  
414 - if (posFile.exists()) posFile.remove();  
415 - negFile.remove();  
416 - }  
417 - 279 +
  280 + // Train transform
  281 + void train(const TemplateList& data){
  282 + if (overwrite){
  283 + QDir dataDir(model);
  284 + if (dataDir.exists()){
  285 + dataDir.removeRecursively();
  286 + QDir::current().mkdir(model);
  287 + }
  288 + }
  289 +
  290 + FileList files = data.files();
  291 +
  292 +
  293 + // Open positive and negative list files
  294 + QString posFName = "pos.txt";
  295 + QString negFName = "neg.txt";
  296 + QFile posFile(posFName);
  297 + QFile negFile(negFName);
  298 + posFile.open(QIODevice::WriteOnly | QIODevice::Text);
  299 + negFile.open(QIODevice::WriteOnly | QIODevice::Text);
  300 + QTextStream posStream(&posFile);
  301 + QTextStream negStream(&negFile);
  302 +
  303 +
  304 + const QString endln = "\r\n";
  305 +
  306 + int posCount = 0;
  307 + int negCount = 0;
  308 +
  309 + bool buildPos = false; // If true, build positive vector from single image
  310 +
  311 + TrainParams params;
  312 +
  313 + // Fill in from params (param defaults are same as struct defaults, so no checks are needed)
  314 + params.numStages = numStages;
  315 + params.w = w;
  316 + params.h = h;
  317 + params.numPos = numPos;
  318 + params.numNeg = numNeg;
  319 + params.precalcValBufSize = precalcValBufSize;
  320 + params.precalcIdxBufSize = precalcIdxBufSize;
  321 + params.minHitRate = minHitRate;
  322 + params.maxFalseAlarmRate = maxFalseAlarmRate;
  323 + params.weightTrimRate = weightTrimRate;
  324 + params.maxDepth = maxDepth;
  325 + params.maxWeakCount = maxWeakCount;
  326 + params.stageType = stageType;
  327 + params.featureType = featureType;
  328 + params.bt = bt;
  329 + params.mode = mode;
  330 + params.show = show;
  331 + params.baseFormatSave = baseFormatSave;
  332 + if (params.w < 0) params.w = minSize;
  333 + if (params.h < 0) params.h = minSize;
  334 +
  335 + for (int i = 0; i < files.length(); i++){
  336 + File f = files[i];
  337 + if (f.localKeys().contains("training-set")){
  338 + QString tset = f.localMetadata()["training-set"].toString().toLower();
  339 +
  340 + // Negative samples
  341 + if (tset == "neg"){
  342 + if (negCount > 0) negStream<<endln;
  343 + negStream << f.path() << QDir::separator() << f.fileName();
  344 + negCount++;
  345 +
  346 + // Positive samples for crop/rescale
  347 + }else if (tset == "pos"){
  348 +
  349 + if (posCount > 0) posStream<<endln;
  350 + QString rects = "";
  351 +
  352 + // Extract rectangles
  353 + for (int j = 0; j < f.rects().length(); j++){
  354 + rects += rectToString(f.rects()[j]);
  355 + posCount++;
  356 + }
  357 + if (f.rects().length() > 0)
  358 + posStream << f.path() << QDir::separator() << f.fileName() << " " << f.rects().length() << " " << rects;
  359 +
  360 + // Single positive sample for background removal and overlay on negatives
  361 + }else if (tset == "pos-base"){
  362 +
  363 + buildPos = true;
  364 + params.img = f.path() + QDir::separator() + f.fileName();
  365 +
  366 + // Parse settings (unique to this one tag)
  367 + if (f.localKeys().contains("num")) params.num = f.localMetadata()["num"].toInt();
  368 + if (f.localKeys().contains("bgcolor")) params.bgcolor = f.localMetadata()["bgcolor"].toInt();
  369 + if (f.localKeys().contains("bgthresh")) params.bgthresh = f.localMetadata()["bgthresh"].toInt();
  370 + if (f.localKeys().contains("inv")) params.inv = f.localMetadata()["inv"].toBool();
  371 + if (f.localKeys().contains("randinv")) params.randinv = f.localMetadata()["randinv"].toBool();
  372 + if (f.localKeys().contains("maxidev")) params.maxidev = f.localMetadata()["maxidev"].toInt();
  373 + if (f.localKeys().contains("maxxangle")) params.maxxangle = f.localMetadata()["maxxangle"].toDouble();
  374 + if (f.localKeys().contains("maxyangle")) params.maxyangle = f.localMetadata()["maxyangle"].toDouble();
  375 + if (f.localKeys().contains("maxzangle")) params.maxzangle = f.localMetadata()["maxzangle"].toDouble();
  376 + }
  377 + }
  378 + }
  379 +
  380 + // Fill in remaining params conditionally
  381 + posFile.close();
  382 + negFile.close();
  383 + if (buildPos){
  384 + if (params.numPos < 0){
  385 + if (params.num > 0) params.numPos = (int)(params.num*.95);
  386 + else params.numPos = 950;
  387 + posFile.remove();
  388 + }
  389 + }else{
  390 + params.info = posFName;
  391 + if (params.numPos < 0){
  392 + params.numPos = (int)(posCount*.95);
  393 + }
  394 + }
  395 + params.bg = negFName;
  396 + params.data = model;
  397 + if (params.num < 0){
  398 + params.num = posCount;
  399 + }
  400 + if (params.numNeg < 0){
  401 + params.numNeg = negCount*10;
  402 + }
  403 +
  404 +
  405 + genSamples(params);
  406 + trainCascade(params);
  407 + if (posFile.exists()) posFile.remove();
  408 + negFile.remove();
  409 + }
  410 +
418 411
419 void project(const Template &src, Template &dst) const 412 void project(const Template &src, Template &dst) const
420 { 413 {