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 19 #include "openbr_internal.h"
20 20 #include "openbr/core/opencvutils.h"
21 21 #include "openbr/core/resource.h"
22   -#include <QtXml>
23 22 #include <stdlib.h>
24 23  
25   -#ifndef _win32
26   - const QString foldersep = "/";
27   -#else
28   - const QString foldersep = "\\";
29   -#endif
30   -
31 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 174 class CascadeResourceMaker : public ResourceMaker<CascadeClassifier>
182 175 {
183 176 QString file;
... ... @@ -185,26 +178,26 @@ class CascadeResourceMaker : public ResourceMaker&lt;CascadeClassifier&gt;
185 178 public:
186 179 CascadeResourceMaker(const QString &model)
187 180 {
188   - file = Globals->sdkPath + "/share/openbr/models/";
  181 + file = Globals->sdkPath + "/share/openbr/models/";
189 182 if (model == "Ear") file += "haarcascades/haarcascade_ear.xml";
190 183 else if (model == "Eye") file += "haarcascades/haarcascade_eye_tree_eyeglasses.xml";
191 184 else if (model == "FrontalFace") file += "haarcascades/haarcascade_frontalface_alt2.xml";
192 185 else if (model == "ProfileFace") file += "haarcascades/haarcascade_profileface.xml";
193 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 202 private:
210 203 CascadeClassifier *make() const
... ... @@ -228,54 +221,54 @@ class CascadeTransform : public MetaTransform
228 221 Q_PROPERTY(QString model READ get_model WRITE set_model RESET reset_model STORED false)
229 222 Q_PROPERTY(int minSize READ get_minSize WRITE set_minSize RESET reset_minSize STORED false)
230 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 247 BR_PROPERTY(QString, model, "FrontalFace")
255 248 BR_PROPERTY(int, minSize, 64)
256 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 273 Resource<CascadeClassifier> cascadeResource;
281 274  
... ... @@ -283,138 +276,138 @@ class CascadeTransform : public MetaTransform
283 276 {
284 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 412 void project(const Template &src, Template &dst) const
420 413 {
... ...