Commit 40a6bf87020cb27fa18cc671fb3111b0e0c03989

Authored by Scott Klum
2 parents b721e1e0 3ad80556

removed bee.cpp conflict

CHANGELOG.md
1 0.3.0 - ??/??/?? 1 0.3.0 - ??/??/??
2 ================ 2 ================
  3 +* YouTubeFacesDBTransform implements Dr. Wolf's experimental protocol
3 4
4 0.2.0 - 2/23/13 5 0.2.0 - 2/23/13
5 =============== 6 ===============
sdk/core/bee.cpp
@@ -42,8 +42,8 @@ FileList BEE::readSigset(const QString &sigset, bool ignoreMetadata) @@ -42,8 +42,8 @@ FileList BEE::readSigset(const QString &sigset, bool ignoreMetadata)
42 QDomDocument doc(sigset); 42 QDomDocument doc(sigset);
43 QFile file(sigset); 43 QFile file(sigset);
44 bool success; 44 bool success;
45 - success = file.open(QIODevice::ReadOnly); if (!success) qFatal("BEE::readSigset unable to open %s for reading.", qPrintable(sigset));  
46 - success = doc.setContent(&file); if (!success) qFatal("BEE::readSigset unable to parse %s.", qPrintable(sigset)); 45 + success = file.open(QIODevice::ReadOnly); if (!success) qFatal("Unable to open %s for reading.", qPrintable(sigset));
  46 + success = doc.setContent(&file); if (!success) qFatal("Unable to parse %s.", qPrintable(sigset));
