Commit 4d39cf939575e209f8512b8efb5ee42c1e3ae930

Authored by Scott Klum
2 parents 66efa942 2d37a7bc

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

app/br/br.cpp
@@ -68,12 +68,13 @@ public: @@ -68,12 +68,13 @@ public:
68 if (argc == 0) printf("%s\nTry running 'br -help'\n", br_about()); 68 if (argc == 0) printf("%s\nTry running 'br -help'\n", br_about());
69 69
70 bool daemon = false; 70 bool daemon = false;
  71 + const char *daemon_pipe = NULL;
71 while (daemon || (argc > 0)) { 72 while (daemon || (argc > 0)) {
72 const char *fun; 73 const char *fun;
73 int parc; 74 int parc;
74 const char **parv; 75 const char **parv;
75 if (argc == 0) 76 if (argc == 0)
76 - br_read_stdin(&argc, &argv); 77 + br_read_pipe(daemon_pipe, &argc, &argv);
77 78
78 fun = argv[0]; 79 fun = argv[0];
79 if (fun[0] == '-') fun++; 80 if (fun[0] == '-') fun++;
@@ -158,8 +159,9 @@ public: @@ -158,8 +159,9 @@ public:
158 check(parc == 0, "No parameters expected for 'version'."); 159 check(parc == 0, "No parameters expected for 'version'.");
159 printf("%s\n", br_version()); 160 printf("%s\n", br_version());
160 } else if (!strcmp(fun, "daemon")) { 161 } else if (!strcmp(fun, "daemon")) {
161 - check(parc == 0, "No parameters expected for 'daemon'."); 162 + check(parc == 1, "Incorrect parameter count for 'daemon'.");
162 daemon = true; 163 daemon = true;
  164 + daemon_pipe = parv[0];
163 } else if (!strcmp(fun, "exit")) { 165 } else if (!strcmp(fun, "exit")) {
164 check(parc == 0, "No parameters expected for 'exit'."); 166 check(parc == 0, "No parameters expected for 'exit'.");
165 daemon = false; 167 daemon = false;
openbr/core/core.cpp
@@ -275,17 +275,14 @@ private: @@ -275,17 +275,14 @@ private:
275 return QFileInfo(file).exists() ? file : QString(); 275 return QFileInfo(file).exists() ? file : QString();
276 } 276 }
277 277
278 - void init(QString description) 278 + void init(const File &description)
279 { 279 {
280 // Check if a trained binary already exists for this algorithm 280 // Check if a trained binary already exists for this algorithm
281 const QString file = getFileName(description); 281 const QString file = getFileName(description);
282 - if (!file.isEmpty()) description = file; 282 + if (!file.isEmpty()) return init(file);
283 283
284 - File asdf(description);  
285 - QString distribute_status = asdf.get<QString>("distribute","true");  
286 -  
287 - if (QFileInfo(description).exists()) {  
288 - qDebug("Loading %s", qPrintable(QFileInfo(description).fileName())); 284 + if (description.exists()) {
  285 + qDebug("Loading %s", qPrintable(description.fileName()));
289 load(description); 286 load(description);
290 return; 287 return;
291 } 288 }
@@ -294,13 +291,11 @@ private: @@ -294,13 +291,11 @@ private:
294 if (Globals->abbreviations.contains(description)) 291 if (Globals->abbreviations.contains(description))
295 return init(Globals->abbreviations[description]); 292 return init(Globals->abbreviations[description]);
296 293
297 - QStringList words = QtUtils::parse(description, ':');  
298 - if (words.size() > 2) qFatal("Invalid algorithm format."); 294 + QStringList words = QtUtils::parse(description.flat(), ':');
  295 + if ((words.size() < 1) || (words.size() > 2)) qFatal("Invalid algorithm format.");
299 296
300 - if (distribute_status == "true") {  
301 - words[0].prepend("DistributeTemplate(");  
302 - words[0].append(")");  
303 - } 297 + if (description.getBool("distribute", true))
  298 + words[0] = "DistributeTemplate(" + words[0] + ")";
304 299
305 transform = QSharedPointer<Transform>(Transform::make(words[0], NULL)); 300 transform = QSharedPointer<Transform>(Transform::make(words[0], NULL));
306 if (words.size() > 1) distance = QSharedPointer<Distance>(Distance::make(words[1], NULL)); 301 if (words.size() > 1) distance = QSharedPointer<Distance>(Distance::make(words[1], NULL));
openbr/openbr.cpp
@@ -182,17 +182,23 @@ float br_progress() @@ -182,17 +182,23 @@ float br_progress()
182 return Globals->progress(); 182 return Globals->progress();
183 } 183 }
184 184
185 -void br_read_stdin(int *argc, char ***argv) 185 +void br_read_pipe(const char *pipe, int *argc, char ***argv)
186 { 186 {
187 static QList<QByteArray> byteArrayList; 187 static QList<QByteArray> byteArrayList;
188 static QVector<char*> rawCharArrayList; 188 static QVector<char*> rawCharArrayList;
189 189
  190 + QFile file(pipe);
  191 + file.open(QFile::ReadOnly);
  192 + QTextStream stream(&file);
  193 +
190 QStringList args; 194 QStringList args;
191 while (args.isEmpty()) { 195 while (args.isEmpty()) {
192 - args = QtUtils::parse(QTextStream(stdin).readLine(), ' ');  
193 - QThread::yieldCurrentThread(); 196 + args = QtUtils::parse(stream.readAll(), ' ');
  197 + if (args.isEmpty()) QThread::sleep(100);
194 } 198 }
195 199
  200 + file.close();
  201 +
196 byteArrayList.clear(); rawCharArrayList.clear(); 202 byteArrayList.clear(); rawCharArrayList.clear();
197 foreach (const QString &string, args) { 203 foreach (const QString &string, args) {
198 byteArrayList.append(string.toLocal8Bit()); 204 byteArrayList.append(string.toLocal8Bit());
openbr/openbr.h
@@ -297,16 +297,15 @@ BR_EXPORT bool br_plot_metadata(int num_files, const char *files[], const char * @@ -297,16 +297,15 @@ BR_EXPORT bool br_plot_metadata(int num_files, const char *files[], const char *
297 BR_EXPORT float br_progress(); 297 BR_EXPORT float br_progress();
298 298
299 /*! 299 /*!
300 - * \brief Read and parse stdin. 300 + * \brief Read and parse arguments from a named pipe.
301 * 301 *
302 - * Used by the \ref cli to implement \c -daemon. 302 + * Used by the \ref cli to implement \c -daemon, generally not useful otherwise.
303 * Guaranteed to return at least one argument. 303 * Guaranteed to return at least one argument.
304 - * Generally not useful otherwise.  
305 * \param[out] argc argument count 304 * \param[out] argc argument count
306 * \param[out] argv argument list 305 * \param[out] argv argument list
307 * \note \ref managed_return_value 306 * \note \ref managed_return_value
308 */ 307 */
309 -BR_EXPORT void br_read_stdin(int *argc, char ***argv); 308 +BR_EXPORT void br_read_pipe(const char *pipe, int *argc, char ***argv);
310 309
311 /*! 310 /*!
312 * \brief Converts a simmat to a new output format. 311 * \brief Converts a simmat to a new output format.
openbr/openbr_plugin.cpp
@@ -801,8 +801,8 @@ void br::Context::setProperty(const QString &amp;key, const QString &amp;value) @@ -801,8 +801,8 @@ void br::Context::setProperty(const QString &amp;key, const QString &amp;value)
801 qDebug("Set %s%s", qPrintable(key), value.isEmpty() ? "" : qPrintable(" to " + value)); 801 qDebug("Set %s%s", qPrintable(key), value.isEmpty() ? "" : qPrintable(" to " + value));
802 802
803 if (key == "parallelism") { 803 if (key == "parallelism") {
804 - const int maxThreads = std::max(1, QThread::idealThreadCount());  
805 - QThreadPool::globalInstance()->setMaxThreadCount(parallelism ? std::min(maxThreads, abs(parallelism)) : maxThreads); 804 + if (parallelism <= 0) parallelism = 1;
  805 + QThreadPool::globalInstance()->setMaxThreadCount(parallelism);
806 } else if (key == "log") { 806 } else if (key == "log") {
807 logFile.close(); 807 logFile.close();
808 if (log.isEmpty()) return; 808 if (log.isEmpty()) return;
@@ -829,8 +829,17 @@ bool br::Context::checkSDKPath(const QString &amp;sdkPath) @@ -829,8 +829,17 @@ bool br::Context::checkSDKPath(const QString &amp;sdkPath)
829 // We create our own when the user hasn't 829 // We create our own when the user hasn't
830 static QCoreApplication *application = NULL; 830 static QCoreApplication *application = NULL;
831 831
832 -void br::Context::initialize(int &argc, char *argv[], QString sdkPath) 832 +void br::Context::initialize(int &argc, char *argv[], QString sdkPath, bool use_gui)
833 { 833 {
  834 + for (int i=0; i < argc; i ++)
  835 + {
  836 + if (strcmp("-useGui", argv[i]) == 0) {
  837 + const char * val = i+1 < argc ? argv[i+1] : "";
  838 + if (strcmp(val, "false") ==0 || strcmp(val, "0") == 0)
  839 + use_gui = false;
  840 + break;
  841 + }
  842 + }
834 // We take in argc as a reference due to: 843 // We take in argc as a reference due to:
835 // https://bugreports.qt-project.org/browse/QTBUG-5637 844 // https://bugreports.qt-project.org/browse/QTBUG-5637
836 // QApplication should be initialized before anything else. 845 // QApplication should be initialized before anything else.
@@ -861,6 +870,7 @@ void br::Context::initialize(int &amp;argc, char *argv[], QString sdkPath) @@ -861,6 +870,7 @@ void br::Context::initialize(int &amp;argc, char *argv[], QString sdkPath)
861 870
862 Globals = new Context(); 871 Globals = new Context();
863 Globals->init(File()); 872 Globals->init(File());
  873 + Globals->useGui = use_gui;
864 874
865 qInstallMessageHandler(messageHandler); 875 qInstallMessageHandler(messageHandler);
866 876
@@ -885,8 +895,7 @@ void br::Context::initialize(int &amp;argc, char *argv[], QString sdkPath) @@ -885,8 +895,7 @@ void br::Context::initialize(int &amp;argc, char *argv[], QString sdkPath)
885 } 895 }
886 Globals->sdkPath = sdkPath; 896 Globals->sdkPath = sdkPath;
887 897
888 - // Empirical evidence suggests an extra thread helps achieve full CPU utilization  
889 - QThreadPool::globalInstance()->releaseThread(); 898 + QThreadPool::globalInstance()->setMaxThreadCount(Globals->parallelism);
890 899
891 // Trigger registered initializers 900 // Trigger registered initializers
892 QList< QSharedPointer<Initializer> > initializers = Factory<Initializer>::makeAll(); 901 QList< QSharedPointer<Initializer> > initializers = Factory<Initializer>::makeAll();
@@ -896,9 +905,6 @@ void br::Context::initialize(int &amp;argc, char *argv[], QString sdkPath) @@ -896,9 +905,6 @@ void br::Context::initialize(int &amp;argc, char *argv[], QString sdkPath)
896 905
897 void br::Context::finalize() 906 void br::Context::finalize()
898 { 907 {
899 - // Undo the 'releaseThread()' in 'initialize()'  
900 - QThreadPool::globalInstance()->reserveThread();  
901 -  
902 // Trigger registered finalizers 908 // Trigger registered finalizers
903 QList< QSharedPointer<Initializer> > initializers = Factory<Initializer>::makeAll(); 909 QList< QSharedPointer<Initializer> > initializers = Factory<Initializer>::makeAll();
904 foreach (const QSharedPointer<Initializer> &initializer, initializers) 910 foreach (const QSharedPointer<Initializer> &initializer, initializers)
@@ -1192,10 +1198,8 @@ private: @@ -1192,10 +1198,8 @@ private:
1192 templatesList[i] = Downsample(templatesList[i], transforms[i]); 1198 templatesList[i] = Downsample(templatesList[i], transforms[i]);
1193 1199
1194 QFutureSynchronizer<void> futures; 1200 QFutureSynchronizer<void> futures;
1195 - for (int i=0; i<templatesList.size(); i++) {  
1196 - if (Globals->parallelism) futures.addFuture(QtConcurrent::run(_train, transforms[i], &templatesList[i]));  
1197 - else _train (transforms[i], &templatesList[i]);  
1198 - } 1201 + for (int i=0; i<templatesList.size(); i++)
  1202 + futures.addFuture(QtConcurrent::run(_train, transforms[i], &templatesList[i]));
1199 futures.waitForFinished(); 1203 futures.waitForFinished();
1200 } 1204 }
1201 1205
@@ -1308,21 +1312,12 @@ void Transform::project(const TemplateList &amp;src, TemplateList &amp;dst) const @@ -1308,21 +1312,12 @@ void Transform::project(const TemplateList &amp;src, TemplateList &amp;dst) const
1308 { 1312 {
1309 dst.reserve(src.size()); 1313 dst.reserve(src.size());
1310 1314
1311 - // There are certain conditions where we should process the templates in serial,  
1312 - // but generally we'd prefer to process them in parallel.  
1313 - if ((src.size() < 2) || (Globals->parallelism == 0)) {  
1314 - foreach (const Template &t, src) {  
1315 - dst.append(Template());  
1316 - _project(this, &t, &dst.last());  
1317 - }  
1318 - } else {  
1319 - for (int i=0; i<src.size(); i++)  
1320 - dst.append(Template());  
1321 - QFutureSynchronizer<void> futures;  
1322 - for (int i=0; i<dst.size(); i++)  
1323 - futures.addFuture(QtConcurrent::run(_project, this, &src[i], &dst[i]));  
1324 - futures.waitForFinished();  
1325 - } 1315 + for (int i=0; i<src.size(); i++)
  1316 + dst.append(Template());
  1317 + QFutureSynchronizer<void> futures;
  1318 + for (int i=0; i<dst.size(); i++)
  1319 + futures.addFuture(QtConcurrent::run(_project, this, &src[i], &dst[i]));
  1320 + futures.waitForFinished();
1326 } 1321 }
1327 1322
1328 static void _backProject(const Transform *transform, const Template *dst, Template *src) 1323 static void _backProject(const Transform *transform, const Template *dst, Template *src)
@@ -1343,8 +1338,7 @@ void Transform::backProject(const TemplateList &amp;dst, TemplateList &amp;src) const @@ -1343,8 +1338,7 @@ void Transform::backProject(const TemplateList &amp;dst, TemplateList &amp;src) const
1343 1338
1344 QFutureSynchronizer<void> futures; 1339 QFutureSynchronizer<void> futures;
1345 for (int i=0; i<dst.size(); i++) 1340 for (int i=0; i<dst.size(); i++)
1346 - if (Globals->parallelism) futures.addFuture(QtConcurrent::run(_backProject, this, &dst[i], &src[i]));  
1347 - else _backProject (this, &dst[i], &src[i]); 1341 + futures.addFuture(QtConcurrent::run(_backProject, this, &dst[i], &src[i]));
1348 futures.waitForFinished(); 1342 futures.waitForFinished();
1349 } 1343 }
1350 1344
openbr/openbr_plugin.h
@@ -189,6 +189,7 @@ struct BR_EXPORT File @@ -189,6 +189,7 @@ struct BR_EXPORT File
189 inline QString baseName() const { const QString baseName = QFileInfo(name).baseName(); 189 inline QString baseName() const { const QString baseName = QFileInfo(name).baseName();
190 return baseName.isEmpty() ? QDir(name).dirName() : baseName; } /*!< \brief Returns the file's base name. */ 190 return baseName.isEmpty() ? QDir(name).dirName() : baseName; } /*!< \brief Returns the file's base name. */
191 inline QString suffix() const { return QFileInfo(name).suffix(); } /*!< \brief Returns the file's extension. */ 191 inline QString suffix() const { return QFileInfo(name).suffix(); } /*!< \brief Returns the file's extension. */
  192 + inline QString path() const { return QFileInfo(name).path(); } /*! \brief Returns the file's path excluding its name. */
192 QString resolved() const; /*!< \brief Returns name prepended with Globals->path if name does not exist. */ 193 QString resolved() const; /*!< \brief Returns name prepended with Globals->path if name does not exist. */
193 194
194 bool contains(const QString &key) const; /*!< \brief Returns \c true if the key has an associated value, \c false otherwise. */ 195 bool contains(const QString &key) const; /*!< \brief Returns \c true if the key has an associated value, \c false otherwise. */
@@ -547,7 +548,13 @@ public: @@ -547,7 +548,13 @@ public:
547 * \brief The number of threads to use. 548 * \brief The number of threads to use.
548 */ 549 */
549 Q_PROPERTY(int parallelism READ get_parallelism WRITE set_parallelism RESET reset_parallelism) 550 Q_PROPERTY(int parallelism READ get_parallelism WRITE set_parallelism RESET reset_parallelism)
550 - BR_PROPERTY(int, parallelism, std::max(1, QThread::idealThreadCount())) 551 + BR_PROPERTY(int, parallelism, std::max(1, QThread::idealThreadCount()+1))
  552 +
  553 + /*!
  554 + * \brief Whether or not to use GUI functions
  555 + */
  556 + Q_PROPERTY(bool useGui READ get_useGui WRITE set_useGui RESET reset_useGui)
  557 + BR_PROPERTY(bool, useGui, true)
551 558
552 /*! 559 /*!
553 * \brief The maximum number of templates to process in parallel. 560 * \brief The maximum number of templates to process in parallel.
@@ -701,7 +708,7 @@ public: @@ -701,7 +708,7 @@ public:
701 * \note <a href="http://qt-project.org/">Qt</a> users should instead call this <i>after</i> initializing QApplication. 708 * \note <a href="http://qt-project.org/">Qt</a> users should instead call this <i>after</i> initializing QApplication.
702 * \see finalize 709 * \see finalize
703 */ 710 */
704 - static void initialize(int &argc, char *argv[], QString sdkPath = ""); 711 + static void initialize(int &argc, char *argv[], QString sdkPath = "", bool use_gui = true);
705 712
706 /*! 713 /*!
707 * \brief Call \em once at the end of the application to deallocate global variables. 714 * \brief Call \em once at the end of the application to deallocate global variables.
openbr/plugins/algorithms.cpp
@@ -38,11 +38,11 @@ class AlgorithmsInitializer : public Initializer @@ -38,11 +38,11 @@ class AlgorithmsInitializer : public Initializer
38 Globals->abbreviations.insert("MedianFace", "Open!Cascade(FrontalFace)+ASEFEyes+Affine(256,256,0.37,0.45)+Center(Median)"); 38 Globals->abbreviations.insert("MedianFace", "Open!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)!ASEFEyes+Draw"); 40 Globals->abbreviations.insert("DrawFaceDetection", "Open+Cascade(FrontalFace)!ASEFEyes+Draw");
41 - Globals->abbreviations.insert("ShowFaceDetection", "DrawFaceDetection!Show"); 41 + Globals->abbreviations.insert("ShowFaceDetection", "DrawFaceDetection!Show[distribute=false]");
42 Globals->abbreviations.insert("OpenBR", "FaceRecognition"); 42 Globals->abbreviations.insert("OpenBR", "FaceRecognition");
43 Globals->abbreviations.insert("GenderEstimation", "GenderClassification"); 43 Globals->abbreviations.insert("GenderEstimation", "GenderClassification");
44 Globals->abbreviations.insert("AgeEstimation", "AgeRegression"); 44 Globals->abbreviations.insert("AgeEstimation", "AgeRegression");
45 - Globals->abbreviations.insert("FaceRecognition2", "{PP5Register+Affine(128,128,0.25,0.35)+Cvt(Gray)}+(Gradient+Bin(0,360,9,true))/(Blur(1)+Gamma(0.2)+DoG(1,2)+ContrastEq(0.1,10)+LBP(1,2,true)+Bin(0,10,10,true))+Merge+Integral+RecursiveIntegralSampler(4,2,8,Center(Hellinger)+LDA(.98)+Normalize(L1)+Cat+PCA(768)+Normalize(L1)+Quantize:UCharL1"); 45 + Globals->abbreviations.insert("FaceRecognition2", "{PP5Register+Affine(128,128,0.25,0.35)+Cvt(Gray)}+(Gradient+Bin(0,360,9,true))/(Blur(1)+Gamma(0.2)+DoG(1,2)+ContrastEq(0.1,10)+LBP(1,2,true)+Bin(0,10,10,true))+Merge+Integral+RecursiveIntegralSampler(4,2,8,LDA(.98)+Normalize(L1))+Cat+PCA(768)+Normalize(L1)+Quantize:UCharL1");
46 46
47 // Generic Image Processing 47 // Generic Image Processing
48 Globals->abbreviations.insert("SIFT", "Open+KeyPointDetector(SIFT)+KeyPointDescriptor(SIFT):KeyPointMatcher(BruteForce)"); 48 Globals->abbreviations.insert("SIFT", "Open+KeyPointDetector(SIFT)+KeyPointDescriptor(SIFT):KeyPointMatcher(BruteForce)");
openbr/plugins/distance.cpp
@@ -158,8 +158,7 @@ class PipeDistance : public Distance @@ -158,8 +158,7 @@ class PipeDistance : public Distance
158 { 158 {
159 QFutureSynchronizer<void> futures; 159 QFutureSynchronizer<void> futures;
160 foreach (br::Distance *distance, distances) 160 foreach (br::Distance *distance, distances)
161 - if (Globals->parallelism) futures.addFuture(QtConcurrent::run(distance, &Distance::train, data));  
162 - else distance->train(data); 161 + futures.addFuture(QtConcurrent::run(distance, &Distance::train, data));
163 futures.waitForFinished(); 162 futures.waitForFinished();
164 } 163 }
165 164
openbr/plugins/draw.cpp
@@ -98,6 +98,8 @@ class DrawGridTransform : public UntrainableTransform @@ -98,6 +98,8 @@ class DrawGridTransform : public UntrainableTransform
98 98
99 BR_REGISTER(Transform, DrawGridTransform) 99 BR_REGISTER(Transform, DrawGridTransform)
100 100
  101 +// TODO: re-implement EditTransform using Qt
  102 +#if 0
101 /*! 103 /*!
102 * \ingroup transforms 104 * \ingroup transforms
103 * \brief Remove landmarks. 105 * \brief Remove landmarks.
@@ -162,6 +164,7 @@ Template EditTransform::currentTemplate; @@ -162,6 +164,7 @@ Template EditTransform::currentTemplate;
162 QMutex EditTransform::currentTemplateLock; 164 QMutex EditTransform::currentTemplateLock;
163 165
164 BR_REGISTER(Transform, EditTransform) 166 BR_REGISTER(Transform, EditTransform)
  167 +#endif
165 168
166 } // namespace br 169 } // namespace br
167 170
openbr/plugins/format.cpp
@@ -15,6 +15,7 @@ @@ -15,6 +15,7 @@
15 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 15 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
16 16
17 #include <QDate> 17 #include <QDate>
  18 +#include <QSize>
18 #ifndef BR_EMBEDDED 19 #ifndef BR_EMBEDDED
19 #include <QtXml> 20 #include <QtXml>
20 #endif // BR_EMBEDDED 21 #endif // BR_EMBEDDED
@@ -547,14 +548,43 @@ BR_REGISTER(Format, nullFormat) @@ -547,14 +548,43 @@ BR_REGISTER(Format, nullFormat)
547 class rawFormat : public Format 548 class rawFormat : public Format
548 { 549 {
549 Q_OBJECT 550 Q_OBJECT
  551 + static QHash<QString, QHash<QString,QSize> > imageSizes; // QHash<Path, QHash<File,Size> >
550 552
551 Template read() const 553 Template read() const
552 { 554 {
  555 + QString path = file.path();
  556 + if (!imageSizes.contains(path)) {
  557 + static QMutex mutex;
  558 + QMutexLocker locker(&mutex);
  559 +
  560 + if (!imageSizes.contains(path)) {
  561 + const QString imageSize = path+"/ImageSize.txt";
  562 + QStringList lines;
  563 + if (QFileInfo(imageSize).exists()) {
  564 + lines = QtUtils::readLines(imageSize);
  565 + lines.removeFirst(); // Remove header
  566 + }
  567 +
  568 + QHash<QString,QSize> sizes;
  569 + QRegExp whiteSpace("\\s+");
  570 + foreach (const QString &line, lines) {
  571 + QStringList words = line.split(whiteSpace);
  572 + if (words.size() != 3) continue;
  573 + sizes.insert(words[0], QSize(words[2].toInt(), words[1].toInt()));
  574 + }
  575 +
  576 + imageSizes.insert(path, sizes);
  577 + }
  578 + }
  579 +
553 QByteArray data; 580 QByteArray data;
554 QtUtils::readFile(file, data); 581 QtUtils::readFile(file, data);
555 - if (data.size() != 768*800)  
556 - qFatal("Expected 768*800 bytes.");  
557 - return Template(file, Mat(768, 800, CV_8UC1, data.data()).clone()); 582 +
  583 + QSize size = imageSizes[path][file.baseName()];
  584 + if (!size.isValid()) size = QSize(800,768);
  585 + if (data.size() != size.width() * size.height())
  586 + qFatal("Expected %d*%d bytes, got %d.", size.height(), size.width(), data.size());
  587 + return Template(file, Mat(size.height(), size.width(), CV_8UC1, data.data()).clone());
558 } 588 }
559 589
560 void write(const Template &t) const 590 void write(const Template &t) const
@@ -563,6 +593,8 @@ class rawFormat : public Format @@ -563,6 +593,8 @@ class rawFormat : public Format
563 } 593 }
564 }; 594 };
565 595
  596 +QHash<QString, QHash<QString,QSize> > rawFormat::imageSizes;
  597 +
566 BR_REGISTER(Format, rawFormat) 598 BR_REGISTER(Format, rawFormat)
567 599
568 /*! 600 /*!
openbr/plugins/gallery.cpp
@@ -107,8 +107,7 @@ class EmptyGallery : public Gallery @@ -107,8 +107,7 @@ class EmptyGallery : public Gallery
107 QList< QFuture<TemplateList> > futures; 107 QList< QFuture<TemplateList> > futures;
108 foreach (const QString &folder, NaturalStringSort(dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot))) { 108 foreach (const QString &folder, NaturalStringSort(dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot))) {
109 const QDir subdir = dir.absoluteFilePath(folder); 109 const QDir subdir = dir.absoluteFilePath(folder);
110 - if (Globals->parallelism) futures.append(QtConcurrent::run(&EmptyGallery::getTemplates, subdir));  
111 - else templates.append(getTemplates(subdir)); 110 + futures.append(QtConcurrent::run(&EmptyGallery::getTemplates, subdir));
112 } 111 }
113 foreach (const QFuture<TemplateList> &future, futures) 112 foreach (const QFuture<TemplateList> &future, futures)
114 templates.append(future.result()); 113 templates.append(future.result());
openbr/plugins/gui.cpp
@@ -94,6 +94,8 @@ public slots: @@ -94,6 +94,8 @@ public slots:
94 void createWindow() 94 void createWindow()
95 { 95 {
96 delete window; 96 delete window;
  97 + QApplication::instance()->removeEventFilter(this);
  98 +
97 window = new QLabel(); 99 window = new QLabel();
98 window->setVisible(true); 100 window->setVisible(true);
99 101
@@ -109,21 +111,25 @@ public slots: @@ -109,21 +111,25 @@ public slots:
109 * \ingroup transforms 111 * \ingroup transforms
110 * \brief Displays templates in a GUI pop-up window using QT. 112 * \brief Displays templates in a GUI pop-up window using QT.
111 * \author Charles Otto \cite caotto 113 * \author Charles Otto \cite caotto
112 - * Unlike ShowTransform, this can be used with parallelism enabled, although it  
113 - * is considered TimeVarying. 114 + * Can be used with parallelism enabled, although it is considered TimeVarying.
114 */ 115 */
115 -class Show2Transform : public TimeVaryingTransform 116 +class ShowTransform : public TimeVaryingTransform
116 { 117 {
117 Q_OBJECT 118 Q_OBJECT
118 public: 119 public:
119 Q_PROPERTY(bool waitInput READ get_waitInput WRITE set_waitInput RESET reset_waitInput STORED false) 120 Q_PROPERTY(bool waitInput READ get_waitInput WRITE set_waitInput RESET reset_waitInput STORED false)
120 - BR_PROPERTY(bool, waitInput, false) 121 + BR_PROPERTY(bool, waitInput, true)
121 122
122 Q_PROPERTY(QStringList keys READ get_keys WRITE set_keys RESET reset_keys STORED false) 123 Q_PROPERTY(QStringList keys READ get_keys WRITE set_keys RESET reset_keys STORED false)
123 BR_PROPERTY(QStringList, keys, QStringList("FrameNumber")) 124 BR_PROPERTY(QStringList, keys, QStringList("FrameNumber"))
124 125
125 - Show2Transform() : TimeVaryingTransform(false, false) 126 + ShowTransform() : TimeVaryingTransform(false, false)
126 { 127 {
  128 + gui = NULL;
  129 + displayBuffer = NULL;
  130 + if (!Globals->useGui)
  131 + return;
  132 + displayBuffer = new QPixmap();
127 // Create our GUI proxy 133 // Create our GUI proxy
128 gui = new GUIProxy(); 134 gui = new GUIProxy();
129 // Move it to the main thread, this means signals we send to it will 135 // Move it to the main thread, this means signals we send to it will
@@ -134,16 +140,17 @@ public: @@ -134,16 +140,17 @@ public:
134 connect(this, SIGNAL(updateImage(QPixmap)), gui,SLOT(showImage(QPixmap))); 140 connect(this, SIGNAL(updateImage(QPixmap)), gui,SLOT(showImage(QPixmap)));
135 } 141 }
136 142
137 - ~Show2Transform() 143 + ~ShowTransform()
138 { 144 {
139 delete gui; 145 delete gui;
  146 + delete displayBuffer;
140 } 147 }
141 148
142 void train(const TemplateList &data) { (void) data; } 149 void train(const TemplateList &data) { (void) data; }
143 150
144 void project(const TemplateList &src, TemplateList &dst) const 151 void project(const TemplateList &src, TemplateList &dst) const
145 { 152 {
146 - Transform * non_const = (Show2Transform *) this; 153 + Transform * non_const = (ShowTransform *) this;
147 non_const->projectUpdate(src,dst); 154 non_const->projectUpdate(src,dst);
148 } 155 }
149 156
@@ -151,7 +158,7 @@ public: @@ -151,7 +158,7 @@ public:
151 { 158 {
152 dst = src; 159 dst = src;
153 160
154 - if (src.empty()) 161 + if (src.empty() || !Globals->useGui)
155 return; 162 return;
156 163
157 foreach (const Template & t, src) { 164 foreach (const Template & t, src) {
@@ -168,12 +175,12 @@ public: @@ -168,12 +175,12 @@ public:
168 175
169 foreach(const cv::Mat & m, t) { 176 foreach(const cv::Mat & m, t) {
170 qImageBuffer = toQImage(m); 177 qImageBuffer = toQImage(m);
171 - displayBuffer.convertFromImage(qImageBuffer); 178 + displayBuffer->convertFromImage(qImageBuffer);
172 179
173 // Emit an explicit copy of our pixmap so that the pixmap used 180 // Emit an explicit copy of our pixmap so that the pixmap used
174 // by the main thread isn't damaged when we update displayBuffer 181 // by the main thread isn't damaged when we update displayBuffer
175 // later. 182 // later.
176 - emit updateImage(displayBuffer.copy(displayBuffer.rect())); 183 + emit updateImage(displayBuffer->copy(displayBuffer->rect()));
177 184
178 // Blocking wait for a key-press 185 // Blocking wait for a key-press
179 if (this->waitInput) 186 if (this->waitInput)
@@ -191,6 +198,9 @@ public: @@ -191,6 +198,9 @@ public:
191 198
192 void init() 199 void init()
193 { 200 {
  201 + if (!Globals->useGui)
  202 + return;
  203 +
194 emit needWindow(); 204 emit needWindow();
195 connect(this, SIGNAL(changeTitle(QString)), gui->window, SLOT(setWindowTitle(QString))); 205 connect(this, SIGNAL(changeTitle(QString)), gui->window, SLOT(setWindowTitle(QString)));
196 connect(this, SIGNAL(hideWindow()), gui->window, SLOT(hide())); 206 connect(this, SIGNAL(hideWindow()), gui->window, SLOT(hide()));
@@ -199,7 +209,7 @@ public: @@ -199,7 +209,7 @@ public:
199 protected: 209 protected:
200 GUIProxy * gui; 210 GUIProxy * gui;
201 QImage qImageBuffer; 211 QImage qImageBuffer;
202 - QPixmap displayBuffer; 212 + QPixmap * displayBuffer;
203 213
204 signals: 214 signals:
205 void needWindow(); 215 void needWindow();
@@ -208,7 +218,7 @@ signals: @@ -208,7 +218,7 @@ signals:
208 void hideWindow(); 218 void hideWindow();
209 }; 219 };
210 220
211 -BR_REGISTER(Transform, Show2Transform) 221 +BR_REGISTER(Transform, ShowTransform)
212 222
213 class FPSSynch : public TimeVaryingTransform 223 class FPSSynch : public TimeVaryingTransform
214 { 224 {
openbr/plugins/meta.cpp
@@ -109,8 +109,7 @@ class PipeTransform : public CompositeTransform @@ -109,8 +109,7 @@ class PipeTransform : public CompositeTransform
109 fprintf(stderr, " projecting..."); 109 fprintf(stderr, " projecting...");
110 QFutureSynchronizer<void> futures; 110 QFutureSynchronizer<void> futures;
111 for (int j=0; j<copy.size(); j++) 111 for (int j=0; j<copy.size(); j++)
112 - if (Globals->parallelism) futures.addFuture(QtConcurrent::run(this, &PipeTransform::_projectPartial, &copy[j], i, nextTrainableTransform));  
113 - else _projectPartial( &copy[j], i, nextTrainableTransform); 112 + futures.addFuture(QtConcurrent::run(this, &PipeTransform::_projectPartial, &copy[j], i, nextTrainableTransform));
114 futures.waitForFinished(); 113 futures.waitForFinished();
115 i = nextTrainableTransform; 114 i = nextTrainableTransform;
116 } 115 }
@@ -288,10 +287,8 @@ class ForkTransform : public CompositeTransform @@ -288,10 +287,8 @@ class ForkTransform : public CompositeTransform
288 { 287 {
289 if (!trainable) return; 288 if (!trainable) return;
290 QFutureSynchronizer<void> futures; 289 QFutureSynchronizer<void> futures;
291 - for (int i=0; i<transforms.size(); i++) {  
292 - if (Globals->parallelism) futures.addFuture(QtConcurrent::run(_train, transforms[i], &data));  
293 - else _train (transforms[i], &data);  
294 - } 290 + for (int i=0; i<transforms.size(); i++)
  291 + futures.addFuture(QtConcurrent::run(_train, transforms[i], &data));
295 futures.waitForFinished(); 292 futures.waitForFinished();
296 } 293 }
297 294
openbr/plugins/misc.cpp
@@ -51,46 +51,6 @@ BR_REGISTER(Transform, OpenTransform) @@ -51,46 +51,6 @@ BR_REGISTER(Transform, OpenTransform)
51 51
52 /*! 52 /*!
53 * \ingroup transforms 53 * \ingroup transforms
54 - * \brief Displays templates in a GUI pop-up window.  
55 - * \author Josh Klontz \cite jklontz  
56 - */  
57 -class ShowTransform : public UntrainableMetaTransform  
58 -{  
59 - Q_OBJECT  
60 - Q_PROPERTY(bool waitKey READ get_waitKey WRITE set_waitKey RESET reset_waitKey STORED false)  
61 - BR_PROPERTY(bool, waitKey, true)  
62 -  
63 - static int counter;  
64 - int uid;  
65 -  
66 - void init()  
67 - {  
68 - uid = counter++;  
69 - Globals->setProperty("parallelism", "0"); // Can only work in single threaded mode  
70 - }  
71 -  
72 - void project(const Template &src, Template &dst) const  
73 - {  
74 - dst = src;  
75 -  
76 - if (Globals->parallelism) {  
77 - qWarning("Show::project() only works in single threaded mode.");  
78 - return;  
79 - }  
80 -  
81 - for (int i=0; i<src.size(); i++)  
82 - OpenCVUtils::showImage(src[i], "Show" + (counter*src.size() > 1 ? "-" + QString::number(uid*src.size()+i) : QString()), false);  
83 -  
84 - if (waitKey && !src.isEmpty()) cv::waitKey(-1);  
85 - }  
86 -};  
87 -  
88 -int ShowTransform::counter = 0;  
89 -  
90 -BR_REGISTER(Transform, ShowTransform)  
91 -  
92 -/*!  
93 - * \ingroup transforms  
94 * \brief Prints the template's file to stdout or stderr. 54 * \brief Prints the template's file to stdout or stderr.
95 * \author Josh Klontz \cite jklontz 55 * \author Josh Klontz \cite jklontz
96 */ 56 */
@@ -368,6 +328,8 @@ class AnonymizeTransform : public UntrainableMetaTransform @@ -368,6 +328,8 @@ class AnonymizeTransform : public UntrainableMetaTransform
368 328
369 BR_REGISTER(Transform, AnonymizeTransform) 329 BR_REGISTER(Transform, AnonymizeTransform)
370 330
  331 +// TODO: Use a global Mutex to prevent concurrent reads from stdin
  332 +#if 0
371 /*! 333 /*!
372 * \ingroup transforms 334 * \ingroup transforms
373 * \brief Name a point 335 * \brief Name a point
@@ -415,6 +377,7 @@ class ElicitMetadataTransform : public UntrainableMetaTransform @@ -415,6 +377,7 @@ class ElicitMetadataTransform : public UntrainableMetaTransform
415 }; 377 };
416 378
417 BR_REGISTER(Transform, ElicitMetadataTransform) 379 BR_REGISTER(Transform, ElicitMetadataTransform)
  380 +#endif
418 381
419 /*! 382 /*!
420 * \ingroup transforms 383 * \ingroup transforms
openbr/plugins/neclatent1.cpp
@@ -18,9 +18,12 @@ class NECLatent1Initialier : public Initializer @@ -18,9 +18,12 @@ class NECLatent1Initialier : public Initializer
18 18
19 void initialize() const 19 void initialize() const
20 { 20 {
21 - Globals->abbreviations.insert("NECTenprint1", "Open+Cvt(Gray)+NECLatent1Enroll:NECLatent1Compare");  
22 - Globals->abbreviations.insert("NECLatent1", "Open+Cvt(Gray)+NECLatent1Enroll(true):NECLatent1Compare");  
23 - Globals->abbreviations.insert("NECLatentLFFS1", "Open+NECLatent1Enroll(true,ELFT_M):NECLatent1Compare(ELFT_M)"); 21 + Globals->abbreviations.insert("NECTenprintLFML", "Open+Cvt(Gray)+NECLatent1Enroll(false,LFML):NECLatent1Compare(LFML)");
  22 + Globals->abbreviations.insert("NECTenprintELFT", "Open+Cvt(Gray)+NECLatent1Enroll(false,ELFT):NECLatent1Compare(ELFT)");
  23 + Globals->abbreviations.insert("NECTenprintELFTM", "Open+Cvt(Gray)+NECLatent1Enroll(false,ELFT_M):NECLatent1Compare(ELFT_M)");
  24 + Globals->abbreviations.insert("NECLatentLFML", "Open+Cvt(Gray)+NECLatent1Enroll(true,LFML):NECLatent1Compare(LFML)");
  25 + Globals->abbreviations.insert("NECLatentELFT", "Open+Cvt(Gray)+NECLatent1Enroll(true,ELFT):NECLatent1Compare(ELFT)");
  26 + Globals->abbreviations.insert("NECLatentELFTM", "Open+NECLatent1Enroll(true,ELFT_M):NECLatent1Compare(ELFT_M)");
24 } 27 }
25 }; 28 };
26 29
@@ -50,23 +53,25 @@ private: @@ -50,23 +53,25 @@ private:
50 53
51 void project(const Template &src, Template &dst) const 54 void project(const Template &src, Template &dst) const
52 { 55 {
  56 + static QMutex mutex;
  57 + QMutexLocker locker(&mutex); // It seems that most of the API is not reentrant
  58 +
53 if (src.m().type() != CV_8UC1) qFatal("Requires 8UC1 data!"); 59 if (src.m().type() != CV_8UC1) qFatal("Requires 8UC1 data!");
54 uchar *data = src.m().data; 60 uchar *data = src.m().data;
55 const int rows = src.m().rows; 61 const int rows = src.m().rows;
56 const int columns = src.m().cols; 62 const int columns = src.m().cols;
57 uchar buff[MAX_TEMPLATE_SIZE]; 63 uchar buff[MAX_TEMPLATE_SIZE];
58 uchar* pBuff = NULL; 64 uchar* pBuff = NULL;
59 - int size = 0;  
60 - int error;  
61 65
  66 + int size, error;
62 if (latent) { 67 if (latent) {
63 if (algorithm == LFML) error = NEC_LFML_ExtractLatent(data, rows, columns, 500, buff, &size); 68 if (algorithm == LFML) error = NEC_LFML_ExtractLatent(data, rows, columns, 500, buff, &size);
64 - else if (algorithm == ELFT) error = NEC_ELFT_ExtractLatent(data, rows, columns, 500, 4, buff, &size);  
65 - else error = NEC_ELFT_M_ExtractLatent(data, columns, 1, &pBuff, &size); 69 + else if (algorithm == ELFT) error = NEC_ELFT_ExtractLatent(data, rows, columns, 500, 32, buff, &size);
  70 + else error = NEC_ELFT_M_ExtractLatent(data, columns, 5, &pBuff, &size);
66 } else { 71 } else {
67 if (algorithm == LFML) error = NEC_LFML_ExtractTenprint(data, rows, columns, 500, buff, &size); 72 if (algorithm == LFML) error = NEC_LFML_ExtractTenprint(data, rows, columns, 500, buff, &size);
68 - else if (algorithm == ELFT) error = NEC_ELFT_ExtractTenprint(data, rows, columns, 500, 2, buff, &size);  
69 - else qFatal("ELFT_M Tenprint not implemented."); 73 + else if (algorithm == ELFT) error = NEC_ELFT_ExtractTenprint(data, rows, columns, 500, 8, buff, &size);
  74 + else error = NEC_ELFT_M_ExtractTenprint(data, rows, columns, 500, 5, &pBuff, &size);
70 } 75 }
71 76
72 if (!error) { 77 if (!error) {
@@ -109,10 +114,12 @@ private: @@ -109,10 +114,12 @@ private:
109 uchar *aData = a.m().data; 114 uchar *aData = a.m().data;
110 uchar *bData = b.m().data; 115 uchar *bData = b.m().data;
111 if (!a.m().data || !b.m().data) return -std::numeric_limits<float>::max(); 116 if (!a.m().data || !b.m().data) return -std::numeric_limits<float>::max();
112 - int score;  
113 - if (algorithm == LFML) NEC_LFML_Verify(bData, b.m().total(), aData, a.m().total(), &score);  
114 - else if (algorithm == ELFT) NEC_ELFT_Verify(bData, aData, &score, 1);  
115 - else NEC_ELFT_M_Verify(bData, aData, &score, 1); 117 + int score, error;
  118 + if (algorithm == LFML) error = NEC_LFML_Verify(bData, b.m().total(), aData, a.m().total(), &score);
  119 + else if (algorithm == ELFT) error = NEC_ELFT_Verify(bData, aData, &score, 1);
  120 + else error = NEC_ELFT_M_Verify(bData, aData, &score, 1);
  121 + if (error)
  122 + qWarning("NECLatent1CompareDistance error %d", error);
116 return score; 123 return score;
117 } 124 }
118 }; 125 };
openbr/plugins/normalize.cpp
@@ -137,11 +137,9 @@ private: @@ -137,11 +137,9 @@ private:
137 } 137 }
138 138
139 QFutureSynchronizer<void> futures; 139 QFutureSynchronizer<void> futures;
140 - const bool parallel = (data.size() > 1000) && Globals->parallelism;  
141 for (size_t c = 0; c < mv.size(); c++) { 140 for (size_t c = 0; c < mv.size(); c++) {
142 for (int i=0; i<dims; i++) 141 for (int i=0; i<dims; i++)
143 - if (parallel) futures.addFuture(QtConcurrent::run(_train, method, mv[c].col(i), labels, &av[c].at<double>(0, i), &bv[c].at<double>(0, i)));  
144 - else _train (method, mv[c].col(i), labels, &av[c].at<double>(0, i), &bv[c].at<double>(0, i)); 142 + futures.addFuture(QtConcurrent::run(_train, method, mv[c].col(i), labels, &av[c].at<double>(0, i), &bv[c].at<double>(0, i)));
145 av[c] = av[c].reshape(1, data.first().m().rows); 143 av[c] = av[c].reshape(1, data.first().m().rows);
146 bv[c] = bv[c].reshape(1, data.first().m().rows); 144 bv[c] = bv[c].reshape(1, data.first().m().rows);
147 } 145 }
openbr/plugins/openbr_internal.h
@@ -221,7 +221,7 @@ public: @@ -221,7 +221,7 @@ public:
221 Transform * maybe_copy = t->smartCopy(); 221 Transform * maybe_copy = t->smartCopy();
222 if (maybe_copy->parent() == NULL) 222 if (maybe_copy->parent() == NULL)
223 maybe_copy->setParent(output); 223 maybe_copy->setParent(output);
224 - output->transforms.append(t->smartCopy()); 224 + output->transforms.append(maybe_copy);
225 } 225 }
226 226
227 output->file = this->file; 227 output->file = this->file;
openbr/plugins/quantize.cpp
@@ -82,8 +82,7 @@ class HistEqQuantizationTransform : public Transform @@ -82,8 +82,7 @@ class HistEqQuantizationTransform : public Transform
82 82
83 QFutureSynchronizer<void> futures; 83 QFutureSynchronizer<void> futures;
84 for (int i=0; i<data.cols; i++) 84 for (int i=0; i<data.cols; i++)
85 - if (Globals->parallelism) futures.addFuture(QtConcurrent::run(&HistEqQuantizationTransform::computeThresholds, data.col(i), &thresholds.data()[i*256]));  
86 - else computeThresholds( data.col(i), &thresholds.data()[i*256]); 85 + futures.addFuture(QtConcurrent::run(&HistEqQuantizationTransform::computeThresholds, data.col(i), &thresholds.data()[i*256]));
87 futures.waitForFinished(); 86 futures.waitForFinished();
88 } 87 }
89 88
@@ -156,8 +155,7 @@ class BayesianQuantizationDistance : public Distance @@ -156,8 +155,7 @@ class BayesianQuantizationDistance : public Distance
156 155
157 QFutureSynchronizer<void> futures; 156 QFutureSynchronizer<void> futures;
158 for (int i=0; i<data.cols; i++) 157 for (int i=0; i<data.cols; i++)
159 - if (Globals->parallelism) futures.addFuture(QtConcurrent::run(&BayesianQuantizationDistance::computeLogLikelihood, data.col(i), templateLabels, &loglikelihoods.data()[i*256]));  
160 - else computeLogLikelihood( data.col(i), templateLabels, &loglikelihoods.data()[i*256]); 158 + futures.addFuture(QtConcurrent::run(&BayesianQuantizationDistance::computeLogLikelihood, data.col(i), templateLabels, &loglikelihoods.data()[i*256]));
161 futures.waitForFinished(); 159 futures.waitForFinished();
162 } 160 }
163 161
openbr/plugins/quantize2.cpp
@@ -83,8 +83,7 @@ class BayesianQuantizationTransform : public Transform @@ -83,8 +83,7 @@ class BayesianQuantizationTransform : public Transform
83 83
84 QFutureSynchronizer<void> futures; 84 QFutureSynchronizer<void> futures;
85 for (int i=0; i<data.cols; i++) 85 for (int i=0; i<data.cols; i++)
86 - if (Globals->parallelism) futures.addFuture(QtConcurrent::run(&BayesianQuantizationTransform::computeThresholds, data.col(i), labels, &thresholds.data()[i*256]));  
87 - else computeThresholds( data.col(i), labels, &thresholds.data()[i*256]); 86 + futures.addFuture(QtConcurrent::run(&BayesianQuantizationTransform::computeThresholds, data.col(i), labels, &thresholds.data()[i*256]));
88 futures.waitForFinished(); 87 futures.waitForFinished();
89 } 88 }
90 89
openbr/plugins/stasm.cpp
@@ -33,7 +33,8 @@ BR_REGISTER(Initializer, StasmInitializer) @@ -33,7 +33,8 @@ BR_REGISTER(Initializer, StasmInitializer)
33 * \brief Wraps STASM key point detector 33 * \brief Wraps STASM key point detector
34 * \author Scott Klum \cite sklum 34 * \author Scott Klum \cite sklum
35 */ 35 */
36 - 36 +// TODO: Use a global mutex to prevent concurrent calls to AsmSearchDll
  37 +#if 0
37 class StasmTransform : public UntrainableTransform 38 class StasmTransform : public UntrainableTransform
38 { 39 {
39 Q_OBJECT 40 Q_OBJECT
@@ -67,6 +68,7 @@ class StasmTransform : public UntrainableTransform @@ -67,6 +68,7 @@ class StasmTransform : public UntrainableTransform
67 }; 68 };
68 69
69 BR_REGISTER(Transform, StasmTransform) 70 BR_REGISTER(Transform, StasmTransform)
  71 +#endif
70 72
71 } // namespace br 73 } // namespace br
72 74
openbr/plugins/stream.cpp
@@ -771,11 +771,6 @@ public: @@ -771,11 +771,6 @@ public:
771 (void) src; (void) dst; 771 (void) src; (void) dst;
772 qFatal("nope"); 772 qFatal("nope");
773 } 773 }
774 - void project(const TemplateList & src, TemplateList & dst) const  
775 - {  
776 - (void) src; (void) dst;  
777 - qFatal("nope");  
778 - }  
779 774
780 void projectUpdate(const Template &src, Template &dst) 775 void projectUpdate(const Template &src, Template &dst)
781 { 776 {
openbr/plugins/validate.cpp
@@ -46,8 +46,7 @@ class CrossValidateTransform : public MetaTransform @@ -46,8 +46,7 @@ class CrossValidateTransform : public MetaTransform
46 if (partitions[j] == i) 46 if (partitions[j] == i)
47 partitionedData.removeAt(j); 47 partitionedData.removeAt(j);
48 // Train on the remaining templates 48 // Train on the remaining templates
49 - if (Globals->parallelism) futures.addFuture(QtConcurrent::run(transforms[i], &Transform::train, partitionedData));  
50 - else transforms[i]->train(partitionedData); 49 + futures.addFuture(QtConcurrent::run(transforms[i], &Transform::train, partitionedData));
51 } 50 }
52 futures.waitForFinished(); 51 futures.waitForFinished();
53 } 52 }