Commit 570e3750cb8fdb927f36c825ef8825e3da19f51f

Authored by Brendan Klare
2 parents b101367f aff1aa31

Merge branch 'master' of https://github.com/biometrics/openbr

openbr/plugins/algorithms.cpp
... ... @@ -46,12 +46,13 @@ class AlgorithmsInitializer : public Initializer
46 46 Globals->abbreviations.insert("CropFace", "Open+Cvt(Gray)+Cascade(FrontalFace)+ASEFEyes+Affine(128,128,0.25,0.35)");
47 47  
48 48 // Video
49   - Globals->abbreviations.insert("DisplayVideo", "Stream([FPSLimit(30)+Show(false,[FrameNumber])+Discard])");
50   - Globals->abbreviations.insert("PerFrameDetection", "Stream([SaveMat(original)+Cvt(Gray)+Cascade(FrontalFace)+ASEFEyes+RestoreMat(original)+Draw(inPlace=true),Show(false,[FrameNumber])+Discard])");
51   - Globals->abbreviations.insert("AgeGenderDemo", "Stream([SaveMat(original)+Cvt(Gray)+Cascade(FrontalFace)+Expand+<FaceClassificationRegistration>+<FaceClassificationExtraction>+<AgeRegressor>/<GenderClassifier>+Discard+RestoreMat(original)+Draw(inPlace=true)+DrawPropertiesPoint([Age,Gender],Affine_0,inPlace=true)+SaveMat(original)+Discard+Contract,RestoreMat(original)+FPSCalc+Show(false,[AvgFPS,Age,Gender])+Discard])");
52   - Globals->abbreviations.insert("HOG", "Stream([DropFrames(5)+Cvt(Gray)+KeyPointDetector(SIFT)+ROI+Expand+Resize(32,32)+Gradient+RectRegions+Bin(0,360,8)+Hist(8)+Cat])+Contract+CatRows+KMeans(500)+Hist(500)+SVM");
53   - Globals->abbreviations.insert("HOF", "Stream([DropFrames(5)+KeyPointDetector(SIFT),AggregateFrames(2),OpticalFlow+ROI+Expand+Resize(32,32)+Gradient+RectRegions+Bin(0,360,8)+Hist(8)+Cat])+Contract+CatRows+KMeans(500)+Hist(500)");
54   - Globals->abbreviations.insert("HOGHOF", "Stream([DropFrames(5)+Cvt(Gray),KeyPointDetector(SIFT),AggregateFrames(2),(OpticalFlow+Gradient+Bin(0,360,8)+ROI+Hist(8))/(First+Gradient+Bin(0,360,8)+ROI+Hist(8)),CatCols])+Contract+CatRows+KMeans(500)+Hist(500)");
  49 + Globals->abbreviations.insert("DisplayVideo", "Stream(FPSLimit(30)+Show(false,[FrameNumber])+Discard)");
  50 + Globals->abbreviations.insert("PerFrameDetection", "Stream(SaveMat(original)+Cvt(Gray)+Cascade(FrontalFace)+ASEFEyes+RestoreMat(original)+Draw(inPlace=true)+Show(false,[FrameNumber])+Discard)");
  51 + Globals->abbreviations.insert("AgeGenderDemo", "Stream(SaveMat(original)+Cvt(Gray)+Cascade(FrontalFace)+Expand+<FaceClassificationRegistration>+<FaceClassificationExtraction>+<AgeRegressor>/<GenderClassifier>+Discard+RestoreMat(original)+Draw(inPlace=true)+DrawPropertiesPoint([Age,Gender],Affine_0,inPlace=true)+SaveMat(original)+Discard+Contract+RestoreMat(original)+FPSCalc+Show(false,[AvgFPS,Age,Gender])+Discard)");
  52 +
  53 + Globals->abbreviations.insert("HOG", "Stream(DropFrames(5)+Cvt(Gray)+KeyPointDetector(SIFT)+ROI+Expand+Resize(32,32)+Gradient+RectRegions+Bin(0,360,8)+Hist(8)+Cat)+Contract+CatRows+KMeans(500)+Hist(500)+SVM");
  54 + Globals->abbreviations.insert("HOF", "Stream(DropFrames(5)+KeyPointDetector(SIFT)+AggregateFrames(2)+OpticalFlow+ROI+Expand+Resize(32,32)+Gradient+RectRegions+Bin(0,360,8)+Hist(8)+Cat)+Contract+CatRows+KMeans(500)+Hist(500)");
  55 + Globals->abbreviations.insert("HOGHOF", "Stream(DropFrames(5)+Cvt(Gray),KeyPointDetector(SIFT)+AggregateFrames(2)+(OpticalFlow+Gradient+Bin(0,360,8)+ROI+Hist(8))/(First+Gradient+Bin(0,360,8)+ROI+Hist(8))+CatCols)+Contract+CatRows+KMeans(500)+Hist(500)");