47 file.close(); 47 file.close();
48 48
49 QDomElement docElem = doc.documentElement(); 49 QDomElement docElem = doc.documentElement();
@@ -75,7 +75,7 @@ FileList BEE::readSigset(const QString &sigset, bool ignoreMetadata) @@ -75,7 +75,7 @@ FileList BEE::readSigset(const QString &sigset, bool ignoreMetadata)
75 } 75 }
76 } 76 }
77 77
78 - if (file.isNull()) qFatal("BEE::readSigset empty file-name in %s.", qPrintable(sigset)); 78 + if (file.isNull()) qFatal("Empty file-name in %s.", qPrintable(sigset));
79 fileList.append(file); 79 fileList.append(file);
80 80
81 fileNode = fileNode.nextSibling(); 81 fileNode = fileNode.nextSibling();
@@ -115,7 +115,7 @@ Mat readMatrix(const br::File &matrix) @@ -115,7 +115,7 @@ Mat readMatrix(const br::File &matrix)
115 if (matrix == "Matrix") { 115 if (matrix == "Matrix") {
116 const int size = matrix.getInt("Size"); 116 const int size = matrix.getInt("Size");
117 const int step = matrix.getInt("Step", 1); 117 const int step = matrix.getInt("Step", 1);
118 - if (size % step != 0) qFatal("bee.cpp readMatrix step does not divide size evenly."); 118 + if (size % step != 0) qFatal("Step does not divide size evenly.");
119 119
120 if (sizeof(T) == sizeof(BEE::Mask_t)) { 120 if (sizeof(T) == sizeof(BEE::Mask_t)) {
121 const bool selfSimilar = matrix.getBool("SelfSimilar"); 121 const bool selfSimilar = matrix.getBool("SelfSimilar");
@@ -140,13 +140,12 @@ Mat readMatrix(const br::File &matrix) @@ -140,13 +140,12 @@ Mat readMatrix(const br::File &matrix)
140 140
141 QFile file(matrix); 141 QFile file(matrix);
142 bool success = file.open(QFile::ReadOnly); 142 bool success = file.open(QFile::ReadOnly);
143 - if (!success) qFatal("bee.cpp readMatrix unable to open %s for reading.", qPrintable((QString)matrix)); 143 + if (!success) qFatal("Unable to open %s for reading.", qPrintable((QString)matrix));
144 144
145 // Check format 145 // Check format
146 QByteArray format = file.readLine(); 146 QByteArray format = file.readLine();
147 bool isDistance = (format[0] == 'D'); 147 bool isDistance = (format[0] == 'D');
148 -  
149 - if (format[1] != '2') qFatal("bee.cpp readMatrix invalid matrix header."); 148 + if (format[1] != '2') qFatal("Invalid matrix header.");
150 149
151 // Skip sigset lines 150 // Skip sigset lines
152 file.readLine(); 151 file.readLine();
@@ -161,7 +160,7 @@ Mat readMatrix(const br::File &matrix) @@ -161,7 +160,7 @@ Mat readMatrix(const br::File &matrix)
161 qint64 bytesExpected = (qint64)rows*(qint64)cols*(qint64)sizeof(T); 160 qint64 bytesExpected = (qint64)rows*(qint64)cols*(qint64)sizeof(T);
162 Mat m(rows, cols, OpenCVType<T,1>::make()); 161 Mat m(rows, cols, OpenCVType<T,1>::make());
163 if (file.read((char*)m.data, bytesExpected) != bytesExpected) 162 if (file.read((char*)m.data, bytesExpected) != bytesExpected)
164 - qFatal("bee.cpp readMatrix invalid matrix size."); 163 + qFatal("Invalid matrix size.");
165 file.close(); 164 file.close();
166 165
167 Mat result; 166 Mat result;
@@ -183,17 +182,17 @@ Mat BEE::readMask(const br::File &amp;mask) @@ -183,17 +182,17 @@ Mat BEE::readMask(const br::File &amp;mask)
183 template <typename T> 182 template <typename T>
184 void writeMatrix(const Mat &m, const QString &matrix, const QString &targetSigset, const QString &querySigset) 183 void writeMatrix(const Mat &m, const QString &matrix, const QString &targetSigset, const QString &querySigset)
185 { 184 {
186 - if (m.type() != OpenCVType<T,1>::make()) qFatal("bee.cpp writeMatrix invalid matrix type."); 185 + if (m.type() != OpenCVType<T,1>::make()) qFatal("Invalid matrix type.");
187 186
188 int elemSize = sizeof(T); 187 int elemSize = sizeof(T);
189 QString matrixType; 188 QString matrixType;
190 if (elemSize == 1) matrixType = "B"; 189 if (elemSize == 1) matrixType = "B";
191 else if (elemSize == 4) matrixType = "F"; 190 else if (elemSize == 4) matrixType = "F";
192 - else qFatal("bee.cpp writeMatrix invalid element size.\n"); 191 + else qFatal("Invalid element size.");
193 192
194 char buff[4]; 193 char buff[4];
195 QFile file(matrix); 194 QFile file(matrix);
196 - bool success = file.open(QFile::WriteOnly); if (!success) qFatal("bee.cpp writeMatrix unable to open %s for writing.", qPrintable(matrix)); 195 + bool success = file.open(QFile::WriteOnly); if (!success) qFatal("Unable to open %s for writing.", qPrintable(matrix));
197 file.write("S2\n"); 196 file.write("S2\n");
198 file.write(qPrintable(QFileInfo(targetSigset).fileName())); 197 file.write(qPrintable(QFileInfo(targetSigset).fileName()));
199 file.write("\n"); 198 file.write("\n");
@@ -228,8 +227,8 @@ void BEE::makeMask(const QString &amp;targetInput, const QString &amp;queryInput, const @@ -228,8 +227,8 @@ void BEE::makeMask(const QString &amp;targetInput, const QString &amp;queryInput, const
228 { 227 {
229 qDebug("Making mask from %s and %s to %s", qPrintable(targetInput), qPrintable(queryInput), qPrintable(mask)); 228 qDebug("Making mask from %s and %s to %s", qPrintable(targetInput), qPrintable(queryInput), qPrintable(mask));
230 229
231 - FileList targetFiles = TemplateList::fromInput(targetInput).files();  
232 - FileList queryFiles = TemplateList::fromInput(queryInput).files(); 230 + FileList targetFiles = TemplateList::fromGallery(targetInput).files();
  231 + FileList queryFiles = TemplateList::fromGallery(queryInput).files();
233 QList<float> targetLabels = targetFiles.labels(); 232 QList<float> targetLabels = targetFiles.labels();
234 QList<float> queryLabels = queryFiles.labels(); 233 QList<float> queryLabels = queryFiles.labels();
235 QList<int> targetPartitions = targetFiles.crossValidationPartitions(); 234 QList<int> targetPartitions = targetFiles.crossValidationPartitions();
@@ -266,12 +265,12 @@ void BEE::combineMasks(const QStringList &amp;inputMasks, const QString &amp;outputMask, @@ -266,12 +265,12 @@ void BEE::combineMasks(const QStringList &amp;inputMasks, const QString &amp;outputMask,
266 bool AND = true; 265 bool AND = true;
267 if (method == "And") AND = true; 266 if (method == "And") AND = true;
268 else if (method == "Or") AND = false; 267 else if (method == "Or") AND = false;
269 - else qFatal("combineMasks invalid method"); 268 + else qFatal("Invalid method.");
270 269
271 QList<Mat> masks; 270 QList<Mat> masks;
272 foreach (const QString &inputMask, inputMasks) 271 foreach (const QString &inputMask, inputMasks)
273 masks.append(readMask(inputMask)); 272 masks.append(readMask(inputMask));
274 - if (masks.size() < 2) qFatal("BEE::mergeMasks expects at least two masks."); 273 + if (masks.size() < 2) qFatal("Expected at least two masks.");
275 274
276 const int rows = masks.first().rows; 275 const int rows = masks.first().rows;
277 const int columns = masks.first().cols; 276 const int columns = masks.first().cols;
@@ -295,7 +294,7 @@ void BEE::combineMasks(const QStringList &amp;inputMasks, const QString &amp;outputMask, @@ -295,7 +294,7 @@ void BEE::combineMasks(const QStringList &amp;inputMasks, const QString &amp;outputMask,
295 break; 294 break;
296 } 295 }
297 } 296 }
298 - if ((genuineCount != 0) && (imposterCount != 0)) qFatal("BEE::combinedMasks comparison is both a genuine and an imposter."); 297 + if ((genuineCount != 0) && (imposterCount != 0)) qFatal("Comparison is both a genuine and an imposter.");
299 298
300 Mask_t val; 299 Mask_t val;
301 if (genuineCount > 0) val = Match; 300 if (genuineCount > 0) val = Match;
sdk/core/classify.cpp
@@ -37,14 +37,14 @@ void br::EvalClassification(const QString &amp;predictedInput, const QString &amp;truthI @@ -37,14 +37,14 @@ void br::EvalClassification(const QString &amp;predictedInput, const QString &amp;truthI
37 { 37 {
38 qDebug("Evaluating classification of %s against %s", qPrintable(predictedInput), qPrintable(truthInput)); 38 qDebug("Evaluating classification of %s against %s", qPrintable(predictedInput), qPrintable(truthInput));
39 39
40 - TemplateList predicted(TemplateList::fromInput(predictedInput));  
41 - TemplateList truth(TemplateList::fromInput(truthInput));  
42 - if (predicted.size() != truth.size()) qFatal("br::EvalClassification input size mismatch."); 40 + TemplateList predicted(TemplateList::fromGallery(predictedInput));
  41 + TemplateList truth(TemplateList::fromGallery(truthInput));
  42 + if (predicted.size() != truth.size()) qFatal("Input size mismatch.");
43 43
44 QHash<int, Counter> counters; 44 QHash<int, Counter> counters;
45 for (int i=0; i<predicted.size(); i++) { 45 for (int i=0; i<predicted.size(); i++) {
46 if (predicted[i].file.name != truth[i].file.name) 46 if (predicted[i].file.name != truth[i].file.name)
47 - qFatal("br::EvalClassification input order mismatch."); 47 + qFatal("Input order mismatch.");
48 48
49 const int trueLabel = truth[i].file.label(); 49 const int trueLabel = truth[i].file.label();
50 const int predictedLabel = predicted[i].file.label(); 50 const int predictedLabel = predicted[i].file.label();
@@ -83,15 +83,15 @@ void br::EvalRegression(const QString &amp;predictedInput, const QString &amp;truthInput @@ -83,15 +83,15 @@ void br::EvalRegression(const QString &amp;predictedInput, const QString &amp;truthInput
83 { 83 {
84 qDebug("Evaluating regression of %s against %s", qPrintable(predictedInput), qPrintable(truthInput)); 84 qDebug("Evaluating regression of %s against %s", qPrintable(predictedInput), qPrintable(truthInput));
85 85
86 - const TemplateList predicted(TemplateList::fromInput(predictedInput));  
87 - const TemplateList truth(TemplateList::fromInput(truthInput));  
88 - if (predicted.size() != truth.size()) qFatal("br::EvalRegression input size mismatch."); 86 + const TemplateList predicted(TemplateList::fromGallery(predictedInput));
  87 + const TemplateList truth(TemplateList::fromGallery(truthInput));
  88 + if (predicted.size() != truth.size()) qFatal("Input size mismatch.");
89 89
90 float rmsError = 0; 90 float rmsError = 0;
91 QStringList truthValues, predictedValues; 91 QStringList truthValues, predictedValues;
92 for (int i=0; i<predicted.size(); i++) { 92 for (int i=0; i<predicted.size(); i++) {
93 if (predicted[i].file.name != truth[i].file.name) 93 if (predicted[i].file.name != truth[i].file.name)
94 - qFatal("br::EvalRegression input order mismatch."); 94 + qFatal("Input order mismatch.");
95 rmsError += pow(predicted[i].file.label()-truth[i].file.label(), 2.f); 95 rmsError += pow(predicted[i].file.label()-truth[i].file.label(), 2.f);
96 truthValues.append(QString::number(truth[i].file.label())); 96 truthValues.append(QString::number(truth[i].file.label()));
97 predictedValues.append(QString::number(predicted[i].file.label())); 97 predictedValues.append(QString::number(predicted[i].file.label()));
sdk/core/cluster.cpp
@@ -90,7 +90,7 @@ Neighborhood getNeighborhood(const QStringList &amp;simmats) @@ -90,7 +90,7 @@ Neighborhood getNeighborhood(const QStringList &amp;simmats)
90 float globalMin = std::numeric_limits<float>::max(); 90 float globalMin = std::numeric_limits<float>::max();
91 int numGalleries = (int)sqrt((float)simmats.size()); 91 int numGalleries = (int)sqrt((float)simmats.size());
92 if (numGalleries*numGalleries != simmats.size()) 92 if (numGalleries*numGalleries != simmats.size())
93 - qFatal("cluser.cpp readGalleries incorrect number of similarity matrices."); 93 + qFatal("Incorrect number of similarity matrices.");
94 94
95 // Process each simmat 95 // Process each simmat
96 for (int i=0; i<numGalleries; i++) { 96 for (int i=0; i<numGalleries; i++) {
@@ -104,7 +104,7 @@ Neighborhood getNeighborhood(const QStringList &amp;simmats) @@ -104,7 +104,7 @@ Neighborhood getNeighborhood(const QStringList &amp;simmats)
104 currentRows = m.rows; 104 currentRows = m.rows;
105 allNeighbors.resize(currentRows); 105 allNeighbors.resize(currentRows);
106 } 106 }
107 - if (currentRows != m.rows) qFatal("cluster.cpp::getNeighborhood row count mismatch."); 107 + if (currentRows != m.rows) qFatal("Row count mismatch.");
108 108
109 // Get data row by row 109 // Get data row by row
110 for (int k=0; k<m.rows; k++) { 110 for (int k=0; k<m.rows; k++) {
@@ -278,7 +278,7 @@ void br::EvalClustering(const QString &amp;csv, const QString &amp;input) @@ -278,7 +278,7 @@ void br::EvalClustering(const QString &amp;csv, const QString &amp;input)
278 { 278 {
279 qDebug("Evaluating %s against %s", qPrintable(csv), qPrintable(input)); 279 qDebug("Evaluating %s against %s", qPrintable(csv), qPrintable(input));
280 280
281 - QList<float> labels = TemplateList::fromInput(input).files().labels(); 281 + QList<float> labels = TemplateList::fromGallery(input).files().labels();
282 282
283 QHash<int, int> labelToIndex; 283 QHash<int, int> labelToIndex;
284 int nClusters = 0; 284 int nClusters = 0;
@@ -322,7 +322,7 @@ br::Clusters br::ReadClusters(const QString &amp;csv) @@ -322,7 +322,7 @@ br::Clusters br::ReadClusters(const QString &amp;csv)
322 Clusters clusters; 322 Clusters clusters;
323 QFile file(csv); 323 QFile file(csv);
324 bool success = file.open(QFile::ReadOnly); 324 bool success = file.open(QFile::ReadOnly);
325 - if (!success) qFatal("br::ReadClusters failed to open %s for reading.", qPrintable(csv)); 325 + if (!success) qFatal("Failed to open %s for reading.", qPrintable(csv));
326 QStringList lines = QString(file.readAll()).split("\n"); 326 QStringList lines = QString(file.readAll()).split("\n");
327 file.close(); 327 file.close();
328 328
@@ -332,7 +332,7 @@ br::Clusters br::ReadClusters(const QString &amp;csv) @@ -332,7 +332,7 @@ br::Clusters br::ReadClusters(const QString &amp;csv)
332 foreach (const QString &id, ids) { 332 foreach (const QString &id, ids) {
333 bool ok; 333 bool ok;
334 cluster.append(id.toInt(&ok)); 334 cluster.append(id.toInt(&ok));
335 - if (!ok) qFatal("br::ReadClusters non-interger id."); 335 + if (!ok) qFatal("Non-interger id.");
336 } 336 }
337 clusters.append(cluster); 337 clusters.append(cluster);
338 } 338 }
@@ -343,7 +343,7 @@ void br::WriteClusters(const Clusters &amp;clusters, const QString &amp;csv) @@ -343,7 +343,7 @@ void br::WriteClusters(const Clusters &amp;clusters, const QString &amp;csv)
343 { 343 {
344 QFile file(csv); 344 QFile file(csv);
345 bool success = file.open(QFile::WriteOnly); 345 bool success = file.open(QFile::WriteOnly);
346 - if (!success) qFatal("br::WriteClusters failed to open %s for writing.", qPrintable(csv)); 346 + if (!success) qFatal("Failed to open %s for writing.", qPrintable(csv));
347 347
348 foreach (Cluster cluster, clusters) { 348 foreach (Cluster cluster, clusters) {
349 if (cluster.empty()) continue; 349 if (cluster.empty()) continue;
sdk/core/common.cpp
@@ -33,7 +33,7 @@ QList&lt;int&gt; Common::RandSample(int n, int max, int min, bool unique) @@ -33,7 +33,7 @@ QList&lt;int&gt; Common::RandSample(int n, int max, int min, bool unique)
33 33
34 QList<int> samples; samples.reserve(n); 34 QList<int> samples; samples.reserve(n);
35 int range = max-min; 35 int range = max-min;
36 - if (range <= 0) qFatal("Common::RandSample non-positive range."); 36 + if (range <= 0) qFatal("Non-positive range.");
37 if (unique && (n >= range)) { 37 if (unique && (n >= range)) {
38 for (int i=min; i<max; i++) 38 for (int i=min; i<max; i++)
39 samples.append(i); 39 samples.append(i);
sdk/core/core.cpp
@@ -40,7 +40,7 @@ struct AlgorithmCore @@ -40,7 +40,7 @@ struct AlgorithmCore
40 40
41 void train(const File &input, const QString &model) 41 void train(const File &input, const QString &model)
42 { 42 {
43 - TemplateList data(TemplateList::fromInput(input)); 43 + TemplateList data(TemplateList::fromGallery(input));
44 44
45 if (transform.isNull()) qFatal("Null transform."); 45 if (transform.isNull()) qFatal("Null transform.");
46 qDebug("%d training files", data.size()); 46 qDebug("%d training files", data.size());
@@ -118,7 +118,7 @@ struct AlgorithmCore @@ -118,7 +118,7 @@ struct AlgorithmCore
118 if (!fileList.isEmpty() && gallery.contains("cache")) 118 if (!fileList.isEmpty() && gallery.contains("cache"))
119 return fileList; 119 return fileList;
120 120
121 - const TemplateList i(TemplateList::fromInput(input)); 121 + const TemplateList i(TemplateList::fromGallery(input));
122 if (i.isEmpty()) return fileList; // Nothing to enroll 122 if (i.isEmpty()) return fileList; // Nothing to enroll
123 123
124 if (transform.isNull()) qFatal("Null transform."); 124 if (transform.isNull()) qFatal("Null transform.");
@@ -280,9 +280,12 @@ public: @@ -280,9 +280,12 @@ public:
280 if (algorithm.isEmpty()) qFatal("No default algorithm set."); 280 if (algorithm.isEmpty()) qFatal("No default algorithm set.");
281 281
282 if (!algorithms.contains(algorithm)) { 282 if (!algorithms.contains(algorithm)) {
  283 + // Some algorithms are recursive, so we need to construct them outside the lock.
  284 + QSharedPointer<AlgorithmCore> algorithmCore(new AlgorithmCore(algorithm));
  285 +
283 algorithmsLock.lock(); 286 algorithmsLock.lock();
284 if (!algorithms.contains(algorithm)) 287 if (!algorithms.contains(algorithm))
285 - algorithms.insert(algorithm, QSharedPointer<AlgorithmCore>(new AlgorithmCore(algorithm))); 288 + algorithms.insert(algorithm, algorithmCore);
286 algorithmsLock.unlock(); 289 algorithmsLock.unlock();
287 } 290 }
288 291
sdk/core/fuse.cpp
@@ -60,7 +60,7 @@ static void normalizeMatrix(Mat &amp;matrix, const Mat &amp;mask, const QString &amp;method) @@ -60,7 +60,7 @@ static void normalizeMatrix(Mat &amp;matrix, const Mat &amp;mask, const QString &amp;method)
60 } 60 }
61 } 61 }
62 } else if (method == "ZScore") { 62 } else if (method == "ZScore") {
63 - if (stddev == 0) qFatal("fuse.cpp normalizeMatrix stddev is 0."); 63 + if (stddev == 0) qFatal("Stddev is 0.");
64 for (int i=0; i<matrix.rows; i++) { 64 for (int i=0; i<matrix.rows; i++) {
65 for (int j=0; j<matrix.cols; j++) { 65 for (int j=0; j<matrix.cols; j++) {
66 if (mask.at<BEE::Mask_t>(i,j) == BEE::DontCare) continue; 66 if (mask.at<BEE::Mask_t>(i,j) == BEE::DontCare) continue;
@@ -71,7 +71,7 @@ static void normalizeMatrix(Mat &amp;matrix, const Mat &amp;mask, const QString &amp;method) @@ -71,7 +71,7 @@ static void normalizeMatrix(Mat &amp;matrix, const Mat &amp;mask, const QString &amp;method)
71 } 71 }
72 } 72 }
73 } else { 73 } else {
74 - qFatal("fuse.cpp normalizeMatrix invalid normalization method %s.", qPrintable(method)); 74 + qFatal("Invalid normalization method %s.", qPrintable(method));
75 } 75 }
76 } 76 }
77 77
@@ -81,8 +81,8 @@ void br::Fuse(const QStringList &amp;inputSimmats, const QString &amp;mask, const QStrin @@ -81,8 +81,8 @@ void br::Fuse(const QStringList &amp;inputSimmats, const QString &amp;mask, const QStrin
81 QList<Mat> matrices; 81 QList<Mat> matrices;
82 foreach (const QString &simmat, inputSimmats) 82 foreach (const QString &simmat, inputSimmats)
83 matrices.append(BEE::readSimmat(simmat)); 83 matrices.append(BEE::readSimmat(simmat));
84 - if ((matrices.size() < 2) && (fusion != "None")) qFatal("br::Fuse expected at least two similarity matrices.");  
85 - if ((matrices.size() > 1) && (fusion == "None")) qFatal("mm:Fuse expected exactly one similarity matrix."); 84 + if ((matrices.size() < 2) && (fusion != "None")) qFatal("Expected at least two similarity matrices.");
  85 + if ((matrices.size() > 1) && (fusion == "None")) qFatal("Expected exactly one similarity matrix.");
86 Mat matrix_mask = BEE::readMask(mask); 86 Mat matrix_mask = BEE::readMask(mask);
87 87
88 for (int i=0; i<matrices.size(); i++) 88 for (int i=0; i<matrices.size(); i++)
@@ -107,27 +107,27 @@ void br::Fuse(const QStringList &amp;inputSimmats, const QString &amp;mask, const QStrin @@ -107,27 +107,27 @@ void br::Fuse(const QStringList &amp;inputSimmats, const QString &amp;mask, const QStrin
107 bool ok; 107 bool ok;
108 for (int k=0; k<matrices.size(); k++) { 108 for (int k=0; k<matrices.size(); k++) {
109 float weight = words[k].toFloat(&ok); 109 float weight = words[k].toFloat(&ok);
110 - if (!ok) qFatal("br::Fuse non-numerical weight %s.", qPrintable(words[k])); 110 + if (!ok) qFatal("Non-numerical weight %s.", qPrintable(words[k]));
111 weights.append(weight); 111 weights.append(weight);
112 } 112 }
113 } else { 113 } else {
114 - qFatal("br::Fuse number of weights does not match number of similarity matrices."); 114 + qFatal("Number of weights does not match number of similarity matrices.");
115 } 115 }
116 116
117 addWeighted(matrices[0], weights[0], matrices[1], weights[1], 0, fused); 117 addWeighted(matrices[0], weights[0], matrices[1], weights[1], 0, fused);
118 for (int i=2; i<matrices.size(); i++) 118 for (int i=2; i<matrices.size(); i++)
119 addWeighted(fused, 1, matrices[i], weights[i], 0, fused); 119 addWeighted(fused, 1, matrices[i], weights[i], 0, fused);
120 } else if (fusion == "Replace") { 120 } else if (fusion == "Replace") {
121 - if (matrices.size() != 2) qFatal("br::Fuse Replace fusion requires exactly two matrices."); 121 + if (matrices.size() != 2) qFatal("Replace fusion requires exactly two matrices.");
122 fused = matrices.first().clone(); 122 fused = matrices.first().clone();
123 matrices.last().copyTo(fused, matrix_mask != BEE::DontCare); 123 matrices.last().copyTo(fused, matrix_mask != BEE::DontCare);
124 } else if (fusion == "Difference") { 124 } else if (fusion == "Difference") {
125 - if (matrices.size() != 2) qFatal("br::Fuse Difference fusion requires exactly two matrices."); 125 + if (matrices.size() != 2) qFatal("Difference fusion requires exactly two matrices.");
126 subtract(matrices[0], matrices[1], fused); 126 subtract(matrices[0], matrices[1], fused);
127 } else if (fusion == "None") { 127 } else if (fusion == "None") {
128 fused = matrices[0]; 128 fused = matrices[0];
129 } else { 129 } else {
130 - qFatal("br::Fuse invalid fusion method %s.", qPrintable(fusion)); 130 + qFatal("Invalid fusion method %s.", qPrintable(fusion));
131 } 131 }
132 132
133 BEE::writeSimmat(fused, outputSimmat); 133 BEE::writeSimmat(fused, outputSimmat);
sdk/core/opencvutils.cpp
@@ -55,7 +55,7 @@ void OpenCVUtils::saveImage(const Mat &amp;src, const QString &amp;file) @@ -55,7 +55,7 @@ void OpenCVUtils::saveImage(const Mat &amp;src, const QString &amp;file)
55 55
56 Mat draw; 56 Mat draw;
57 cvtUChar(src, draw); 57 cvtUChar(src, draw);
58 - bool success = imwrite(file.toStdString(), draw); if (!success) qFatal("OpenCVUtils::saveImage failed to save %s", qPrintable(file)); 58 + bool success = imwrite(file.toStdString(), draw); if (!success) qFatal("Failed to save %s", qPrintable(file));
59 } 59 }
60 60
61 void OpenCVUtils::showImage(const Mat &src, const QString &window, bool waitKey) 61 void OpenCVUtils::showImage(const Mat &src, const QString &window, bool waitKey)
@@ -112,7 +112,7 @@ Mat OpenCVUtils::toMat(const QList&lt;float&gt; &amp;src, int rows) @@ -112,7 +112,7 @@ Mat OpenCVUtils::toMat(const QList&lt;float&gt; &amp;src, int rows)
112 { 112 {
113 if (rows == -1) rows = src.size(); 113 if (rows == -1) rows = src.size();
114 int columns = src.isEmpty() ? 0 : src.size() / rows; 114 int columns = src.isEmpty() ? 0 : src.size() / rows;
115 - if (rows*columns != src.size()) qFatal("OpenCVUtils::toMat invalid matrix size."); 115 + if (rows*columns != src.size()) qFatal("Invalid matrix size.");
116 Mat dst(rows, columns, CV_32FC1); 116 Mat dst(rows, columns, CV_32FC1);
117 for (int i=0; i<src.size(); i++) 117 for (int i=0; i<src.size(); i++)
118 dst.at<float>(i/columns,i%columns) = src[i]; 118 dst.at<float>(i/columns,i%columns) = src[i];
@@ -131,7 +131,7 @@ Mat OpenCVUtils::toMat(const QList&lt;Mat&gt; &amp;src) @@ -131,7 +131,7 @@ Mat OpenCVUtils::toMat(const QList&lt;Mat&gt; &amp;src)
131 for (int i=0; i<rows; i++) { 131 for (int i=0; i<rows; i++) {
132 const Mat &m = src[i]; 132 const Mat &m = src[i];
133 if ((m.total() != total) || (m.type() != type) || !m.isContinuous()) 133 if ((m.total() != total) || (m.type() != type) || !m.isContinuous())
134 - qFatal("OpenCVUtils::toMat invalid matrix."); 134 + qFatal("Invalid matrix.");
135 memcpy(dst.ptr(i), m.ptr(), total * src.first().elemSize()); 135 memcpy(dst.ptr(i), m.ptr(), total * src.first().elemSize());
136 } 136 }
137 return dst; 137 return dst;
@@ -149,7 +149,7 @@ Mat OpenCVUtils::toMatByRow(const QList&lt;Mat&gt; &amp;src) @@ -149,7 +149,7 @@ Mat OpenCVUtils::toMatByRow(const QList&lt;Mat&gt; &amp;src)
149 int row = 0; 149 int row = 0;
150 foreach (const Mat &m, src) { 150 foreach (const Mat &m, src) {
151 if ((m.cols != cols) || (m.type() != type) || (!m.isContinuous())) 151 if ((m.cols != cols) || (m.type() != type) || (!m.isContinuous()))
152 - qFatal("OpenCVUtils::toMatByRow invalid matrix."); 152 + qFatal("Invalid matrix.");
153 memcpy(dst.ptr(row), m.ptr(), m.rows*m.cols*m.elemSize()); 153 memcpy(dst.ptr(row), m.ptr(), m.rows*m.cols*m.elemSize());
154 row += m.rows; 154 row += m.rows;
155 } 155 }
@@ -167,7 +167,7 @@ QString OpenCVUtils::elemToString(const Mat &amp;m, int r, int c) @@ -167,7 +167,7 @@ QString OpenCVUtils::elemToString(const Mat &amp;m, int r, int c)
167 case CV_32S: return QString::number(m.at<qint32>(r,c)); 167 case CV_32S: return QString::number(m.at<qint32>(r,c));
168 case CV_32F: return QString::number(m.at<float>(r,c)); 168 case CV_32F: return QString::number(m.at<float>(r,c));
169 case CV_64F: return QString::number(m.at<double>(r,c)); 169 case CV_64F: return QString::number(m.at<double>(r,c));
170 - default: qFatal("OpenCVUtils::elemToString unknown matrix depth"); 170 + default: qFatal("Unknown matrix depth");
171 } 171 }
172 return "?"; 172 return "?";
173 } 173 }
@@ -183,7 +183,7 @@ float OpenCVUtils::elemToFloat(const Mat &amp;m, int r, int c) @@ -183,7 +183,7 @@ float OpenCVUtils::elemToFloat(const Mat &amp;m, int r, int c)
183 case CV_32S: return float(m.at<qint32>(r,c)); 183 case CV_32S: return float(m.at<qint32>(r,c));
184 case CV_32F: return float(m.at<float>(r,c)); 184 case CV_32F: return float(m.at<float>(r,c));
185 case CV_64F: return float(m.at<double>(r,c)); 185 case CV_64F: return float(m.at<double>(r,c));
186 - default: qFatal("OpenCVUtils::elemToFloat unknown matrix depth"); 186 + default: qFatal("Unknown matrix depth");
187 } 187 }
188 return 0; 188 return 0;
189 } 189 }
@@ -300,10 +300,9 @@ QDataStream &amp;operator&lt;&lt;(QDataStream &amp;stream, const Mat &amp;m) @@ -300,10 +300,9 @@ QDataStream &amp;operator&lt;&lt;(QDataStream &amp;stream, const Mat &amp;m)
300 int len = rows*cols*m.elemSize(); 300 int len = rows*cols*m.elemSize();
301 stream << len; 301 stream << len;
302 if (len > 0) { 302 if (len > 0) {
303 - if (!m.isContinuous()) qFatal("opencvutils.cpp operator<< Mat can't serialize non-continuous matrices."); 303 + if (!m.isContinuous()) qFatal("Can't serialize non-continuous matrices.");
304 int written = stream.writeRawData((const char*)m.data, len); 304 int written = stream.writeRawData((const char*)m.data, len);
305 -  
306 - if (written != len) qFatal("opencvutils.cpp operator<< Mat serialization failure."); 305 + if (written != len) qFatal("Serialization failure.");
307 } 306 }
308 return stream; 307 return stream;
309 } 308 }
sdk/core/plot.cpp
@@ -309,7 +309,7 @@ struct RPlot @@ -309,7 +309,7 @@ struct RPlot
309 309
310 RPlot(QStringList files, const br::File &destination, bool isEvalFormat = true) 310 RPlot(QStringList files, const br::File &destination, bool isEvalFormat = true)
311 { 311 {
312 - if (files.isEmpty()) qFatal("RPlot::RPlot() empty file list."); 312 + if (files.isEmpty()) qFatal("Empty file list.");
313 qSort(files.begin(), files.end(), sortFiles); 313 qSort(files.begin(), files.end(), sortFiles);
314 314
315 // Parse destination 315 // Parse destination
@@ -320,7 +320,7 @@ struct RPlot @@ -320,7 +320,7 @@ struct RPlot
320 320
321 file.setFileName(basename+".R"); 321 file.setFileName(basename+".R");
322 bool success = file.open(QFile::WriteOnly); 322 bool success = file.open(QFile::WriteOnly);
323 - if (!success) qFatal("RPlot::RPlot() failed to open %s for writing.", qPrintable(file.fileName())); 323 + if (!success) qFatal("Failed to open %s for writing.", qPrintable(file.fileName()));
324 324
325 file.write("# Load libraries\n" 325 file.write("# Load libraries\n"
326 "library(ggplot2)\n" 326 "library(ggplot2)\n"
sdk/core/qtutils.cpp
@@ -44,7 +44,7 @@ QStringList QtUtils::getFiles(QDir dir, bool recursive) @@ -44,7 +44,7 @@ QStringList QtUtils::getFiles(QDir dir, bool recursive)
44 44
45 foreach (const QString &folder, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) { 45 foreach (const QString &folder, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) {
46 QDir subdir(dir); 46 QDir subdir(dir);
47 - bool success = subdir.cd(folder); if (!success) qFatal("QtUtils::getFiles cd failure."); 47 + bool success = subdir.cd(folder); if (!success) qFatal("cd failure.");
48 files.append(getFiles(subdir, true)); 48 files.append(getFiles(subdir, true));
49 } 49 }
50 return files; 50 return files;
@@ -74,7 +74,7 @@ QStringList QtUtils::readLines(const QString &amp;file) @@ -74,7 +74,7 @@ QStringList QtUtils::readLines(const QString &amp;file)
74 void QtUtils::readFile(const QString &file, QStringList &lines) 74 void QtUtils::readFile(const QString &file, QStringList &lines)
75 { 75 {
76 QFile f(file); 76 QFile f(file);
77 - if (!f.open(QFile::ReadOnly)) qFatal("QtUtils::readFile unable to open %s for reading.", qPrintable(file)); 77 + if (!f.open(QFile::ReadOnly)) qFatal("Unable to open %s for reading.", qPrintable(file));
78 lines = QString(f.readAll()).split('\n', QString::SkipEmptyParts); 78 lines = QString(f.readAll()).split('\n', QString::SkipEmptyParts);
79 for (int i=0; i<lines.size(); i++) 79 for (int i=0; i<lines.size(); i++)
80 lines[i] = lines[i].simplified(); 80 lines[i] = lines[i].simplified();
@@ -84,7 +84,7 @@ void QtUtils::readFile(const QString &amp;file, QStringList &amp;lines) @@ -84,7 +84,7 @@ void QtUtils::readFile(const QString &amp;file, QStringList &amp;lines)
84 void QtUtils::readFile(const QString &file, QByteArray &data, bool uncompress) 84 void QtUtils::readFile(const QString &file, QByteArray &data, bool uncompress)
85 { 85 {
86 QFile f(file); 86 QFile f(file);
87 - if (!f.open(QFile::ReadOnly)) qFatal("QtUtils::readFile unable to open %s for reading.", qPrintable(file)); 87 + if (!f.open(QFile::ReadOnly)) qFatal("Unable to open %s for reading.", qPrintable(file));
88 data = f.readAll(); 88 data = f.readAll();
89 if (uncompress) data = qUncompress(data); 89 if (uncompress) data = qUncompress(data);
90 f.close(); 90 f.close();
@@ -112,7 +112,7 @@ void QtUtils::writeFile(const QString &amp;file, const QByteArray &amp;data, int compres @@ -112,7 +112,7 @@ void QtUtils::writeFile(const QString &amp;file, const QByteArray &amp;data, int compres
112 QFile f(file); 112 QFile f(file);
113 touchDir(f); 113 touchDir(f);
114 if (!f.open(QFile::WriteOnly)) 114 if (!f.open(QFile::WriteOnly))
115 - qFatal("QtUtils::writeFile failed to open %s for writing.", qPrintable(file)); 115 + qFatal("Failed to open %s for writing.", qPrintable(file));
116 f.write(contents); 116 f.write(contents);
117 f.close(); 117 f.close();
118 } 118 }
@@ -139,7 +139,7 @@ void QtUtils::emptyDir(QDir &amp;dir) @@ -139,7 +139,7 @@ void QtUtils::emptyDir(QDir &amp;dir)
139 { 139 {
140 foreach (const QString &folder, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks)) { 140 foreach (const QString &folder, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks)) {
141 QDir subdir(dir); 141 QDir subdir(dir);
142 - bool success = subdir.cd(folder); if (!success) qFatal("QtUtils::emptyDir cd failure."); 142 + bool success = subdir.cd(folder); if (!success) qFatal("cd failure.");
143 emptyDir(subdir); 143 emptyDir(subdir);
144 } 144 }
145 145
@@ -163,28 +163,28 @@ QString QtUtils::find(const QString &amp;file, const QString &amp;alt) @@ -163,28 +163,28 @@ QString QtUtils::find(const QString &amp;file, const QString &amp;alt)
163 { 163 {
164 if (QFileInfo(file).exists()) return file; 164 if (QFileInfo(file).exists()) return file;
165 if (QFileInfo(alt).exists()) return alt; 165 if (QFileInfo(alt).exists()) return alt;
166 - qFatal("QtUtils::find can't find file %s or alt %s\n", qPrintable(file), qPrintable(alt)); 166 + qFatal("Can't find file %s or alt %s\n", qPrintable(file), qPrintable(alt));
167 return ""; 167 return "";
168 } 168 }
169 169
170 bool QtUtils::toBool(const QString &string) 170 bool QtUtils::toBool(const QString &string)
171 { 171 {
172 bool ok; 172 bool ok;
173 - bool result = (bool)string.toInt(&ok); if (!ok) qFatal("QtUtils::toBool expected integer value, got %s.", qPrintable(string)); 173 + bool result = (bool)string.toInt(&ok); if (!ok) qFatal("Expected integer value, got %s.", qPrintable(string));
174 return result; 174 return result;
175 } 175 }
176 176
177 int QtUtils::toInt(const QString &string) 177 int QtUtils::toInt(const QString &string)
178 { 178 {
179 bool ok; 179 bool ok;
180 - int result = string.toInt(&ok); if (!ok) qFatal("QtUtils::toInt expected integer value, got %s.", qPrintable(string)); 180 + int result = string.toInt(&ok); if (!ok) qFatal("Expected integer value, got %s.", qPrintable(string));
181 return result; 181 return result;
182 } 182 }
183 183
184 float QtUtils::toFloat(const QString &string) 184 float QtUtils::toFloat(const QString &string)
185 { 185 {
186 bool ok; 186 bool ok;
187 - float result = string.toFloat(&ok); if (!ok) qFatal("QtUtils::toFloat expected floating point value, got %s.", qPrintable(string)); 187 + float result = string.toFloat(&ok); if (!ok) qFatal("Expected floating point value, got %s.", qPrintable(string));
188 return result; 188 return result;
189 } 189 }
190 190
@@ -194,7 +194,7 @@ QList&lt;float&gt; QtUtils::toFloats(const QStringList &amp;strings) @@ -194,7 +194,7 @@ QList&lt;float&gt; QtUtils::toFloats(const QStringList &amp;strings)
194 bool ok; 194 bool ok;
195 foreach (const QString &string, strings) { 195 foreach (const QString &string, strings) {
196 floats.append(string.toFloat(&ok)); 196 floats.append(string.toFloat(&ok));
197 - if (!ok) qFatal("QtUtils::toFloats failed to convert %s to floating point format.", qPrintable(string)); 197 + if (!ok) qFatal("Failed to convert %s to floating point format.", qPrintable(string));
198 } 198 }
199 return floats; 199 return floats;
200 } 200 }
@@ -239,13 +239,13 @@ QStringList QtUtils::parse(QString args, char split) @@ -239,13 +239,13 @@ QStringList QtUtils::parse(QString args, char split)
239 } else if ((args[i] == '(') || (args[i] == '[') || (args[i] == '<') || (args[i] == '{')) { 239 } else if ((args[i] == '(') || (args[i] == '[') || (args[i] == '<') || (args[i] == '{')) {
240 subexpressions.push(args[i]); 240 subexpressions.push(args[i]);
241 } else if (args[i] == ')') { 241 } else if (args[i] == ')') {
242 - if (subexpressions.pop() != '(') qFatal("QtUtils::parse unexpected ')'."); 242 + if (subexpressions.pop() != '(') qFatal("Unexpected ')'.");
243 } else if (args[i] == ']') { 243 } else if (args[i] == ']') {
244 - if (subexpressions.pop() != '[') qFatal("QtUtils::parse unexpected ']'."); 244 + if (subexpressions.pop() != '[') qFatal("Unexpected ']'.");
245 } else if (args[i] == '>') { 245 } else if (args[i] == '>') {
246 - if (subexpressions.pop() != '<') qFatal("QtUtils::parse unexpected '>'."); 246 + if (subexpressions.pop() != '<') qFatal("Unexpected '>'.");
247 } else if (args[i] == '}') { 247 } else if (args[i] == '}') {
248 - if (subexpressions.pop() != '{') qFatal("QtUtils::parse unexpected '}'."); 248 + if (subexpressions.pop() != '{') qFatal("Unexpected '}'.");
249 } else if (subexpressions.isEmpty() && (args[i] == split)) { 249 } else if (subexpressions.isEmpty() && (args[i] == split)) {
250 words.append(args.mid(start, i-start).trimmed()); 250 words.append(args.mid(start, i-start).trimmed());
251 start = i+1; 251 start = i+1;
sdk/openbr.cpp
@@ -204,7 +204,7 @@ void br_read_line(int *argc, const char ***argv) @@ -204,7 +204,7 @@ void br_read_line(int *argc, const char ***argv)
204 204
205 void br_reformat(const char *target_input, const char *query_input, const char *simmat, const char *output) 205 void br_reformat(const char *target_input, const char *query_input, const char *simmat, const char *output)
206 { 206 {
207 - Output::reformat(TemplateList::fromInput(target_input).files(), TemplateList::fromInput(query_input).files(), simmat, output); 207 + Output::reformat(TemplateList::fromGallery(target_input).files(), TemplateList::fromGallery(query_input).files(), simmat, output);
208 } 208 }
209 209
210 const char *br_scratch_path() 210 const char *br_scratch_path()
sdk/openbr_plugin.cpp
@@ -95,6 +95,11 @@ QList&lt;File&gt; File::split(const QString &amp;separator) const @@ -95,6 +95,11 @@ QList&lt;File&gt; File::split(const QString &amp;separator) const
95 return files; 95 return files;
96 } 96 }
97 97
  98 +QString File::resolved() const
  99 +{
  100 + return exists() ? name : Globals->path + "/" + name;
  101 +}
  102 +
98 bool File::contains(const QString &key) const 103 bool File::contains(const QString &key) const
99 { 104 {
100 return m_metadata.contains(key) || Globals->contains(key); 105 return m_metadata.contains(key) || Globals->contains(key);
@@ -150,7 +155,7 @@ void File::set(const QString &amp;key, const QVariant &amp;value) @@ -150,7 +155,7 @@ void File::set(const QString &amp;key, const QVariant &amp;value)
150 155
151 QVariant File::get(const QString &key) const 156 QVariant File::get(const QString &key) const
152 { 157 {
153 - if (!contains(key)) qFatal("File::get missing key: %s", qPrintable(key)); 158 + if (!contains(key)) qFatal("Missing key: %s", qPrintable(key));
154 return value(key); 159 return value(key);
155 } 160 }
156 161
@@ -177,9 +182,9 @@ void File::setBool(const QString &amp;key, bool value) @@ -177,9 +182,9 @@ void File::setBool(const QString &amp;key, bool value)
177 182
178 int File::getInt(const QString &key) const 183 int File::getInt(const QString &key) const
179 { 184 {
180 - if (!contains(key)) qFatal("File::getInt missing key: %s", qPrintable(key)); 185 + if (!contains(key)) qFatal("Missing key: %s", qPrintable(key));
181 bool ok; int result = value(key).toInt(&ok); 186 bool ok; int result = value(key).toInt(&ok);
182 - if (!ok) qFatal("File::getInt invalid conversion from: %s", qPrintable(getString(key))); 187 + if (!ok) qFatal("Invalid conversion from: %s", qPrintable(getString(key)));
183 return result; 188 return result;
184 } 189 }
185 190
@@ -193,9 +198,9 @@ int File::getInt(const QString &amp;key, int defaultValue) const @@ -193,9 +198,9 @@ int File::getInt(const QString &amp;key, int defaultValue) const
193 198
194 float File::getFloat(const QString &key) const 199 float File::getFloat(const QString &key) const
195 { 200 {
196 - if (!contains(key)) qFatal("File::getFloat missing key: %s", qPrintable(key)); 201 + if (!contains(key)) qFatal("Missing key: %s", qPrintable(key));
197 bool ok; float result = value(key).toFloat(&ok); 202 bool ok; float result = value(key).toFloat(&ok);
198 - if (!ok) qFatal("File::getFloat invalid conversion from: %s", qPrintable(getString(key))); 203 + if (!ok) qFatal("Invalid conversion from: %s", qPrintable(getString(key)));
199 return result; 204 return result;
200 } 205 }
201 206
@@ -209,7 +214,7 @@ float File::getFloat(const QString &amp;key, float defaultValue) const @@ -209,7 +214,7 @@ float File::getFloat(const QString &amp;key, float defaultValue) const
209 214
210 QString File::getString(const QString &key) const 215 QString File::getString(const QString &key) const
211 { 216 {
212 - if (!contains(key)) qFatal("File::getString missing key: %s", qPrintable(key)); 217 + if (!contains(key)) qFatal("Missing key: %s", qPrintable(key));
213 return value(key).toString(); 218 return value(key).toString();
214 } 219 }
215 220
@@ -440,14 +445,14 @@ QDataStream &amp;br::operator&gt;&gt;(QDataStream &amp;stream, Template &amp;t) @@ -440,14 +445,14 @@ QDataStream &amp;br::operator&gt;&gt;(QDataStream &amp;stream, Template &amp;t)
440 } 445 }
441 446
442 /* TemplateList - public methods */ 447 /* TemplateList - public methods */
443 -TemplateList TemplateList::fromInput(const br::File &input) 448 +TemplateList TemplateList::fromGallery(const br::File &gallery)
444 { 449 {
445 TemplateList templates; 450 TemplateList templates;
446 451
447 - foreach (const br::File &file, input.split()) { 452 + foreach (const br::File &file, gallery.split()) {
448 QScopedPointer<Gallery> i(Gallery::make(file)); 453 QScopedPointer<Gallery> i(Gallery::make(file));
449 TemplateList newTemplates = i->read(); 454 TemplateList newTemplates = i->read();
450 - const int crossValidate = input.getInt("crossValidate"); 455 + const int crossValidate = gallery.getInt("crossValidate");
451 if (crossValidate > 0) srand(0); 456 if (crossValidate > 0) srand(0);
452 457
453 // If file is a Format not a Gallery 458 // If file is a Format not a Gallery
@@ -456,13 +461,13 @@ TemplateList TemplateList::fromInput(const br::File &amp;input) @@ -456,13 +461,13 @@ TemplateList TemplateList::fromInput(const br::File &amp;input)
456 461
457 // Propogate metadata 462 // Propogate metadata
458 for (int i=0; i<newTemplates.size(); i++) { 463 for (int i=0; i<newTemplates.size(); i++) {
459 - newTemplates[i].file.append(input.localMetadata()); 464 + newTemplates[i].file.append(gallery.localMetadata());
460 newTemplates[i].file.append(file.localMetadata()); 465 newTemplates[i].file.append(file.localMetadata());
461 - newTemplates[i].file.insert("Input_Index", i+templates.size()); 466 + newTemplates[i].file.insert("Index", i+templates.size());
462 if (crossValidate > 0) newTemplates[i].file.insert("Cross_Validation_Partition", rand()%crossValidate); 467 if (crossValidate > 0) newTemplates[i].file.insert("Cross_Validation_Partition", rand()%crossValidate);
463 } 468 }
464 469
465 - if (!templates.isEmpty() && input.getBool("merge")) { 470 + if (!templates.isEmpty() && gallery.getBool("merge")) {
466 if (newTemplates.size() != templates.size()) 471 if (newTemplates.size() != templates.size())
467 qFatal("Inputs must be the same size in order to merge."); 472 qFatal("Inputs must be the same size in order to merge.");
468 for (int i=0; i<templates.size(); i++) 473 for (int i=0; i<templates.size(); i++)
@@ -652,7 +657,7 @@ void Object::setProperty(const QString &amp;name, const QString &amp;value) @@ -652,7 +657,7 @@ void Object::setProperty(const QString &amp;name, const QString &amp;value)
652 657
653 QVariant variant; 658 QVariant variant;
654 if (type.startsWith("QList<") && type.endsWith(">")) { 659 if (type.startsWith("QList<") && type.endsWith(">")) {
655 - if (!value.startsWith('[')) qFatal("Object::setProperty expected a list."); 660 + if (!value.startsWith('[')) qFatal("Expected a list.");
656 const QStringList strings = parse(value.mid(1, value.size()-2)); 661 const QStringList strings = parse(value.mid(1, value.size()-2));
657 662
658 if (type == "QList<float>") { 663 if (type == "QList<float>") {
@@ -1014,6 +1019,11 @@ void MatrixOutput::initialize(const FileList &amp;targetFiles, const FileList &amp;query @@ -1014,6 +1019,11 @@ void MatrixOutput::initialize(const FileList &amp;targetFiles, const FileList &amp;query
1014 data.create(queryFiles.size(), targetFiles.size(), CV_32FC1); 1019 data.create(queryFiles.size(), targetFiles.size(), CV_32FC1);
1015 } 1020 }
1016 1021
  1022 +MatrixOutput *MatrixOutput::make(const FileList &targetFiles, const FileList &queryFiles)
  1023 +{
  1024 + return dynamic_cast<MatrixOutput*>(Output::make(".Matrix", targetFiles, queryFiles));
  1025 +}
  1026 +
1017 /* MatrixOutput - protected methods */ 1027 /* MatrixOutput - protected methods */
1018 QString MatrixOutput::toString(int row, int column) const 1028 QString MatrixOutput::toString(int row, int column) const
1019 { 1029 {
sdk/openbr_plugin.h
@@ -126,7 +126,7 @@ void reset_##NAME() { NAME = DEFAULT; } @@ -126,7 +126,7 @@ void reset_##NAME() { NAME = DEFAULT; }
126 * path | QString | Resolve complete file paths from file names 126 * path | QString | Resolve complete file paths from file names
127 * enrollAll | bool | Enroll zero or more templates per file 127 * enrollAll | bool | Enroll zero or more templates per file
128 * separator | QString | Seperate #name into multiple files 128 * separator | QString | Seperate #name into multiple files
129 - * Input_Index | int | Index of a template in a template list 129 + * Index | int | Index of a template in a template list
130 * Label | float | Classification/Regression class 130 * Label | float | Classification/Regression class
131 * Confidence | float | Classification/Regression quality 131 * Confidence | float | Classification/Regression quality
132 * FTE | bool | Failure to enroll 132 * FTE | bool | Failure to enroll
@@ -153,7 +153,7 @@ struct BR_EXPORT File @@ -153,7 +153,7 @@ struct BR_EXPORT File
153 File(const QString &file) { init(file); } /*!< \brief Construct a file from a string. */ 153 File(const QString &file) { init(file); } /*!< \brief Construct a file from a string. */
154 File(const QString &file, const QVariant &label) { init(file); insert("Label", label); } /*!< \brief Construct a file from a string and assign a label. */ 154 File(const QString &file, const QVariant &label) { init(file); insert("Label", label); } /*!< \brief Construct a file from a string and assign a label. */
155 File(const char *file) { init(file); } /*!< \brief Construct a file from a c-style string. */ 155 File(const char *file) { init(file); } /*!< \brief Construct a file from a c-style string. */
156 - operator QString() const { return name; } /*!< \brief Returns #name. */ 156 + inline operator QString() const { return name; } /*!< \brief Returns #name. */
157 QString flat() const; /*!< \brief A stringified version of the file with metadata. */ 157 QString flat() const; /*!< \brief A stringified version of the file with metadata. */
158 QString hash() const; /*!< \brief A hash of the file. */ 158 QString hash() const; /*!< \brief A hash of the file. */
159 inline void clear() { name.clear(); m_metadata.clear(); } /*!< \brief Clears the file's name and metadata. */ 159 inline void clear() { name.clear(); m_metadata.clear(); } /*!< \brief Clears the file's name and metadata. */
@@ -187,6 +187,7 @@ struct BR_EXPORT File @@ -187,6 +187,7 @@ struct BR_EXPORT File
187 inline QString baseName() const { const QString baseName = QFileInfo(name).baseName(); 187 inline QString baseName() const { const QString baseName = QFileInfo(name).baseName();
188 return baseName.isEmpty() ? QDir(name).dirName() : baseName; } /*!< \brief Returns the file's base name. */ 188 return baseName.isEmpty() ? QDir(name).dirName() : baseName; } /*!< \brief Returns the file's base name. */
189 inline QString suffix() const { return QFileInfo(name).suffix(); } /*!< \brief Returns the file's extension. */ 189 inline QString suffix() const { return QFileInfo(name).suffix(); } /*!< \brief Returns the file's extension. */
  190 + QString resolved() const; /*!< \brief Returns name prepended with Globals->path if name does not exist. */
190 191
191 bool contains(const QString &key) const; /*!< \brief Returns \c true if the key has an associated value, \c false otherwise. */ 192 bool contains(const QString &key) const; /*!< \brief Returns \c true if the key has an associated value, \c false otherwise. */
192 QVariant value(const QString &key) const; /*!< \brief Returns the value for the specified key. */ 193 QVariant value(const QString &key) const; /*!< \brief Returns the value for the specified key. */
@@ -276,7 +277,7 @@ struct Template : public QList&lt;cv::Mat&gt; @@ -276,7 +277,7 @@ struct Template : public QList&lt;cv::Mat&gt;
276 Template(const cv::Mat &mat) { append(mat); } /*!< \brief Append a matrix. */ 277 Template(const cv::Mat &mat) { append(mat); } /*!< \brief Append a matrix. */
277 278
278 inline const cv::Mat &m() const { static const cv::Mat NullMatrix; 279 inline const cv::Mat &m() const { static const cv::Mat NullMatrix;
279 - return isEmpty() ? qFatal("Template::m() empty template."), NullMatrix : last(); } /*!< \brief Idiom to treat the template as a matrix. */ 280 + return isEmpty() ? qFatal("Empty template."), NullMatrix : last(); } /*!< \brief Idiom to treat the template as a matrix. */
280 inline cv::Mat &m() { return isEmpty() ? append(cv::Mat()), last() : last(); } /*!< \brief Idiom to treat the template as a matrix. */ 281 inline cv::Mat &m() { return isEmpty() ? append(cv::Mat()), last() : last(); } /*!< \brief Idiom to treat the template as a matrix. */
281 inline cv::Mat &operator=(const cv::Mat &other) { return m() = other; } /*!< \brief Idiom to treat the template as a matrix. */ 282 inline cv::Mat &operator=(const cv::Mat &other) { return m() = other; } /*!< \brief Idiom to treat the template as a matrix. */
282 inline operator const cv::Mat&() const { return m(); } /*!< \brief Idiom to treat the template as a matrix. */ 283 inline operator const cv::Mat&() const { return m(); } /*!< \brief Idiom to treat the template as a matrix. */
@@ -330,9 +331,10 @@ struct TemplateList : public QList&lt;Template&gt; @@ -330,9 +331,10 @@ struct TemplateList : public QList&lt;Template&gt;
330 331
331 TemplateList() : uniform(false) {} 332 TemplateList() : uniform(false) {}
332 TemplateList(const QList<Template> &templates) : uniform(false) { append(templates); } /*!< \brief Initialize the template list from another template list. */ 333 TemplateList(const QList<Template> &templates) : uniform(false) { append(templates); } /*!< \brief Initialize the template list from another template list. */
333 - TemplateList(const QList<File> &files) : uniform(false) { foreach (const File &file, files) append(file); }  
334 - BR_EXPORT static TemplateList fromInput(const File &input); /*!< \brief Create a template list from a br::Input. */ 334 + TemplateList(const QList<File> &files) : uniform(false) { foreach (const File &file, files) append(file); } /*!< \brief Initialize the template list from a file list. */
  335 + BR_EXPORT static TemplateList fromGallery(const File &gallery); /*!< \brief Create a template list from a br::Gallery. */
335 BR_EXPORT static TemplateList relabel(const TemplateList &tl); /*!< \brief Ensure labels are in the range [0,numClasses-1]. */ 336 BR_EXPORT static TemplateList relabel(const TemplateList &tl); /*!< \brief Ensure labels are in the range [0,numClasses-1]. */
  337 +
336 /*! 338 /*!
337 * \brief Returns the total number of bytes in all the templates. 339 * \brief Returns the total number of bytes in all the templates.
338 */ 340 */
@@ -365,6 +367,11 @@ struct TemplateList : public QList&lt;Template&gt; @@ -365,6 +367,11 @@ struct TemplateList : public QList&lt;Template&gt;
365 } 367 }
366 368
367 /*! 369 /*!
  370 + * \brief Returns #br::Template::file for each template in the list.
  371 + */
  372 + FileList operator()() const { return files(); }
  373 +
  374 + /*!
368 * \brief Returns br::Template::label() for each template in the list. 375 * \brief Returns br::Template::label() for each template in the list.
369 */ 376 */
370 template <typename T> 377 template <typename T>
@@ -859,6 +866,11 @@ class BR_EXPORT MatrixOutput : public Output @@ -859,6 +866,11 @@ class BR_EXPORT MatrixOutput : public Output
859 public: 866 public:
860 cv::Mat data; /*!< \brief The similarity matrix. */ 867 cv::Mat data; /*!< \brief The similarity matrix. */
861 868
  869 + /*!
  870 + * \brief Make a MatrixOutput from gallery and probe file lists.
  871 + */
  872 + static MatrixOutput *make(const FileList &targetFiles, const FileList &queryFiles);
  873 +
862 protected: 874 protected:
863 QString toString(int row, int column) const; /*!< \brief Converts the value requested similarity score to a string. */ 875 QString toString(int row, int column) const; /*!< \brief Converts the value requested similarity score to a string. */
864 876
sdk/plugins/cascade.cpp
@@ -37,7 +37,7 @@ public: @@ -37,7 +37,7 @@ public:
37 else if (model == "Eye") file += "haarcascades/haarcascade_eye_tree_eyeglasses.xml"; 37 else if (model == "Eye") file += "haarcascades/haarcascade_eye_tree_eyeglasses.xml";
38 else if (model == "FrontalFace") file += "haarcascades/haarcascade_frontalface_alt2.xml"; 38 else if (model == "FrontalFace") file += "haarcascades/haarcascade_frontalface_alt2.xml";
39 else if (model == "ProfileFace") file += "haarcascades/haarcascade_profileface.xml"; 39 else if (model == "ProfileFace") file += "haarcascades/haarcascade_profileface.xml";
40 - else qFatal("CascadeResourceMaker::CascadeResourceMaker invalid model."); 40 + else qFatal("Invalid model.");
41 } 41 }
42 42
43 private: 43 private:
@@ -45,7 +45,7 @@ private: @@ -45,7 +45,7 @@ private:
45 { 45 {
46 CascadeClassifier *cascade = new CascadeClassifier(); 46 CascadeClassifier *cascade = new CascadeClassifier();
47 if (!cascade->load(file.toStdString())) 47 if (!cascade->load(file.toStdString()))
48 - qFatal("CascadeResourceMaker::make failed to load: %s", qPrintable(file)); 48 + qFatal("Failed to load: %s", qPrintable(file));
49 return cascade; 49 return cascade;
50 } 50 }
51 }; 51 };
sdk/plugins/distance.cpp
@@ -87,7 +87,7 @@ private: @@ -87,7 +87,7 @@ private:
87 } 87 }
88 88
89 if (result != result) 89 if (result != result)
90 - qFatal("Dist::compare NaN result."); 90 + qFatal("NaN result.");
91 91
92 return -log(result+1); 92 return -log(result+1);
93 } 93 }
sdk/plugins/eigen3.cpp
@@ -82,7 +82,7 @@ private: @@ -82,7 +82,7 @@ private:
82 void train(const TemplateList &trainingSet) 82 void train(const TemplateList &trainingSet)
83 { 83 {
84 if (trainingSet.first().m().type() != CV_32FC1) 84 if (trainingSet.first().m().type() != CV_32FC1)
85 - qFatal("PCA::train requires single channel 32-bit floating point matrices."); 85 + qFatal("Requires single channel 32-bit floating point matrices.");
86 86
87 originalRows = trainingSet.first().m().rows; 87 originalRows = trainingSet.first().m().rows;
88 int dimsIn = trainingSet.first().m().rows * trainingSet.first().m().cols; 88 int dimsIn = trainingSet.first().m().rows * trainingSet.first().m().cols;
@@ -156,7 +156,7 @@ private: @@ -156,7 +156,7 @@ private:
156 } 156 }
157 } else { 157 } else {
158 if (keep + drop > allEVals.rows()) 158 if (keep + drop > allEVals.rows())
159 - qFatal("PCA::train insufficient samples, needed at least %d but only got %d.", (int)keep + drop, (int)allEVals.rows()); 159 + qFatal("Insufficient samples, needed at least %d but only got %d.", (int)keep + drop, (int)allEVals.rows());
160 } 160 }
161 161
162 // Keep highest energy vectors 162 // Keep highest energy vectors
sdk/plugins/eyes.cpp
@@ -71,10 +71,10 @@ public: @@ -71,10 +71,10 @@ public:
71 71
72 // Open the eye locator model 72 // Open the eye locator model
73 file.setFileName(Globals->sdkPath + "/share/openbr/models/EyeLocatorASEF128x128.fel"); 73 file.setFileName(Globals->sdkPath + "/share/openbr/models/EyeLocatorASEF128x128.fel");
74 - bool success = file.open(QFile::ReadOnly); if (!success) qFatal("ASEFEyes::ASEFEyes failed to open %s for reading.", qPrintable(file.fileName())); 74 + if (!file.open(QFile::ReadOnly)) qFatal("Failed to open %s for reading.", qPrintable(file.fileName()));
75 75
76 // Check the first line 76 // Check the first line
77 - line = file.readLine().simplified(); if (line != "CFEL") qFatal("ASEFEyes::ASEFEyes invalid header."); 77 + if (file.readLine().simplified() != "CFEL") qFatal("Invalid header.");
78 78
79 // Read past the comment and copyright. 79 // Read past the comment and copyright.
80 file.readLine(); 80 file.readLine();
sdk/plugins/fill.cpp
@@ -114,7 +114,7 @@ class BlendTransform : public UntrainableMetaTransform @@ -114,7 +114,7 @@ class BlendTransform : public UntrainableMetaTransform
114 114
115 void project(const Template &src, Template &dst) const 115 void project(const Template &src, Template &dst) const
116 { 116 {
117 - if (src.size() != 2) qFatal("Blend::project expected two source matrices."); 117 + if (src.size() != 2) qFatal("Expected two source matrices.");
118 addWeighted(src[0], alpha, src[1], 1-alpha, 0, dst); 118 addWeighted(src[0], alpha, src[1], 1-alpha, 0, dst);
119 } 119 }
120 }; 120 };
sdk/plugins/filter.cpp
@@ -130,7 +130,7 @@ class CSDNTransform : public UntrainableTransform @@ -130,7 +130,7 @@ class CSDNTransform : public UntrainableTransform
130 130
131 void project(const Template &src, Template &dst) const 131 void project(const Template &src, Template &dst) const
132 { 132 {
133 - if (src.m().channels() != 1) qFatal("ContrastEq::project expected single channel source matrix."); 133 + if (src.m().channels() != 1) qFatal("Expected single channel source matrix.");
134 134
135 const int nRows = src.m().rows; 135 const int nRows = src.m().rows;
136 const int nCols = src.m().cols; 136 const int nCols = src.m().cols;
@@ -180,7 +180,7 @@ class ContrastEqTransform : public UntrainableTransform @@ -180,7 +180,7 @@ class ContrastEqTransform : public UntrainableTransform
180 180
181 void project(const Template &src, Template &dst) const 181 void project(const Template &src, Template &dst) const
182 { 182 {
183 - if (src.m().channels() != 1) qFatal("ContrastEq::project expected single channel source matrix."); 183 + if (src.m().channels() != 1) qFatal("Expected single channel source matrix.");
184 184
185 // Stage 1 185 // Stage 1
186 Mat stage1; 186 Mat stage1;
sdk/plugins/format.cpp
@@ -112,7 +112,7 @@ class binFormat : public Format @@ -112,7 +112,7 @@ class binFormat : public Format
112 { 112 {
113 Mat m; 113 Mat m;
114 t.m().convertTo(m, CV_32F); 114 t.m().convertTo(m, CV_32F);
115 - if (m.channels() != 1) qFatal("binFormat::write only supports single channel matrices."); 115 + if (m.channels() != 1) qFatal("Only supports single channel matrices.");
116 116
117 QByteArray data; 117 QByteArray data;
118 QDataStream stream(&data, QFile::WriteOnly); 118 QDataStream stream(&data, QFile::WriteOnly);
@@ -168,8 +168,8 @@ class csvFormat : public Format @@ -168,8 +168,8 @@ class csvFormat : public Format
168 void write(const Template &t) const 168 void write(const Template &t) const
169 { 169 {
170 const Mat &m = t.m(); 170 const Mat &m = t.m();
171 - if (t.size() != 1) qFatal("csvFormat::write only supports single matrix templates.");  
172 - if (m.channels() != 1) qFatal("csvFormat::write only supports single channel matrices."); 171 + if (t.size() != 1) qFatal("Only supports single matrix templates.");
  172 + if (m.channels() != 1) qFatal("Only supports single channel matrices.");
173 173
174 QStringList lines; lines.reserve(m.rows); 174 QStringList lines; lines.reserve(m.rows);
175 for (int r=0; r<m.rows; r++) { 175 for (int r=0; r<m.rows; r++) {
@@ -337,7 +337,7 @@ class matFormat : public Format @@ -337,7 +337,7 @@ class matFormat : public Format
337 int skipBytes = (bytes < 4) ? (4 - bytes) : (8 - bytes%8)%8; 337 int skipBytes = (bytes < 4) ? (4 - bytes) : (8 - bytes%8)%8;
338 if (skipBytes != 0) stream.skipRawData(skipBytes); 338 if (skipBytes != 0) stream.skipRawData(skipBytes);
339 339
340 - if (error) qFatal("matFormat::Element Unexpected end of file."); 340 + if (error) qFatal("Unexpected end of file.");
341 } 341 }
342 342
343 void print() const 343 void print() const
@@ -356,7 +356,7 @@ class matFormat : public Format @@ -356,7 +356,7 @@ class matFormat : public Format
356 QByteArray header(128, 0); 356 QByteArray header(128, 0);
357 f.readRawData(header.data(), 128); 357 f.readRawData(header.data(), 128);
358 if (!header.startsWith("MATLAB 5.0 MAT-file")) 358 if (!header.startsWith("MATLAB 5.0 MAT-file"))
359 - qFatal("matFormat::read Invalid MAT header."); 359 + qFatal("Invalid MAT header.");
360 } 360 }
361 361
362 Template t(file); 362 Template t(file);
@@ -426,7 +426,7 @@ class matFormat : public Format @@ -426,7 +426,7 @@ class matFormat : public Format
426 426
427 for (int i=0; i<t.size(); i++) { 427 for (int i=0; i<t.size(); i++) {
428 const Mat &m = t[i]; 428 const Mat &m = t[i];
429 - if (m.channels() != 1) qFatal("matFormat::write only supports single channel matrices."); 429 + if (m.channels() != 1) qFatal("Only supports single channel matrices.");
430 430
431 QByteArray subdata; 431 QByteArray subdata;
432 QDataStream substream(&subdata, QFile::WriteOnly); 432 QDataStream substream(&subdata, QFile::WriteOnly);
@@ -443,7 +443,7 @@ class matFormat : public Format @@ -443,7 +443,7 @@ class matFormat : public Format
443 case CV_16UC1: arrayClass = 10; break; 443 case CV_16UC1: arrayClass = 10; break;
444 case CV_16SC1: arrayClass = 11; break; 444 case CV_16SC1: arrayClass = 11; break;
445 case CV_32SC1: arrayClass = 12; break; 445 case CV_32SC1: arrayClass = 12; break;
446 - default: qFatal("matFormat::write unsupported matrix class."); 446 + default: qFatal("Unsupported matrix class.");
447 } 447 }
448 substream.writeRawData((const char*)&type, 4); 448 substream.writeRawData((const char*)&type, 4);
449 substream.writeRawData((const char*)&bytes, 4); 449 substream.writeRawData((const char*)&bytes, 4);
@@ -480,7 +480,7 @@ class matFormat : public Format @@ -480,7 +480,7 @@ class matFormat : public Format
480 case CV_32SC1: type = 5; break; 480 case CV_32SC1: type = 5; break;
481 case CV_32FC1: type = 7; break; 481 case CV_32FC1: type = 7; break;
482 case CV_64FC1: type = 9; break; 482 case CV_64FC1: type = 9; break;
483 - default: qFatal("matFormat::write unsupported matrix type."); 483 + default: qFatal("Unsupported matrix type.");
484 } 484 }
485 quint32 bytes = m.elemSize() * m.rows * m.cols; 485 quint32 bytes = m.elemSize() * m.rows * m.cols;
486 QByteArray buffer((8 - bytes%8)%8, 0); 486 QByteArray buffer((8 - bytes%8)%8, 0);
@@ -531,7 +531,7 @@ class webcamFormat : public Format @@ -531,7 +531,7 @@ class webcamFormat : public Format
531 void write(const Template &t) const 531 void write(const Template &t) const
532 { 532 {
533 (void) t; 533 (void) t;
534 - qFatal("webcamFormat::write not supported."); 534 + qFatal("Not supported.");
535 } 535 }
536 }; 536 };
537 537
@@ -552,8 +552,8 @@ class xmlFormat : public Format @@ -552,8 +552,8 @@ class xmlFormat : public Format
552 { 552 {
553 QDomDocument doc(file); 553 QDomDocument doc(file);
554 QFile f(file); 554 QFile f(file);
555 - if (!f.open(QIODevice::ReadOnly)) qFatal("xmlFormat::read unable to open %s for reading.", qPrintable(file.flat()));  
556 - if (!doc.setContent(&f)) qFatal("xmlFormat::read unable to parse %s.", qPrintable(file.flat())); 555 + if (!f.open(QIODevice::ReadOnly)) qFatal("Unable to open %s for reading.", qPrintable(file.flat()));
  556 + if (!doc.setContent(&f)) qFatal("Unable to parse %s.", qPrintable(file.flat()));
557 f.close(); 557 f.close();
558 558
559 Template t; 559 Template t;
@@ -599,7 +599,7 @@ class xmlFormat : public Format @@ -599,7 +599,7 @@ class xmlFormat : public Format
599 void write(const Template &t) const 599 void write(const Template &t) const
600 { 600 {
601 (void) t; 601 (void) t;
602 - qFatal("xmlFormat::write not supported."); 602 + qFatal("Not supported.");
603 } 603 }
604 }; 604 };
605 605
sdk/plugins/gallery.cpp
@@ -80,7 +80,7 @@ BR_REGISTER(Gallery, galGallery) @@ -80,7 +80,7 @@ BR_REGISTER(Gallery, galGallery)
80 80
81 /*! 81 /*!
82 * \ingroup galleries 82 * \ingroup galleries
83 - * \brief Reads and writes templates to folders of images. 83 + * \brief Reads/writes templates to/from folders.
84 * \author Josh Klontz \cite jklontz 84 * \author Josh Klontz \cite jklontz
85 */ 85 */
86 class EmptyGallery : public Gallery 86 class EmptyGallery : public Gallery
@@ -120,9 +120,14 @@ class EmptyGallery : public Gallery @@ -120,9 +120,14 @@ class EmptyGallery : public Gallery
120 // Enrolling a null file is used as an idiom to initialize an algorithm 120 // Enrolling a null file is used as an idiom to initialize an algorithm
121 if (file.name.isEmpty()) return; 121 if (file.name.isEmpty()) return;
122 122
123 - QMutexLocker diskLocker(&diskLock);  
124 - if (t.isNull()) QFile::copy((t.file.exists() ? QString() : Globals->path+"/") + t.file.name, file.name + "/" + t.file.fileName());  
125 - else OpenCVUtils::saveImage(t, file.name + "/" + t.file.baseName() + ".png"); 123 + const QString destination = file.name + "/" + t.file.fileName();
  124 + QMutexLocker diskLocker(&diskLock); // Windows prefers to crash when writing to disk in parallel
  125 + if (t.isNull()) {
  126 + QFile::copy(t.file.resolved(), destination);
  127 + } else {
  128 + QScopedPointer<Format> format(Factory<Format>::make(destination));
  129 + format->write(t);
  130 + }
126 } 131 }
127 }; 132 };
128 133
@@ -286,12 +291,12 @@ class memGallery : public Gallery @@ -286,12 +291,12 @@ class memGallery : public Gallery
286 size_t offset = 0; 291 size_t offset = 0;
287 for (int i=0; i<templates.size(); i++) { 292 for (int i=0; i<templates.size(); i++) {
288 Template &t = templates[i]; 293 Template &t = templates[i];
289 - if (t.size() > 1) qFatal("memGallery::align can't handle multi-matrix template %s.", qPrintable(t.file.flat())); 294 + if (t.size() > 1) qFatal("Can't handle multi-matrix template %s.", qPrintable(t.file.flat()));
290 295
291 cv::Mat &m = t; 296 cv::Mat &m = t;
292 if (m.data) { 297 if (m.data) {
293 const size_t size = m.total() * m.elemSize(); 298 const size_t size = m.total() * m.elemSize();
294 - if (!m.isContinuous()) qFatal("memGallery::align requires continuous matrix data of size %d for %s.", (int)size, qPrintable(t.file.flat())); 299 + if (!m.isContinuous()) qFatal("Requires continuous matrix data of size %d for %s.", (int)size, qPrintable(t.file.flat()));
295 memcpy(&(alignedData.data()[offset]), m.ptr(), size); 300 memcpy(&(alignedData.data()[offset]), m.ptr(), size);
296 m = cv::Mat(m.rows, m.cols, m.type(), &(alignedData.data()[offset])); 301 m = cv::Mat(m.rows, m.cols, m.type(), &(alignedData.data()[offset]));
297 offset += size; 302 offset += size;
@@ -591,7 +596,7 @@ class dbGallery : public Gallery @@ -591,7 +596,7 @@ class dbGallery : public Gallery
591 void write(const Template &t) 596 void write(const Template &t)
592 { 597 {
593 (void) t; 598 (void) t;
594 - qFatal("Writing not supported."); 599 + qFatal("Not supported.");
595 } 600 }
596 }; 601 };
597 602
@@ -644,7 +649,7 @@ class googleGallery : public Gallery @@ -644,7 +649,7 @@ class googleGallery : public Gallery
644 void write(const Template &t) 649 void write(const Template &t)
645 { 650 {
646 (void) t; 651 (void) t;
647 - qFatal("Writing to a txtGallery not supported."); 652 + qFatal("Not supported.");
648 } 653 }
649 }; 654 };
650 655
sdk/plugins/keypoint.cpp
@@ -42,7 +42,7 @@ class KeyPointDetectorTransform : public UntrainableTransform @@ -42,7 +42,7 @@ class KeyPointDetectorTransform : public UntrainableTransform
42 { 42 {
43 featureDetector = FeatureDetector::create(detector.toStdString()); 43 featureDetector = FeatureDetector::create(detector.toStdString());
44 if (featureDetector.empty()) 44 if (featureDetector.empty())
45 - qFatal("KeyPointDetector::init failed to create KeyPointDetector: %s", qPrintable(detector)); 45 + qFatal("Failed to create KeyPointDetector: %s", qPrintable(detector));
46 } 46 }
47 47
48 void project(const Template &src, Template &dst) const 48 void project(const Template &src, Template &dst) const
@@ -85,7 +85,7 @@ class KeyPointDescriptorTransform : public UntrainableTransform @@ -85,7 +85,7 @@ class KeyPointDescriptorTransform : public UntrainableTransform
85 { 85 {
86 descriptorExtractor = DescriptorExtractor::create(descriptor.toStdString()); 86 descriptorExtractor = DescriptorExtractor::create(descriptor.toStdString());
87 if (descriptorExtractor.empty()) 87 if (descriptorExtractor.empty())
88 - qFatal("KeyPointDescriptor::make failed to create DescriptorExtractor: %s", qPrintable(descriptor)); 88 + qFatal("Failed to create DescriptorExtractor: %s", qPrintable(descriptor));
89 } 89 }
90 90
91 void project(const Template &src, Template &dst) const 91 void project(const Template &src, Template &dst) const
@@ -123,7 +123,7 @@ class KeyPointMatcherTransform : public Distance @@ -123,7 +123,7 @@ class KeyPointMatcherTransform : public Distance
123 { 123 {
124 descriptorMatcher = DescriptorMatcher::create(matcher.toStdString()); 124 descriptorMatcher = DescriptorMatcher::create(matcher.toStdString());
125 if (descriptorMatcher.empty()) 125 if (descriptorMatcher.empty())
126 - qFatal("KeyPointMatcher::make failed to create DescriptorMatcher: %s", qPrintable(matcher)); 126 + qFatal("Failed to create DescriptorMatcher: %s", qPrintable(matcher));
127 } 127 }
128 128
129 float compare(const Template &a, const Template &b) const 129 float compare(const Template &a, const Template &b) const
sdk/plugins/lbp.cpp
@@ -171,7 +171,7 @@ class ColoredU2Transform : public UntrainableTransform @@ -171,7 +171,7 @@ class ColoredU2Transform : public UntrainableTransform
171 } 171 }
172 172
173 if (src.m().type() != CV_8UC1) 173 if (src.m().type() != CV_8UC1)
174 - qFatal("ColoredU2::project expected 8UC1 source type."); 174 + qFatal("Expected 8UC1 source type.");
175 175
176 Mat hue, saturation, value; 176 Mat hue, saturation, value;
177 LUT(src, hueLUT, hue); 177 LUT(src, hueLUT, hue);
sdk/plugins/mask.cpp
@@ -59,7 +59,7 @@ class GradientMaskTransform : public UntrainableTransform @@ -59,7 +59,7 @@ class GradientMaskTransform : public UntrainableTransform
59 void project(const Template &src, Template &dst) const 59 void project(const Template &src, Template &dst) const
60 { 60 {
61 const Mat &m = src.m(); 61 const Mat &m = src.m();
62 - if (m.type() != CV_8UC1) qFatal("GradientMask operates on 8UC1 matrices."); 62 + if (m.type() != CV_8UC1) qFatal("Requires 8UC1 matrices.");
63 Mat n = Mat(m.rows, m.cols, CV_8UC1); 63 Mat n = Mat(m.rows, m.cols, CV_8UC1);
64 n.setTo(255); 64 n.setTo(255);
65 for (int i=0; i<m.rows; i++) { 65 for (int i=0; i<m.rows; i++) {
sdk/plugins/meta.cpp
@@ -39,8 +39,8 @@ static TemplateList Simplified(const TemplateList &amp;templates) @@ -39,8 +39,8 @@ static TemplateList Simplified(const TemplateList &amp;templates)
39 const bool fte = t.file.getBool("FTE"); 39 const bool fte = t.file.getBool("FTE");
40 QList<QPointF> landmarks = t.file.landmarks(); 40 QList<QPointF> landmarks = t.file.landmarks();
41 QList<QRectF> ROIs = t.file.ROIs(); 41 QList<QRectF> ROIs = t.file.ROIs();
42 - if (landmarks.size() % t.size() != 0) qFatal("TemplateList::simplified uneven landmark count.");  
43 - if (ROIs.size() % t.size() != 0) qFatal("TemplateList::simplified uneven ROI count."); 42 + if (landmarks.size() % t.size() != 0) qFatal("Uneven landmark count.");
  43 + if (ROIs.size() % t.size() != 0) qFatal("Uneven ROI count.");
44 const int landmarkStep = landmarks.size() / t.size(); 44 const int landmarkStep = landmarks.size() / t.size();
45 const int ROIStep = ROIs.size() / t.size(); 45 const int ROIStep = ROIs.size() / t.size();
46 46
@@ -281,7 +281,7 @@ class ForkTransform : public MetaTransform @@ -281,7 +281,7 @@ class ForkTransform : public MetaTransform
281 foreach (const Transform *f, transforms) { 281 foreach (const Transform *f, transforms) {
282 TemplateList m; 282 TemplateList m;
283 f->project(src, m); 283 f->project(src, m);
284 - if (m.size() != dst.size()) qFatal("Fork::project templateList is of an unexpected size."); 284 + if (m.size() != dst.size()) qFatal("TemplateList is of an unexpected size.");
285 for (int i=0; i<src.size(); i++) dst[i].append(m[i]); 285 for (int i=0; i<src.size(); i++) dst[i].append(m[i]);
286 } 286 }
287 } else { 287 } else {
@@ -313,7 +313,8 @@ public: @@ -313,7 +313,8 @@ public:
313 313
314 // Write to cache 314 // Write to cache
315 QFile file("Cache"); 315 QFile file("Cache");
316 - bool success = file.open(QFile::WriteOnly); if (!success) qFatal("Cache::Cache unable to open %s for writing.", qPrintable(file.fileName())); 316 + if (!file.open(QFile::WriteOnly))
  317 + qFatal("Unable to open %s for writing.", qPrintable(file.fileName()));
317 QDataStream stream(&file); 318 QDataStream stream(&file);
318 stream << cache; 319 stream << cache;
319 file.close(); 320 file.close();
@@ -327,7 +328,8 @@ private: @@ -327,7 +328,8 @@ private:
327 // Read from cache 328 // Read from cache
328 QFile file("Cache"); 329 QFile file("Cache");
329 if (file.exists()) { 330 if (file.exists()) {
330 - bool success = file.open(QFile::ReadOnly); if (!success) qFatal("Cache::make unable to open %s for reading.", qPrintable(file.fileName())); 331 + if (!file.open(QFile::ReadOnly))
  332 + qFatal("Unable to open %s for reading.", qPrintable(file.fileName()));
331 QDataStream stream(&file); 333 QDataStream stream(&file);
332 stream >> cache; 334 stream >> cache;
333 file.close(); 335 file.close();
@@ -458,7 +460,8 @@ class FTETransform : public Transform @@ -458,7 +460,8 @@ class FTETransform : public Transform
458 460
459 QList<float> vals; 461 QList<float> vals;
460 foreach (const Template &t, projectedData) { 462 foreach (const Template &t, projectedData) {
461 - if (!t.file.contains(transform->objectName())) qFatal("FTE::train matrix metadata missing key %s.", qPrintable(transform->objectName())); 463 + if (!t.file.contains(transform->objectName()))
  464 + qFatal("Matrix metadata missing key %s.", qPrintable(transform->objectName()));
462 vals.append(t.file.getFloat(transform->objectName())); 465 vals.append(t.file.getFloat(transform->objectName()));
463 } 466 }
464 float q1, q3; 467 float q1, q3;
sdk/plugins/normalize.cpp
@@ -100,7 +100,7 @@ private: @@ -100,7 +100,7 @@ private:
100 if (method == Mean) mean(m.col(i), &A, &B); 100 if (method == Mean) mean(m.col(i), &A, &B);
101 else if (method == Median) median(m.col(i), &A, &B); 101 else if (method == Median) median(m.col(i), &A, &B);
102 else if (method == Range) range(m.col(i), &A, &B); 102 else if (method == Range) range(m.col(i), &A, &B);
103 - else qFatal("Center::train invalid method"); 103 + else qFatal("Invalid method.");
104 ca->at<double>(0, i) = A; 104 ca->at<double>(0, i) = A;
105 cb->at<double>(0, i) = B; 105 cb->at<double>(0, i) = B;
106 } 106 }
sdk/plugins/pixel.cpp
@@ -54,7 +54,6 @@ class PerPixelClassifierTransform : public MetaTransform @@ -54,7 +54,6 @@ class PerPixelClassifierTransform : public MetaTransform
54 54
55 void rotate(Template &src, Template &dst) const 55 void rotate(Template &src, Template &dst) const
56 { 56 {
57 - //if (src.m().cols%9 != 0) qFatal("Rotation invariance can only be used after Neighbors");  
58 int images = (src.m().cols)/9; 57 int images = (src.m().cols)/9;
59 dst = src; 58 dst = src;
60 for (int i = 0; i < images; i++){ 59 for (int i = 0; i < images; i++){
sdk/plugins/pp5.cpp
@@ -283,7 +283,7 @@ class PP5Compare : public Distance @@ -283,7 +283,7 @@ class PP5Compare : public Distance
283 { 283 {
284 (void) target; 284 (void) target;
285 (void) query; 285 (void) query;
286 - qFatal("PP5Compare::compare (single templates) should never be called!"); 286 + qFatal("Compare single templates should never be called!");
287 return 0; 287 return 0;
288 } 288 }
289 289
sdk/plugins/quality.cpp
@@ -158,15 +158,15 @@ class MatchProbabilityDistance : public Distance @@ -158,15 +158,15 @@ class MatchProbabilityDistance : public Distance
158 distance->train(src); 158 distance->train(src);
159 159
160 const QList<int> labels = src.labels<int>(); 160 const QList<int> labels = src.labels<int>();
161 - QScopedPointer<MatrixOutput> memoryOutput(dynamic_cast<MatrixOutput*>(Output::make(".Matrix", FileList(src.size()), FileList(src.size()))));  
162 - distance->compare(src, src, memoryOutput.data()); 161 + QScopedPointer<MatrixOutput> matrixOutput(MatrixOutput::make(FileList(src.size()), FileList(src.size())));
  162 + distance->compare(src, src, matrixOutput.data());
163 163
164 QList<float> genuineScores, impostorScores; 164 QList<float> genuineScores, impostorScores;
165 genuineScores.reserve(labels.size()); 165 genuineScores.reserve(labels.size());
166 impostorScores.reserve(labels.size()*labels.size()); 166 impostorScores.reserve(labels.size()*labels.size());
167 for (int i=0; i<src.size(); i++) { 167 for (int i=0; i<src.size(); i++) {
168 for (int j=0; j<i; j++) { 168 for (int j=0; j<i; j++) {
169 - const float score = memoryOutput.data()->data.at<float>(i, j); 169 + const float score = matrixOutput.data()->data.at<float>(i, j);
170 if (score == -std::numeric_limits<float>::max()) continue; 170 if (score == -std::numeric_limits<float>::max()) continue;
171 if (labels[i] == labels[j]) genuineScores.append(score); 171 if (labels[i] == labels[j]) genuineScores.append(score);
172 else impostorScores.append(score); 172 else impostorScores.append(score);
@@ -217,8 +217,8 @@ class UnitDistance : public Distance @@ -217,8 +217,8 @@ class UnitDistance : public Distance
217 { 217 {
218 const TemplateList samples = templates.mid(0, 2000); 218 const TemplateList samples = templates.mid(0, 2000);
219 const QList<float> sampleLabels = samples.labels<float>(); 219 const QList<float> sampleLabels = samples.labels<float>();
220 - QScopedPointer<MatrixOutput> memoryOutput(dynamic_cast<MatrixOutput*>(Output::make(".Matrix", FileList(samples.size()), FileList(samples.size()))));  
221 - Distance::compare(samples, samples, memoryOutput.data()); 220 + QScopedPointer<MatrixOutput> matrixOutput(MatrixOutput::make(FileList(samples.size()), FileList(samples.size())));
  221 + Distance::compare(samples, samples, matrixOutput.data());
222 222
223 double genuineAccumulator, impostorAccumulator; 223 double genuineAccumulator, impostorAccumulator;
224 int genuineCount, impostorCount; 224 int genuineCount, impostorCount;
@@ -226,7 +226,7 @@ class UnitDistance : public Distance @@ -226,7 +226,7 @@ class UnitDistance : public Distance
226 226
227 for (int i=0; i<samples.size(); i++) { 227 for (int i=0; i<samples.size(); i++) {
228 for (int j=0; j<i; j++) { 228 for (int j=0; j<i; j++) {
229 - const float val = memoryOutput.data()->data.at<float>(i, j); 229 + const float val = matrixOutput.data()->data.at<float>(i, j);
230 if (sampleLabels[i] == sampleLabels[j]) { 230 if (sampleLabels[i] == sampleLabels[j]) {
231 genuineAccumulator += val; 231 genuineAccumulator += val;
232 genuineCount++; 232 genuineCount++;
sdk/plugins/quantize.cpp
@@ -95,7 +95,7 @@ class PackTransform : public UntrainableTransform @@ -95,7 +95,7 @@ class PackTransform : public UntrainableTransform
95 { 95 {
96 const Mat &m = src; 96 const Mat &m = src;
97 if ((m.cols % 2 != 0) || (m.type() != CV_8UC1)) 97 if ((m.cols % 2 != 0) || (m.type() != CV_8UC1))
98 - qFatal("Pack::project invalid template format."); 98 + qFatal("Invalid template format.");
99 99
100 Mat n(m.rows, m.cols/2, CV_8UC1); 100 Mat n(m.rows, m.cols/2, CV_8UC1);
101 for (int i=0; i<m.rows; i++) 101 for (int i=0; i<m.rows; i++)
sdk/plugins/reduce.cpp
@@ -32,7 +32,7 @@ class SubtractTransform : public UntrainableMetaTransform @@ -32,7 +32,7 @@ class SubtractTransform : public UntrainableMetaTransform
32 32
33 void project(const Template &src, Template &dst) const 33 void project(const Template &src, Template &dst) const
34 { 34 {
35 - if (src.size() != 2) qFatal("Subtract::project expected exactly two source images, got %d.", src.size()); 35 + if (src.size() != 2) qFatal("Expected exactly two source images, got %d.", src.size());
36 dst.file = src.file; 36 dst.file = src.file;
37 subtract(src[0], src[1], dst); 37 subtract(src[0], src[1], dst);
38 } 38 }
@@ -51,7 +51,7 @@ class AbsDiffTransform : public UntrainableMetaTransform @@ -51,7 +51,7 @@ class AbsDiffTransform : public UntrainableMetaTransform
51 51
52 void project(const Template &src, Template &dst) const 52 void project(const Template &src, Template &dst) const
53 { 53 {
54 - if (src.size() != 2) qFatal("AbsDiff::project expected exactly two source images, got %d.", src.size()); 54 + if (src.size() != 2) qFatal("Expected exactly two source images, got %d.", src.size());
55 dst.file = src.file; 55 dst.file = src.file;
56 absdiff(src[0], src[1], dst); 56 absdiff(src[0], src[1], dst);
57 } 57 }
sdk/plugins/regions.cpp
@@ -89,7 +89,7 @@ class CatTransform : public UntrainableMetaTransform @@ -89,7 +89,7 @@ class CatTransform : public UntrainableMetaTransform
89 dst.file = src.file; 89 dst.file = src.file;
90 90
91 if (src.size() % partitions != 0) 91 if (src.size() % partitions != 0)
92 - qFatal("Cat %d partitions does not evenly divide %d matrices.", partitions, src.size()); 92 + qFatal("%d partitions does not evenly divide %d matrices.", partitions, src.size());
93 QVector<int> sizes(partitions, 0); 93 QVector<int> sizes(partitions, 0);
94 for (int i=0; i<src.size(); i++) 94 for (int i=0; i<src.size(); i++)
95 sizes[i%partitions] += src[i].total() * src[i].channels(); 95 sizes[i%partitions] += src[i].total() * src[i].channels();
sdk/plugins/svm.cpp
@@ -86,7 +86,7 @@ private: @@ -86,7 +86,7 @@ private:
86 } 86 }
87 87
88 if (data.type() != CV_32FC1) 88 if (data.type() != CV_32FC1)
89 - qFatal("SVM::train expected single channel floating point training data."); 89 + qFatal("Expected single channel floating point training data.");
90 90
91 CvSVMParams params; 91 CvSVMParams params;
92 params.kernel_type = kernel; 92 params.kernel_type = kernel;
sdk/plugins/synthetic.cpp
@@ -71,7 +71,7 @@ class OrigLinearRegressionTransform : public UntrainableMetaTransform @@ -71,7 +71,7 @@ class OrigLinearRegressionTransform : public UntrainableMetaTransform
71 71
72 void project(const Template &src, Template &dst) const 72 void project(const Template &src, Template &dst) const
73 { 73 {
74 - if (src.size() != 3) qFatal("OrigLinearRegression::project expected exactly three source images, got %d.", src.size()); 74 + if (src.size() != 3) qFatal("Expected exactly three source images, got %d.", src.size());
75 Mat m1; src[0].convertTo(m1, CV_32F); assert(m1.isContinuous() && (m1.channels() == 1)); 75 Mat m1; src[0].convertTo(m1, CV_32F); assert(m1.isContinuous() && (m1.channels() == 1));
76 Mat m2; src[1].convertTo(m2, CV_32F); assert(m2.isContinuous() && (m2.channels() == 1)); 76 Mat m2; src[1].convertTo(m2, CV_32F); assert(m2.isContinuous() && (m2.channels() == 1));
77 Mat m3; src[2].convertTo(m3, CV_32F); assert(m3.isContinuous() && (m3.channels() == 1)); 77 Mat m3; src[2].convertTo(m3, CV_32F); assert(m3.isContinuous() && (m3.channels() == 1));
sdk/plugins/wavelet.cpp
@@ -109,7 +109,7 @@ private: @@ -109,7 +109,7 @@ private:
109 else if (component == Imaginary) dst = imaginary; 109 else if (component == Imaginary) dst = imaginary;
110 else if (component == Magnitude) dst = magnitude; 110 else if (component == Magnitude) dst = magnitude;
111 else if (component == Phase) dst = phase; 111 else if (component == Phase) dst = phase;
112 - else qFatal("Gabor::project invalid component."); 112 + else qFatal("Invalid component.");
113 } 113 }
114 }; 114 };
115 115
@@ -183,7 +183,7 @@ class GaborJetTransform : public UntrainableTransform @@ -183,7 +183,7 @@ class GaborJetTransform : public UntrainableTransform
183 else if (component == GaborTransform::Imaginary) dst = imaginary; 183 else if (component == GaborTransform::Imaginary) dst = imaginary;
184 else if (component == GaborTransform::Magnitude) dst = magnitude; 184 else if (component == GaborTransform::Magnitude) dst = magnitude;
185 else if (component == GaborTransform::Phase) dst = phase; 185 else if (component == GaborTransform::Phase) dst = phase;
186 - else qFatal("GaborJet::response invalid component."); 186 + else qFatal("Invalid component.");
187 return dst; 187 return dst;
188 } 188 }
189 189
sdk/plugins/youtube.cpp 0 → 100644
  1 +#include <openbr_plugin.h>
  2 +
  3 +namespace br
  4 +{
  5 +
  6 +/*!
  7 + * \ingroup transforms
  8 + * \brief Implements the YouTubesFaceDB \cite wolf11 experimental protocol.
  9 + * \author Josh Klontz \cite jklontz
  10 + */
  11 +class YouTubeFacesDBTransform : public UntrainableMetaTransform
  12 +{
  13 + Q_OBJECT
  14 + Q_PROPERTY(QString algorithm READ get_algorithm WRITE set_algorithm RESET reset_algorithm STORED false)
  15 + BR_PROPERTY(QString, algorithm, "")
  16 +
  17 + QSharedPointer<Transform> transform;
  18 + QSharedPointer<Distance> distance;
  19 +
  20 + void init()
  21 + {
  22 + transform = Transform::fromAlgorithm(algorithm);
  23 + distance = Distance::fromAlgorithm(algorithm);
  24 + }
  25 +
  26 + void project(const Template &src, Template &dst) const
  27 + {
  28 + dst = src;
  29 +
  30 + // First input is the header in 'splits.txt'
  31 + if (src.file.getInt("Index") == 0) return;
  32 +
  33 + const QStringList words = src.file.name.split(", ");
  34 + dst.file.name = words[0] + "_" + words[1] + "_" + words[4] + ".mtx";
  35 +
  36 + TemplateList queryTemplates = TemplateList::fromGallery(File(words[2]).resolved());
  37 + queryTemplates >> *transform;
  38 +
  39 + TemplateList targetTemplates = TemplateList::fromGallery(File(words[3]).resolved());
  40 + targetTemplates >> *transform;
  41 +
  42 + QScopedPointer<MatrixOutput> memoryOutput(MatrixOutput::make(targetTemplates.files(), queryTemplates.files()));
  43 + distance->compare(targetTemplates, queryTemplates, memoryOutput.data());
  44 +
  45 + dst.clear();
  46 + dst.m() = memoryOutput.data()->data;
  47 + }
  48 +};
  49 +
  50 +BR_REGISTER(Transform, YouTubeFacesDBTransform)
  51 +
  52 +} // namespace br
  53 +
  54 +#include "youtube.moc"
share/openbr/openbr.bib
@@ -162,6 +162,14 @@ @@ -162,6 +162,14 @@
162 Title = {Spectral Hashing}, 162 Title = {Spectral Hashing},
163 Year = {2008}} 163 Year = {2008}}
164 164
  165 +@inproceedings{wolf11,
  166 + author={Wolf, L. and Hassner, T. and Maoz, I.},
  167 + booktitle={Computer Vision and Pattern Recognition (CVPR), 2011 IEEE Conference on},
  168 + title={Face recognition in unconstrained videos with matched background similarity},
  169 + year={2011},
  170 + month={june},
  171 + pages={529-534}}
  172 +
165 @mastersthesis{zauner10, 173 @mastersthesis{zauner10,
166 Author = {Zauner, C.}, 174 Author = {Zauner, C.},
167 School = {Upper Austria University of Applied Sciences, Hagenberg Campus}, 175 School = {Upper Austria University of Applied Sciences, Hagenberg Campus},