Commit decda7bc5277e839d1bcf3e78754f2400878c969

Authored by Scott Klum
1 parent d2de26db

Revert "Merge pull request #320 from biometrics/block_compression"

This reverts commit cb35ce836903f6baa19cf577932e6d2b92f3fedb, reversing
changes made to f2f88b8c72d0c86d66232c2cb26a39ab40bca4f3.
openbr/core/common.cpp
@@ -16,32 +16,21 @@ @@ -16,32 +16,21 @@
16 16
17 #include "common.h" 17 #include "common.h"
18 #include <QMutex> 18 #include <QMutex>
19 -#include <RandomLib/Random.hpp>  
20 19
21 using namespace std; 20 using namespace std;
22 21
23 -static RandomLib::Random g_rand;  
24 -static QMutex rngLock;  
25 -  
26 /**** GLOBAL ****/ 22 /**** GLOBAL ****/
27 void Common::seedRNG() { 23 void Common::seedRNG() {
28 - QMutexLocker lock(&rngLock); 24 + static QMutex seedControl;
  25 + QMutexLocker lock(&seedControl);
29 26
30 static bool seeded = false; 27 static bool seeded = false;
31 if (!seeded) { 28 if (!seeded) {
32 srand(0); // We seed with 0 instead of time(NULL) to have reproducible randomness 29 srand(0); // We seed with 0 instead of time(NULL) to have reproducible randomness
33 seeded = true; 30 seeded = true;
34 - g_rand.Reseed(0);  
35 } 31 }
36 } 32 }
37 33
38 -double Common::randN()  
39 -{  
40 - QMutexLocker lock(&rngLock);  
41 -  
42 - return g_rand.FloatN();  
43 -}  
44 -  
45 QList<int> Common::RandSample(int n, int max, int min, bool unique) 34 QList<int> Common::RandSample(int n, int max, int min, bool unique)
46 { 35 {
47 QList<int> samples; samples.reserve(n); 36 QList<int> samples; samples.reserve(n);
openbr/core/common.h
@@ -220,9 +220,6 @@ double KernelDensityEstimation(const V&lt;T&gt; &amp;vals, double x, double h) @@ -220,9 +220,6 @@ double KernelDensityEstimation(const V&lt;T&gt; &amp;vals, double x, double h)
220 return y / (vals.size() * h); 220 return y / (vals.size() * h);
221 } 221 }
222 222
223 -// Return a random number, uniformly distributed over 0,1  
224 -double randN();  
225 -  
226 /*! 223 /*!
227 * \brief Returns a vector of n integers sampled in the range <min, max]. 224 * \brief Returns a vector of n integers sampled in the range <min, max].
228 * 225 *
@@ -239,14 +236,19 @@ QList&lt;int&gt; RandSample(int n, const QSet&lt;int&gt; &amp;values, bool unique = false); @@ -239,14 +236,19 @@ QList&lt;int&gt; RandSample(int n, const QSet&lt;int&gt; &amp;values, bool unique = false);
239 template <typename T> 236 template <typename T>
240 QList<int> RandSample(int n, const QList<T> &weights, bool unique = false) 237 QList<int> RandSample(int n, const QList<T> &weights, bool unique = false)
241 { 238 {
  239 + static bool seeded = false;
  240 + if (!seeded) {
  241 + srand(time(NULL));
  242 + seeded = true;
  243 + }
  244 +
242 QList<T> cdf = CumSum(weights); 245 QList<T> cdf = CumSum(weights);
243 for (int i=0; i<cdf.size(); i++) // Normalize cdf 246 for (int i=0; i<cdf.size(); i++) // Normalize cdf
244 cdf[i] = cdf[i] / cdf.last(); 247 cdf[i] = cdf[i] / cdf.last();
245 248
246 QList<int> samples; samples.reserve(n); 249 QList<int> samples; samples.reserve(n);
247 while (samples.size() < n) { 250 while (samples.size() < n) {
248 - T r = randN();  
249 - 251 + T r = (T)rand() / (T)RAND_MAX;
250 for (int j=0; j<weights.size(); j++) { 252 for (int j=0; j<weights.size(); j++) {
251 if ((r >= cdf[j]) && (r <= cdf[j+1])) { 253 if ((r >= cdf[j]) && (r <= cdf[j+1])) {
252 if (!unique || !samples.contains(j)) 254 if (!unique || !samples.contains(j))
openbr/core/core.cpp
@@ -110,11 +110,9 @@ struct AlgorithmCore @@ -110,11 +110,9 @@ struct AlgorithmCore
110 110
111 void store(const QString &model) const 111 void store(const QString &model) const
112 { 112 {
113 - QtUtils::BlockCompression compressedWrite;  
114 - QFile outFile(model);  
115 - compressedWrite.setBasis(&outFile);  
116 - QDataStream out(&compressedWrite);  
117 - compressedWrite.open(QFile::WriteOnly); 113 + // Create stream
  114 + QByteArray data;
  115 + QDataStream out(&data, QFile::WriteOnly);
118 116
119 // Serialize algorithm to stream 117 // Serialize algorithm to stream
120 transform->serialize(out); 118 transform->serialize(out);
@@ -133,16 +131,18 @@ struct AlgorithmCore @@ -133,16 +131,18 @@ struct AlgorithmCore
133 if (mode == TransformCompare) 131 if (mode == TransformCompare)
134 comparison->serialize(out); 132 comparison->serialize(out);
135 133
136 - compressedWrite.close(); 134 + // Compress and save to file
  135 + QtUtils::writeFile(model, data, -1);
137 } 136 }
138 137
139 void load(const QString &model) 138 void load(const QString &model)
140 { 139 {
141 - QtUtils::BlockCompression compressedRead;  
142 - QFile inFile(model);  
143 - compressedRead.setBasis(&inFile);  
144 - QDataStream in(&compressedRead);  
145 - compressedRead.open(QFile::ReadOnly); 140 + // Load from file and decompress
  141 + QByteArray data;
  142 + QtUtils::readFile(model, data, true);
  143 +
  144 + // Create stream
  145 + QDataStream in(&data, QFile::ReadOnly);
146 146
147 // Load algorithm 147 // Load algorithm
148 transform = QSharedPointer<Transform>(Transform::deserialize(in)); 148 transform = QSharedPointer<Transform>(Transform::deserialize(in));
openbr/core/qtutils.cpp
@@ -500,131 +500,6 @@ QString getAbsolutePath(const QString &amp;filename) @@ -500,131 +500,6 @@ QString getAbsolutePath(const QString &amp;filename)
500 return QFileInfo(filename).absoluteFilePath(); 500 return QFileInfo(filename).absoluteFilePath();
501 } 501 }
502 502
503 -BlockCompression::BlockCompression(QIODevice *_basis)  
504 -{  
505 - blockSize = 100000000;  
506 - setBasis(_basis);  
507 -}  
508 -  
509 -BlockCompression::BlockCompression() { blockSize = 100000000; };  
510 -  
511 -  
512 -bool BlockCompression::open(QIODevice::OpenMode mode)  
513 -{  
514 - this->setOpenMode(mode);  
515 - bool res = basis->open(mode);  
516 -  
517 - if (!res)  
518 - return false;  
519 -  
520 - blockReader.setDevice(basis);  
521 - blockWriter.setDevice(basis);  
522 -  
523 - if (mode & QIODevice::WriteOnly) {  
524 - precompressedBlockWriter = new QBuffer;  
525 - precompressedBlockWriter->open(QIODevice::ReadWrite);  
526 - }  
527 - else if (mode & QIODevice::ReadOnly) {  
528 - QByteArray compressedBlock;  
529 - blockReader >> compressedBlock;  
530 -  
531 - decompressedBlock = qUncompress(compressedBlock);  
532 - decompressedBlockReader.setBuffer(&decompressedBlock);  
533 - decompressedBlockReader.open(QIODevice::ReadOnly);  
534 - }  
535 -  
536 - return true;  
537 -}  
538 -  
539 -void BlockCompression::close()  
540 -{  
541 - // flush output buffer  
542 - if ((openMode() & QIODevice::WriteOnly) && precompressedBlockWriter) {  
543 - QByteArray compressedBlock = qCompress(precompressedBlockWriter->buffer(), -1);  
544 - blockWriter << compressedBlock;  
545 - }  
546 - basis->close();  
547 -}  
548 -  
549 -void BlockCompression::setBasis(QIODevice *_basis)  
550 -{  
551 - basis = _basis;  
552 - blockReader.setDevice(basis);  
553 - blockWriter.setDevice(basis);  
554 -}  
555 -  
556 -// read from current decompressed block, if out of space, read and decompress another  
557 -// block from basis  
558 -qint64 BlockCompression::readData(char *data, qint64 remaining)  
559 -{  
560 - qint64 read = 0;  
561 - while (remaining > 0) {  
562 - qint64 single_read = decompressedBlockReader.read(data, remaining);  
563 - if (single_read == -1)  
564 - qFatal("miss read");  
565 -  
566 - remaining -= single_read;  
567 - read += single_read;  
568 - data += single_read;  
569 -  
570 - // need a new block  
571 - if (remaining > 0) {  
572 - QByteArray compressedBlock;  
573 - blockReader >> compressedBlock;  
574 - if (compressedBlock.size() == 0) {  
575 - return read;  
576 - }  
577 - decompressedBlock = qUncompress(compressedBlock);  
578 -  
579 - decompressedBlockReader.close();  
580 - decompressedBlockReader.setBuffer(&decompressedBlock);  
581 - decompressedBlockReader.open(QIODevice::ReadOnly);  
582 - }  
583 - }  
584 - return blockReader.atEnd() && !basis->isReadable() ? -1 : read;  
585 -}  
586 -  
587 -bool BlockCompression::isSequential() const  
588 -{  
589 - return true;  
590 -}  
591 -  
592 -qint64 BlockCompression::writeData(const char *data, qint64 remaining)  
593 -{  
594 - qint64 written = 0;  
595 -  
596 - while (remaining > 0) {  
597 - // how much more can be put in this buffer?  
598 - qint64 capacity = blockSize - precompressedBlockWriter->pos();  
599 -  
600 - // don't try to write beyond capacity  
601 - qint64 write_size = qMin(capacity, remaining);  
602 -  
603 - qint64 singleWrite = precompressedBlockWriter->write(data, write_size);  
604 - // ignore the error case here, we consdier basis's failure mode the real  
605 - // end case  
606 - if (singleWrite == -1)  
607 - singleWrite = 0;  
608 -  
609 - remaining -= singleWrite;  
610 - data += singleWrite;  
611 - written += singleWrite;  
612 -  
613 - if (remaining > 0) {  
614 - QByteArray compressedBlock = qCompress(precompressedBlockWriter->buffer(), -1);  
615 -  
616 - if (compressedBlock.size() != 0)  
617 - blockWriter << compressedBlock;  
618 -  
619 - delete precompressedBlockWriter;  
620 - precompressedBlockWriter = new QBuffer;  
621 - precompressedBlockWriter->open(QIODevice::ReadWrite);  
622 - }  
623 - }  
624 - return basis->isWritable() ? written : -1;  
625 -}  
626 -  
627 -  
628 503
629 } // namespace QtUtils 504 } // namespace QtUtils
630 505
openbr/core/qtutils.h
@@ -17,7 +17,6 @@ @@ -17,7 +17,6 @@
17 #ifndef QTUTILS_QTUTILS_H 17 #ifndef QTUTILS_QTUTILS_H
18 #define QTUTILS_QTUTILS_H 18 #define QTUTILS_QTUTILS_H
19 19
20 -#include <QBuffer>  
21 #include <QByteArray> 20 #include <QByteArray>
22 #include <QDir> 21 #include <QDir>
23 #include <QFile> 22 #include <QFile>
@@ -94,38 +93,6 @@ namespace QtUtils @@ -94,38 +93,6 @@ namespace QtUtils
94 93
95 /**** Rect Utilities ****/ 94 /**** Rect Utilities ****/
96 float overlap(const QRectF &r, const QRectF &s); 95 float overlap(const QRectF &r, const QRectF &s);
97 -  
98 -  
99 - class BlockCompression : public QIODevice  
100 - {  
101 - public:  
102 - BlockCompression(QIODevice *_basis);  
103 - BlockCompression();  
104 - int blockSize;  
105 - QIODevice *basis;  
106 -  
107 - bool open(QIODevice::OpenMode mode);  
108 -  
109 - void close();  
110 -  
111 - void setBasis(QIODevice *_basis);  
112 -  
113 - QDataStream blockReader;  
114 - QByteArray decompressedBlock;  
115 - QBuffer decompressedBlockReader;  
116 -  
117 - // read from current decompressed block, if out of space, read and decompress another  
118 - // block from basis  
119 - qint64 readData(char *data, qint64 remaining);  
120 -  
121 - bool isSequential() const;  
122 -  
123 - // write to a QByteArray, when max block sized is reached, compress and write  
124 - // it to basis  
125 - QBuffer * precompressedBlockWriter;  
126 - QDataStream blockWriter;  
127 - qint64 writeData(const char *data, qint64 remaining);  
128 - };  
129 } 96 }
130 97
131 #endif // QTUTILS_QTUTILS_H 98 #endif // QTUTILS_QTUTILS_H
openbr/plugins/algorithms.cpp
@@ -31,15 +31,15 @@ class AlgorithmsInitializer : public Initializer @@ -31,15 +31,15 @@ class AlgorithmsInitializer : public Initializer
31 void initialize() const 31 void initialize() const
32 { 32 {
33 // Face 33 // Face
34 - Globals->abbreviations.insert("FaceRecognition", "FaceDetection+FaceRecognitionRegistration+<FaceRecognitionExtraction>+<FaceRecognitionEmbedding>+<FaceRecognitionQuantization>+SetMetadata(AlgorithmID,-1):Unit(ByteL1)");  
35 - Globals->abbreviations.insert("GenderClassification", "FaceDetection+Expand+FaceClassificationRegistration+Expand+<FaceClassificationExtraction>+<GenderClassifier>+Discard");  
36 - Globals->abbreviations.insert("AgeRegression", "FaceDetection+Expand+FaceClassificationRegistration+Expand+<FaceClassificationExtraction>+<AgeRegressor>+Discard"); 34 + Globals->abbreviations.insert("FaceRecognition", "FaceDetection+Expand+<FaceRecognitionRegistration>+Expand+<FaceRecognitionExtraction>+<FaceRecognitionEmbedding>+<FaceRecognitionQuantization>+SetMetadata(AlgorithmID,-1):MatchProbability(ByteL1)");
  35 + Globals->abbreviations.insert("GenderClassification", "FaceDetection+Expand+<FaceClassificationRegistration>+Expand+<FaceClassificationExtraction>+<GenderClassifier>+Discard");
  36 + Globals->abbreviations.insert("AgeRegression", "FaceDetection+Expand+<FaceClassificationRegistration>+Expand+<FaceClassificationExtraction>+<AgeRegressor>+Discard");
37 Globals->abbreviations.insert("FaceQuality", "Open+Expand+Cascade(FrontalFace)+ASEFEyes+Affine(64,64,0.25,0.35)+ImageQuality+Cvt(Gray)+DFFS+Discard"); 37 Globals->abbreviations.insert("FaceQuality", "Open+Expand+Cascade(FrontalFace)+ASEFEyes+Affine(64,64,0.25,0.35)+ImageQuality+Cvt(Gray)+DFFS+Discard");
38 Globals->abbreviations.insert("MedianFace", "Open+Expand+Cascade(FrontalFace)+ASEFEyes+Affine(256,256,0.37,0.45)+Center(Median)"); 38 Globals->abbreviations.insert("MedianFace", "Open+Expand+Cascade(FrontalFace)+ASEFEyes+Affine(256,256,0.37,0.45)+Center(Median)");
39 Globals->abbreviations.insert("BlurredFaceDetection", "Open+LimitSize(1024)+SkinMask/(Cvt(Gray)+GradientMask)+And+Morph(Erode,16)+LargestConvexArea"); 39 Globals->abbreviations.insert("BlurredFaceDetection", "Open+LimitSize(1024)+SkinMask/(Cvt(Gray)+GradientMask)+And+Morph(Erode,16)+LargestConvexArea");
40 Globals->abbreviations.insert("DrawFaceDetection", "Open+Cascade(FrontalFace)+Expand+ASEFEyes+Draw(inPlace=true)"); 40 Globals->abbreviations.insert("DrawFaceDetection", "Open+Cascade(FrontalFace)+Expand+ASEFEyes+Draw(inPlace=true)");
41 Globals->abbreviations.insert("ShowFaceDetection", "DrawFaceDetection+Contract+First+Show+Discard"); 41 Globals->abbreviations.insert("ShowFaceDetection", "DrawFaceDetection+Contract+First+Show+Discard");
42 - Globals->abbreviations.insert("DownloadFaceRecognition", "Download+Open+ROI+Cvt(Gray)+Cascade(FrontalFace)+FaceRecognitionRegistration+<FaceRecognitionExtraction>+<FaceRecognitionEmbedding>+<FaceRecognitionQuantization>+SetMetadata(AlgorithmID,-1):Unit(ByteL1)"); 42 + Globals->abbreviations.insert("DownloadFaceRecognition", "Download+Open+ROI+Expand+Cvt(Gray)+Cascade(FrontalFace)+Expand+<FaceRecognitionRegistration>+Expand+<FaceRecognitionExtraction>+<FaceRecognitionEmbedding>+<FaceRecognitionQuantization>+SetMetadata(AlgorithmID,-1):MatchProbability(ByteL1)");
43 Globals->abbreviations.insert("OpenBR", "FaceRecognition"); 43 Globals->abbreviations.insert("OpenBR", "FaceRecognition");
44 Globals->abbreviations.insert("GenderEstimation", "GenderClassification"); 44 Globals->abbreviations.insert("GenderEstimation", "GenderClassification");
45 Globals->abbreviations.insert("AgeEstimation", "AgeRegression"); 45 Globals->abbreviations.insert("AgeEstimation", "AgeRegression");
@@ -50,7 +50,7 @@ class AlgorithmsInitializer : public Initializer @@ -50,7 +50,7 @@ class AlgorithmsInitializer : public Initializer
50 // Video 50 // Video
51 Globals->abbreviations.insert("DisplayVideo", "FPSLimit(30)+Show(false,[FrameNumber])+Discard"); 51 Globals->abbreviations.insert("DisplayVideo", "FPSLimit(30)+Show(false,[FrameNumber])+Discard");
52 Globals->abbreviations.insert("PerFrameDetection", "SaveMat(original)+Cvt(Gray)+Cascade(FrontalFace)+ASEFEyes+RestoreMat(original)+Draw(inPlace=true)+Show(false,[FrameNumber])+Discard"); 52 Globals->abbreviations.insert("PerFrameDetection", "SaveMat(original)+Cvt(Gray)+Cascade(FrontalFace)+ASEFEyes+RestoreMat(original)+Draw(inPlace=true)+Show(false,[FrameNumber])+Discard");
53 - Globals->abbreviations.insert("AgeGenderDemo", "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"); 53 + Globals->abbreviations.insert("AgeGenderDemo", "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");
54 Globals->abbreviations.insert("ShowOpticalFlowField", "SaveMat(original)+AggregateFrames(2)+OpticalFlow(useMagnitude=false)+Grid(100,100)+DrawOpticalFlow+FPSLimit(30)+Show(false)+Discard"); 54 Globals->abbreviations.insert("ShowOpticalFlowField", "SaveMat(original)+AggregateFrames(2)+OpticalFlow(useMagnitude=false)+Grid(100,100)+DrawOpticalFlow+FPSLimit(30)+Show(false)+Discard");
55 Globals->abbreviations.insert("ShowOpticalFlowMagnitude", "AggregateFrames(2)+OpticalFlow+Normalize(Range,false,0,255)+Cvt(Color)+Draw+FPSLimit(30)+Show(false)+Discard"); 55 Globals->abbreviations.insert("ShowOpticalFlowMagnitude", "AggregateFrames(2)+OpticalFlow+Normalize(Range,false,0,255)+Cvt(Color)+Draw+FPSLimit(30)+Show(false)+Discard");
56 Globals->abbreviations.insert("ShowMotionSegmentation", "DropFrames(5)+AggregateFrames(2)+OpticalFlow+CvtUChar+WatershedSegmentation+DrawSegmentation+Draw+FPSLimit(30)+Show(false)+Discard"); 56 Globals->abbreviations.insert("ShowMotionSegmentation", "DropFrames(5)+AggregateFrames(2)+OpticalFlow+CvtUChar+WatershedSegmentation+DrawSegmentation+Draw+FPSLimit(30)+Show(false)+Discard");
@@ -92,11 +92,11 @@ class AlgorithmsInitializer : public Initializer @@ -92,11 +92,11 @@ class AlgorithmsInitializer : public Initializer
92 Globals->abbreviations.insert("DenseHOG", "Gradient+RectRegions(8,8,6,6)+Bin(0,360,8)+Hist(8)"); 92 Globals->abbreviations.insert("DenseHOG", "Gradient+RectRegions(8,8,6,6)+Bin(0,360,8)+Hist(8)");
93 Globals->abbreviations.insert("DenseSIFT", "(Grid(10,10)+SIFTDescriptor(12)+ByRow)"); 93 Globals->abbreviations.insert("DenseSIFT", "(Grid(10,10)+SIFTDescriptor(12)+ByRow)");
94 Globals->abbreviations.insert("DenseSIFT2", "(Grid(5,5)+SIFTDescriptor(12)+ByRow)"); 94 Globals->abbreviations.insert("DenseSIFT2", "(Grid(5,5)+SIFTDescriptor(12)+ByRow)");
95 - Globals->abbreviations.insert("FaceRecognitionRegistration", "ASEFEyes+Affine(88,88,0.25,0.35)"); 95 + Globals->abbreviations.insert("FaceRecognitionRegistration", "(ASEFEyes+Affine(88,88,0.25,0.35)+DownsampleTraining(FTE(DFFS),instances=1))");
96 Globals->abbreviations.insert("FaceRecognitionExtraction", "(Mask+DenseSIFT/DenseLBP+DownsampleTraining(PCA(0.95),instances=1)+Normalize(L2)+Cat)"); 96 Globals->abbreviations.insert("FaceRecognitionExtraction", "(Mask+DenseSIFT/DenseLBP+DownsampleTraining(PCA(0.95),instances=1)+Normalize(L2)+Cat)");
97 Globals->abbreviations.insert("FaceRecognitionEmbedding", "(Dup(12)+RndSubspace(0.05,1)+DownsampleTraining(LDA(0.98),instances=-2)+Cat+DownsampleTraining(PCA(768),instances=1))"); 97 Globals->abbreviations.insert("FaceRecognitionEmbedding", "(Dup(12)+RndSubspace(0.05,1)+DownsampleTraining(LDA(0.98),instances=-2)+Cat+DownsampleTraining(PCA(768),instances=1))");
98 Globals->abbreviations.insert("FaceRecognitionQuantization", "(Normalize(L1)+Quantize)"); 98 Globals->abbreviations.insert("FaceRecognitionQuantization", "(Normalize(L1)+Quantize)");
99 - Globals->abbreviations.insert("FaceClassificationRegistration", "ASEFEyes+Affine(56,72,0.33,0.45)"); 99 + Globals->abbreviations.insert("FaceClassificationRegistration", "(ASEFEyes+Affine(56,72,0.33,0.45)+FTE(DFFS))");
100 Globals->abbreviations.insert("FaceClassificationExtraction", "((Grid(7,7)+SIFTDescriptor(8)+ByRow)/DenseLBP+DownsampleTraining(PCA(0.95),instances=-1, inputVariable=Gender)+Cat)"); 100 Globals->abbreviations.insert("FaceClassificationExtraction", "((Grid(7,7)+SIFTDescriptor(8)+ByRow)/DenseLBP+DownsampleTraining(PCA(0.95),instances=-1, inputVariable=Gender)+Cat)");
101 Globals->abbreviations.insert("AgeRegressor", "DownsampleTraining(Center(Range),instances=-1, inputVariable=Age)+DownsampleTraining(SVM(RBF,EPS_SVR,inputVariable=Age),instances=100, inputVariable=Age)"); 101 Globals->abbreviations.insert("AgeRegressor", "DownsampleTraining(Center(Range),instances=-1, inputVariable=Age)+DownsampleTraining(SVM(RBF,EPS_SVR,inputVariable=Age),instances=100, inputVariable=Age)");
102 Globals->abbreviations.insert("GenderClassifier", "DownsampleTraining(Center(Range),instances=-1, inputVariable=Gender)+DownsampleTraining(SVM(RBF,C_SVC,inputVariable=Gender),instances=4000, inputVariable=Gender)"); 102 Globals->abbreviations.insert("GenderClassifier", "DownsampleTraining(Center(Range),instances=-1, inputVariable=Gender)+DownsampleTraining(SVM(RBF,C_SVC,inputVariable=Gender),instances=4000, inputVariable=Gender)");
openbr/plugins/cascade.cpp
@@ -252,8 +252,6 @@ class CascadeTransform : public MetaTransform @@ -252,8 +252,6 @@ class CascadeTransform : public MetaTransform
252 void init() 252 void init()
253 { 253 {
254 cascadeResource.setResourceMaker(new CascadeResourceMaker(model)); 254 cascadeResource.setResourceMaker(new CascadeResourceMaker(model));
255 - if (model == "Ear" || model == "Eye" || model == "FrontalFace" || model == "ProfileFace")  
256 - this->trainable = false;  
257 } 255 }
258 256
259 // Train transform 257 // Train transform
openbr/plugins/meta.cpp
@@ -17,8 +17,6 @@ @@ -17,8 +17,6 @@
17 #include <QFutureSynchronizer> 17 #include <QFutureSynchronizer>
18 #include <QRegularExpression> 18 #include <QRegularExpression>
19 #include <QtConcurrentRun> 19 #include <QtConcurrentRun>
20 -#include <qbuffer.h>  
21 -  
22 #include "openbr_internal.h" 20 #include "openbr_internal.h"
23 #include "openbr/core/common.h" 21 #include "openbr/core/common.h"
24 #include "openbr/core/opencvutils.h" 22 #include "openbr/core/opencvutils.h"
@@ -96,15 +94,17 @@ class PipeTransform : public CompositeTransform @@ -96,15 +94,17 @@ class PipeTransform : public CompositeTransform
96 94
97 int i = 0; 95 int i = 0;
98 while (i < transforms.size()) { 96 while (i < transforms.size()) {
  97 + fprintf(stderr, "\n%s", qPrintable(transforms[i]->objectName()));
  98 +
99 // Conditional statement covers likely case that first transform is untrainable 99 // Conditional statement covers likely case that first transform is untrainable
100 if (transforms[i]->trainable) { 100 if (transforms[i]->trainable) {
101 - qDebug() << "Training " << transforms[i]->description() << "\n..."; 101 + fprintf(stderr, " training...");
102 transforms[i]->train(dataLines); 102 transforms[i]->train(dataLines);
103 } 103 }
104 104
105 // if the transform is time varying, we can't project it in parallel 105 // if the transform is time varying, we can't project it in parallel
106 if (transforms[i]->timeVarying()) { 106 if (transforms[i]->timeVarying()) {
107 - qDebug() << "Projecting " << transforms[i]->description() << "\n..."; 107 + fprintf(stderr, "\n%s projecting...", qPrintable(transforms[i]->objectName()));
108 for (int j=0; j < dataLines.size();j++) { 108 for (int j=0; j < dataLines.size();j++) {
109 TemplateList junk; 109 TemplateList junk;
110 splitFTEs(dataLines[j], junk); 110 splitFTEs(dataLines[j], junk);
@@ -130,16 +130,7 @@ class PipeTransform : public CompositeTransform @@ -130,16 +130,7 @@ class PipeTransform : public CompositeTransform
130 !transforms[nextTrainableTransform]->timeVarying()) 130 !transforms[nextTrainableTransform]->timeVarying())
131 nextTrainableTransform++; 131 nextTrainableTransform++;
132 132
133 - // No more trainable transforms? Don't need any more projects then  
134 - if (nextTrainableTransform == transforms.size())  
135 - break;  
136 -  
137 - fprintf(stderr, "Projecting %s", qPrintable(transforms[i]->description()));  
138 - for (int j=i+1; j < nextTrainableTransform; j++)  
139 - fprintf(stderr,"+%s", qPrintable(transforms[j]->description()));  
140 - fprintf(stderr, "\n...\n");  
141 - fflush(stderr);  
142 - 133 + fprintf(stderr, " projecting...");
143 QFutureSynchronizer<void> futures; 134 QFutureSynchronizer<void> futures;
144 for (int j=0; j < dataLines.size(); j++) 135 for (int j=0; j < dataLines.size(); j++)
145 futures.addFuture(QtConcurrent::run(this, &PipeTransform::_projectPartial, &dataLines[j], i, nextTrainableTransform)); 136 futures.addFuture(QtConcurrent::run(this, &PipeTransform::_projectPartial, &dataLines[j], i, nextTrainableTransform));
@@ -519,6 +510,7 @@ class LoadStoreTransform : public MetaTransform @@ -519,6 +510,7 @@ class LoadStoreTransform : public MetaTransform
519 510
520 public: 511 public:
521 Transform *transform; 512 Transform *transform;
  513 + QString baseName;
522 514
523 LoadStoreTransform() : transform(NULL) {} 515 LoadStoreTransform() : transform(NULL) {}
524 516
@@ -548,8 +540,8 @@ private: @@ -548,8 +540,8 @@ private:
548 void init() 540 void init()
549 { 541 {
550 if (transform != NULL) return; 542 if (transform != NULL) return;
551 - if (fileName.isEmpty()) fileName = QRegExp("^[_a-zA-Z0-9]+$").exactMatch(transformString) ? transformString : QtUtils::shortTextHash(transformString);  
552 - 543 + if (fileName.isEmpty()) baseName = QRegExp("^[_a-zA-Z0-9]+$").exactMatch(transformString) ? transformString : QtUtils::shortTextHash(transformString);
  544 + else baseName = fileName;
553 if (!tryLoad()) 545 if (!tryLoad())
554 transform = make(transformString); 546 transform = make(transformString);
555 else 547 else
@@ -561,28 +553,19 @@ private: @@ -561,28 +553,19 @@ private:
561 return transform->timeVarying(); 553 return transform->timeVarying();
562 } 554 }
563 555
564 - void train(const QList<TemplateList> &data) 556 + void train(const TemplateList &data)
565 { 557 {
566 if (QFileInfo(getFileName()).exists()) 558 if (QFileInfo(getFileName()).exists())
567 return; 559 return;
568 560
569 transform->train(data); 561 transform->train(data);
570 562
571 - qDebug("Storing %s", qPrintable(fileName));  
572 - QtUtils::BlockCompression compressedOut;  
573 - QFile fout(fileName);  
574 - QtUtils::touchDir(fout);  
575 - compressedOut.setBasis(&fout);  
576 -  
577 - QDataStream stream(&compressedOut);  
578 - QString desc = transform->description();  
579 -  
580 - if (!compressedOut.open(QFile::WriteOnly))  
581 - qFatal("Failed to open %s for writing.", qPrintable(file));  
582 -  
583 - stream << desc; 563 + qDebug("Storing %s", qPrintable(baseName));
  564 + QByteArray byteArray;
  565 + QDataStream stream(&byteArray, QFile::WriteOnly);
  566 + stream << transform->description();
584 transform->store(stream); 567 transform->store(stream);
585 - compressedOut.close(); 568 + QtUtils::writeFile(baseName, byteArray, -1);
586 } 569 }
587 570
588 void project(const Template &src, Template &dst) const 571 void project(const Template &src, Template &dst) const
@@ -612,8 +595,8 @@ private: @@ -612,8 +595,8 @@ private:
612 595
613 QString getFileName() const 596 QString getFileName() const
614 { 597 {
615 - if (QFileInfo(fileName).exists()) return fileName;  
616 - const QString file = Globals->sdkPath + "/share/openbr/models/transforms/" + fileName; 598 + if (QFileInfo(baseName).exists()) return baseName;
  599 + const QString file = Globals->sdkPath + "/share/openbr/models/transforms/" + baseName;
617 return QFileInfo(file).exists() ? file : QString(); 600 return QFileInfo(file).exists() ? file : QString();
618 } 601 }
619 602
@@ -623,19 +606,12 @@ private: @@ -623,19 +606,12 @@ private:
623 if (file.isEmpty()) return false; 606 if (file.isEmpty()) return false;
624 607
625 qDebug("Loading %s", qPrintable(file)); 608 qDebug("Loading %s", qPrintable(file));
626 - QFile fin(file);  
627 - QtUtils::BlockCompression reader(&fin);  
628 - if (!reader.open(QIODevice::ReadOnly)) {  
629 - if (QFileInfo(file).exists()) qFatal("Unable to open %s for reading. Check file permissions.", qPrintable(file));  
630 - else qFatal("Unable to open %s for reading. File does not exist.", qPrintable(file));  
631 - }  
632 -  
633 - QDataStream stream(&reader); 609 + QByteArray data;
  610 + QtUtils::readFile(file, data, true);
  611 + QDataStream stream(&data, QFile::ReadOnly);
634 stream >> transformString; 612 stream >> transformString;
635 -  
636 transform = Transform::make(transformString); 613 transform = Transform::make(transformString);
637 transform->load(stream); 614 transform->load(stream);
638 -  
639 return true; 615 return true;
640 } 616 }
641 }; 617 };
openbr/plugins/quality.cpp
@@ -77,12 +77,6 @@ class ImpostorUniquenessMeasureTransform : public Transform @@ -77,12 +77,6 @@ class ImpostorUniquenessMeasureTransform : public Transform
77 77
78 BR_REGISTER(Transform, ImpostorUniquenessMeasureTransform) 78 BR_REGISTER(Transform, ImpostorUniquenessMeasureTransform)
79 79
80 -  
81 -float KDEPointer(const QList<float> *scores, double x, double h)  
82 -{  
83 - return Common::KernelDensityEstimation(*scores, x, h);  
84 -}  
85 -  
86 /* Kernel Density Estimator */ 80 /* Kernel Density Estimator */
87 struct KDE 81 struct KDE
88 { 82 {
@@ -91,35 +85,20 @@ struct KDE @@ -91,35 +85,20 @@ struct KDE
91 QList<float> bins; 85 QList<float> bins;
92 86
93 KDE() : min(0), max(1), mean(0), stddev(1) {} 87 KDE() : min(0), max(1), mean(0), stddev(1) {}
94 -  
95 - KDE(const QList<float> &scores, bool trainKDE) 88 + KDE(const QList<float> &scores)
96 { 89 {
97 Common::MinMax(scores, &min, &max); 90 Common::MinMax(scores, &min, &max);
98 Common::MeanStdDev(scores, &mean, &stddev); 91 Common::MeanStdDev(scores, &mean, &stddev);
99 -  
100 - if (!trainKDE)  
101 - return;  
102 -  
103 double h = Common::KernelDensityBandwidth(scores); 92 double h = Common::KernelDensityBandwidth(scores);
104 const int size = 255; 93 const int size = 255;
105 bins.reserve(size); 94 bins.reserve(size);
106 -  
107 - QFutureSynchronizer<float> futures;  
108 -  
109 - for (int i=0; i < size; i++)  
110 - futures.addFuture(QtConcurrent::run(KDEPointer, &scores, min + (max-min)*i/(size-1), h));  
111 - futures.waitForFinished();  
112 -  
113 - foreach(const QFuture<float> & future, futures.futures())  
114 - bins.append(future.result()); 95 + for (int i=0; i<size; i++)
  96 + bins.append(Common::KernelDensityEstimation(scores, min + (max-min)*i/(size-1), h));
115 } 97 }
116 98
117 float operator()(float score, bool gaussian = true) const 99 float operator()(float score, bool gaussian = true) const
118 { 100 {
119 if (gaussian) return 1/(stddev*sqrt(2*CV_PI))*exp(-0.5*pow((score-mean)/stddev, 2)); 101 if (gaussian) return 1/(stddev*sqrt(2*CV_PI))*exp(-0.5*pow((score-mean)/stddev, 2));
120 - if (bins.empty())  
121 - return -std::numeric_limits<float>::max();  
122 -  
123 if (score <= min) return bins.first(); 102 if (score <= min) return bins.first();
124 if (score >= max) return bins.last(); 103 if (score >= max) return bins.last();
125 const float x = (score-min)/(max-min)*bins.size(); 104 const float x = (score-min)/(max-min)*bins.size();
@@ -144,8 +123,8 @@ struct MP @@ -144,8 +123,8 @@ struct MP
144 { 123 {
145 KDE genuine, impostor; 124 KDE genuine, impostor;
146 MP() {} 125 MP() {}
147 - MP(const QList<float> &genuineScores, const QList<float> &impostorScores, bool trainKDE)  
148 - : genuine(genuineScores, trainKDE), impostor(impostorScores, trainKDE) {} 126 + MP(const QList<float> &genuineScores, const QList<float> &impostorScores)
  127 + : genuine(genuineScores), impostor(impostorScores) {}
149 float operator()(float score, bool gaussian = true) const 128 float operator()(float score, bool gaussian = true) const
150 { 129 {
151 const float g = genuine(score, gaussian); 130 const float g = genuine(score, gaussian);
@@ -186,7 +165,7 @@ class MatchProbabilityDistance : public Distance @@ -186,7 +165,7 @@ class MatchProbabilityDistance : public Distance
186 const QList<int> labels = src.indexProperty(inputVariable); 165 const QList<int> labels = src.indexProperty(inputVariable);
187 QScopedPointer<MatrixOutput> matrixOutput(MatrixOutput::make(FileList(src.size()), FileList(src.size()))); 166 QScopedPointer<MatrixOutput> matrixOutput(MatrixOutput::make(FileList(src.size()), FileList(src.size())));
188 distance->compare(src, src, matrixOutput.data()); 167 distance->compare(src, src, matrixOutput.data());
189 - 168 +
190 QList<float> genuineScores, impostorScores; 169 QList<float> genuineScores, impostorScores;
191 genuineScores.reserve(labels.size()); 170 genuineScores.reserve(labels.size());
192 impostorScores.reserve(labels.size()*labels.size()); 171 impostorScores.reserve(labels.size()*labels.size());
@@ -199,8 +178,8 @@ class MatchProbabilityDistance : public Distance @@ -199,8 +178,8 @@ class MatchProbabilityDistance : public Distance
199 else impostorScores.append(score); 178 else impostorScores.append(score);
200 } 179 }
201 } 180 }
202 -  
203 - mp = MP(genuineScores, impostorScores, !gaussian); 181 +
  182 + mp = MP(genuineScores, impostorScores);
204 } 183 }
205 184
206 float compare(const Template &target, const Template &query) const 185 float compare(const Template &target, const Template &query) const
1 -Subproject commit 85842e6da7738e317b9d40d5a395b92cd7b996e1 1 +Subproject commit 79938fe401faafead086b4711dd0b8f898a7a21e