55 56  
56 57 // Generic Image Processing
57 58 Globals->abbreviations.insert("SIFT", "Open+KeyPointDetector(SIFT)+KeyPointDescriptor(SIFT):KeyPointMatcher(BruteForce)");
... ...
openbr/plugins/meta.cpp
... ... @@ -614,6 +614,11 @@ public:
614 614  
615 615 void train(const TemplateList &data)
616 616 {
  617 + if (!transform->trainable) {
  618 + qWarning("Attempted to train untrainable transform, nothing will happen.");
  619 + return;
  620 + }
  621 +
617 622 transform->train(data);
618 623 }
619 624  
... ... @@ -628,7 +633,6 @@ public:
628 633 else dst = output[0];
629 634 }
630 635  
631   -
632 636 // For each input template, form a single element TemplateList, push all those
633 637 // lists through transform, and form dst by concatenating the results.
634 638 // Process the single elemnt templates in parallel if parallelism is enabled.
... ... @@ -677,7 +681,6 @@ public:
677 681  
678 682 void init()
679 683 {
680   -
681 684 if (transform && transform->timeVarying())
682 685 transform = new br::TimeInvariantWrapperTransform(transform);
683 686 }
... ...
openbr/plugins/openbr_internal.h
... ... @@ -122,7 +122,10 @@ public:
122 122  
123 123 TimeInvariantWrapperTransform(Transform * basis) : transformSource(new TransformCopier(basis))
124 124 {
  125 + if (!basis)
  126 + qFatal("TimeInvariantWrapper created with NULL transform");
125 127 baseTransform = basis;
  128 + trainable = basis->trainable;
126 129 }
127 130  
128 131 virtual void project(const Template &src, Template &dst) const
... ... @@ -132,7 +135,6 @@ public:
132 135 transformSource.release(aTransform);
133 136 }
134 137  
135   -
136 138 void project(const TemplateList &src, TemplateList &dst) const
137 139 {
138 140 Transform * aTransform = transformSource.acquire();
... ...
openbr/plugins/stream.cpp
... ... @@ -649,7 +649,7 @@ public:
649 649 class ProcessingStage
650 650 {
651 651 public:
652   - friend class StreamTransform;
  652 + friend class DirectStreamTransform;
653 653 public:
654 654 ProcessingStage(int nThreads = 1)
655 655 {
... ... @@ -1015,17 +1015,20 @@ public:
1015 1015 };
1016 1016  
1017 1017  
1018   -class StreamTransform : public CompositeTransform
  1018 +
  1019 +class DirectStreamTransform : public CompositeTransform
1019 1020 {
1020 1021 Q_OBJECT
1021 1022 public:
1022 1023 Q_PROPERTY(int activeFrames READ get_activeFrames WRITE set_activeFrames RESET reset_activeFrames)
1023 1024 BR_PROPERTY(int, activeFrames, 100)
1024 1025  
  1026 + friend class StreamTransfrom;
  1027 +
1025 1028 void train(const TemplateList & data)
1026 1029 {
1027 1030 if (!trainable) {
1028   - qWarning("How did this happen? You're training a nontrainable transform.");
  1031 + qWarning("Attempted to train untrainable transform, nothing will happen.");
1029 1032 return;
1030 1033 }
1031 1034 qFatal("Stream train is currently not implemented.");
... ... @@ -1115,6 +1118,10 @@ public:
1115 1118 {
1116 1119 if (transforms.isEmpty()) return;
1117 1120  
  1121 + for (int i=0; i < processingStages.size();i++)
  1122 + delete processingStages[i];
  1123 + processingStages.clear();
  1124 +
1118 1125 // call CompositeTransform::init so that trainable is set
1119 1126 // correctly.
1120 1127 CompositeTransform::init();
... ... @@ -1190,12 +1197,13 @@ public:
1190 1197 collectionStage->nextStage = readStage;
1191 1198 }
1192 1199  
1193   - ~StreamTransform()
  1200 + ~DirectStreamTransform()
1194 1201 {
1195 1202 // Delete all the stages
1196 1203 for (int i = 0; i < processingStages.size(); i++) {
1197 1204 delete processingStages[i];
1198 1205 }
  1206 + processingStages.clear();
1199 1207 }
1200 1208  
1201 1209 protected:
... ... @@ -1237,12 +1245,150 @@ protected:
1237 1245 }
1238 1246 };
1239 1247  
1240   -QHash<QObject *, QThreadPool *> StreamTransform::pools;
1241   -QMutex StreamTransform::poolsAccess;
  1248 +QHash<QObject *, QThreadPool *> DirectStreamTransform::pools;
  1249 +QMutex DirectStreamTransform::poolsAccess;
  1250 +
  1251 +BR_REGISTER(Transform, DirectStreamTransform)
  1252 +
  1253 +;
  1254 +
  1255 +class StreamTransform : public TimeVaryingTransform
  1256 +{
  1257 + Q_OBJECT
  1258 +
  1259 +public:
  1260 + StreamTransform() : TimeVaryingTransform(false)
  1261 + {
  1262 + }
  1263 +
  1264 + Q_PROPERTY(br::Transform *transform READ get_transform WRITE set_transform STORED false)
  1265 + Q_PROPERTY(int activeFrames READ get_activeFrames WRITE set_activeFrames RESET reset_activeFrames)
  1266 + BR_PROPERTY(br::Transform *, transform, NULL)
  1267 + BR_PROPERTY(int, activeFrames, 100)
  1268 +
  1269 + bool timeVarying() const { return true; }
  1270 +
  1271 + void project(const Template &src, Template &dst) const
  1272 + {
  1273 + basis.project(src,dst);
  1274 + }
  1275 +
  1276 + void projectUpdate(const Template &src, Template &dst)
  1277 + {
  1278 + basis.projectUpdate(src,dst);
  1279 + }
  1280 + void projectUpdate(const TemplateList & src, TemplateList & dst)
  1281 + {
  1282 + basis.projectUpdate(src,dst);
  1283 + }
  1284 +
  1285 +
  1286 + void train(const TemplateList & data)
  1287 + {
  1288 + basis.train(data);
  1289 + }
  1290 +
  1291 + virtual void finalize(TemplateList & output)
  1292 + {
  1293 + (void) output;
  1294 + // Nothing in particular to do here, stream calls finalize
  1295 + // on all child transforms as part of projectUpdate
  1296 + }
  1297 +
  1298 + // reinterpret transform, set up the actual stream. We can only reinterpret pipes
  1299 + void init()
  1300 + {
  1301 + if (!transform)
  1302 + return;
  1303 + trainable = transform->trainable;
  1304 +
  1305 + basis.setParent(this->parent());
  1306 + basis.transforms.clear();
  1307 + basis.activeFrames = this->activeFrames;
  1308 +
  1309 + // We need at least a CompositeTransform * to acess transform's children.
  1310 + CompositeTransform * downcast = dynamic_cast<CompositeTransform *> (transform);
  1311 +
  1312 + // If this isn't even a composite transform, or it's not a pipe, just set up
  1313 + // basis with 1 stage.
  1314 + if (!downcast || QString(transform->metaObject()->className()) != "br::PipeTransform")
  1315 + {
  1316 + basis.transforms.append(transform);
  1317 + basis.init();
  1318 + return;
  1319 + }
  1320 + if (downcast->transforms.empty())
  1321 + {
  1322 + qWarning("Trying to set up empty stream");
  1323 + basis.init();
  1324 + return;
  1325 + }
  1326 +
  1327 + // OK now we will regroup downcast's children
  1328 + QList<QList<Transform *> > sets;
  1329 + sets.append(QList<Transform *> ());
  1330 + sets.last().append(downcast->transforms[0]);
  1331 + if (downcast->transforms[0]->timeVarying())
  1332 + sets.append(QList<Transform *> ());
  1333 +
  1334 + for (int i=1;i < downcast->transforms.size(); i++) {
  1335 + // If this is time varying it becomse its own stage
  1336 + if (downcast->transforms[i]->timeVarying()) {
  1337 + // If a set was already active, we add another one
  1338 + if (!sets.last().empty()) {
  1339 + sets.append(QList<Transform *>());
  1340 + }
  1341 + // add the item
  1342 + sets.last().append(downcast->transforms[i]);
  1343 + // Add another set to indicate separation.
  1344 + sets.append(QList<Transform *>());
  1345 + }
  1346 + // otherwise, we can combine non time-varying stages
  1347 + else {
  1348 + sets.last().append(downcast->transforms[i]);
  1349 + }
  1350 +
  1351 + }
  1352 + if (sets.last().empty())
  1353 + sets.removeLast();
  1354 +
  1355 + QList<Transform *> transform_set;
  1356 + transform_set.reserve(sets.size());
  1357 + for (int i=0; i < sets.size(); i++) {
  1358 + // If this is a single transform set, we add that to the list
  1359 + if (sets[i].size() == 1 ) {
  1360 + transform_set.append(sets[i].at(0));
  1361 + }
  1362 + //otherwise we build a pipe
  1363 + else {
  1364 + CompositeTransform * pipe = dynamic_cast<CompositeTransform *>(Transform::make("Pipe([])", this));
  1365 + pipe->transforms = sets[i];
  1366 + pipe->init();
  1367 + transform_set.append(pipe);
  1368 + }
  1369 + }
  1370 +
  1371 + basis.transforms = transform_set;
  1372 + basis.init();
  1373 + }
  1374 +
  1375 + Transform * smartCopy()
  1376 + {
  1377 + // We just want the DirectStream to begin with, so just return a copy of that.
  1378 + DirectStreamTransform * res = (DirectStreamTransform *) basis.smartCopy();
  1379 + res->activeFrames = this->activeFrames;
  1380 + return res;
  1381 + }
  1382 +
  1383 +
  1384 +private:
  1385 + DirectStreamTransform basis;
  1386 +};
1242 1387  
1243 1388 BR_REGISTER(Transform, StreamTransform)
1244 1389  
1245 1390  
  1391 +
1246 1392 } // namespace br
1247 1393  
1248 1394 #include "stream.moc"
... ...
1   -Subproject commit c11ff0f0bb451fb5576bd4b8122c32278e52042a
  1 +Subproject commit a73d51013ea05f263e88a28539393159fff2183e
... ...