Commit 559f1f80fc37a77f9470d2ac4887d3c889d69fa7

Authored by Scott Klum
2 parents dbc62a93 c00e8226

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

openbr/core/common.cpp
... ... @@ -63,3 +63,16 @@ QList<int> Common::RandSample(int n, const QSet<int> &values, bool unique)
63 63 }
64 64 return samples;
65 65 }
  66 +
  67 +QList<float> linspace(float start, float stop, int n) {
  68 + float delta = (stop - start) / (n - 1);
  69 + float curValue = start;
  70 + QList<float> spaced;
  71 + spaced.reserve(n);
  72 + spaced.append(start);
  73 + for (int i = 1; i < (n - 1); i++) {
  74 + spaced.append(curValue += delta);
  75 + }
  76 + spaced.append(stop);
  77 + return spaced;
  78 +}
... ...
openbr/core/common.h
... ... @@ -253,6 +253,11 @@ QList&lt;int&gt; RandSample(int n, const QList&lt;T&gt; &amp;weights, bool unique = false)
253 253 }
254 254  
255 255 /*!
  256 + * \brief See Matlab function linspace() for documentation.
  257 + */
  258 +QList<float> linspace(float start, float stop, int n);
  259 +
  260 +/*!
256 261 * \brief See Matlab function unique() for documentation.
257 262 */
258 263 template <typename T>
... ...
openbr/openbr_plugin.cpp
... ... @@ -44,12 +44,6 @@ using namespace cv;
44 44  
45 45 Q_DECLARE_METATYPE(QLocalSocket::LocalSocketState)
46 46  
47   -// Some globals used to transfer data to Context::messageHandler so that
48   -// we can restart the process if we try and fail to create a QApplication.
49   -static bool creating_qapp = false;
50   -static int * argc_ptr = NULL;
51   -static char ** argv_ptr = NULL;
52   -
53 47 /* File - public methods */
54 48 // Note that the convention for displaying metadata is as follows:
55 49 // [] for lists in which argument order does not matter (e.g. [FTO=false, Index=0]),
... ... @@ -848,13 +842,7 @@ int br::Context::blocks(int size) const
848 842  
849 843 bool br::Context::contains(const QString &name)
850 844 {
851   - QByteArray bytes = name.toLocal8Bit();
852   - const char * c_name = bytes.constData();
853   -
854   - for (int i=0; i<metaObject()->propertyCount(); i++)
855   - if (!strcmp(c_name, metaObject()->property(i).name()))
856   - return true;
857   - return false;
  845 + return property(qPrintable(name)).isValid();
858 846 }
859 847  
860 848 void br::Context::printStatus()
... ... @@ -907,42 +895,26 @@ bool br::Context::checkSDKPath(const QString &amp;sdkPath)
907 895 // We create our own when the user hasn't
908 896 static QCoreApplication *application = NULL;
909 897  
910   -void br::Context::initialize(int &argc, char *argv[], QString sdkPath, bool use_gui)
  898 +void br::Context::initialize(int &argc, char *argv[], QString sdkPath, bool useGui)
911 899 {
912   - for (int i=0; i < argc; i ++)
913   - {
914   - if (strcmp("-useGui", argv[i]) == 0) {
915   - const char * val = i+1 < argc ? argv[i+1] : "";
916   - if (strcmp(val, "false") ==0 || strcmp(val, "0") == 0)
917   - use_gui = false;
918   - break;
919   - }
920   - }
921   -
922 900 qInstallMessageHandler(messageHandler);
923 901  
  902 +#ifndef _WIN32
  903 + useGui = useGui && (getenv("DISPLAY") != NULL);
  904 +#endif // not _WIN32
  905 +
924 906 // We take in argc as a reference due to:
925 907 // https://bugreports.qt-project.org/browse/QTBUG-5637
926 908 // QApplication should be initialized before anything else.
927 909 // Since we can't ensure that it gets deleted last, we never delete it.
928 910 if (QCoreApplication::instance() == NULL) {
929 911 #ifndef BR_EMBEDDED
930   - if (use_gui) {
931   - // Set up variables to be used in the message handler if this fails.
932   - // Just so you know, we
933   - creating_qapp = true;
934   - argc_ptr = &argc;
935   - argv_ptr = argv;
936   -
937   - application = new QApplication(argc, argv);
938   - creating_qapp = false;
939   - }
940   - else {
941   - application = new QCoreApplication(argc, argv);
942   - }
943   -#else
  912 + if (useGui) application = new QApplication(argc, argv);
  913 + else application = new QCoreApplication(argc, argv);
  914 +#else // not BR_EMBEDDED
  915 + useGui = false;
944 916 application = new QCoreApplication(argc, argv);
945   -#endif
  917 +#endif // BR_EMBEDDED
946 918 }
947 919  
948 920 QCoreApplication::setOrganizationName(COMPANY_NAME);
... ... @@ -965,8 +937,7 @@ void br::Context::initialize(int &amp;argc, char *argv[], QString sdkPath, bool use_
965 937  
966 938 Globals = new Context();
967 939 Globals->init(File());
968   - Globals->useGui = use_gui;
969   -
  940 + Globals->useGui = useGui;
970 941  
971 942 Common::seedRNG();
972 943  
... ... @@ -1035,26 +1006,6 @@ void br::Context::messageHandler(QtMsgType type, const QMessageLogContext &amp;conte
1035 1006 static QMutex generalLock;
1036 1007 QMutexLocker locker(&generalLock);
1037 1008  
1038   - // If we are trying to create a QApplication, and get a fatal, then restart the process
1039   - // with useGui set to 0.
1040   - if (creating_qapp && type == QtFatalMsg)
1041   - {
1042   - // re-launch process with useGui = 0
1043   - std::cout << "Failed to initialize gui, restarting with -useGui 0" << std::endl;
1044   - QStringList arguments;
1045   - arguments.append("-useGui");
1046   - arguments.append("0");
1047   - for (int i=1; i < *argc_ptr; i++)
1048   - {
1049   - arguments.append(argv_ptr[i]);
1050   - }
1051   - // QProcess::execute blocks until the other process completes.
1052   - QProcess::execute(argv_ptr[0], arguments);
1053   - // have to unlock this for some reason
1054   - locker.unlock();
1055   - std::exit(0);
1056   - }
1057   -
1058 1009 QString txt;
1059 1010 if (type == QtDebugMsg) {
1060 1011 if (Globals->quiet) return;
... ... @@ -1076,8 +1027,13 @@ void br::Context::messageHandler(QtMsgType type, const QMessageLogContext &amp;conte
1076 1027 Globals->logFile.flush();
1077 1028 }
1078 1029  
1079   - if (type == QtFatalMsg)
  1030 + if (type == QtFatalMsg) {
  1031 +#ifdef _WIN32
  1032 + QCoreApplication::quit(); // abort() hangs the console on Windows for some reason related to the event loop not being exited
  1033 +#else // not _WIN32
1080 1034 abort(); // We abort so we can get a stack trace back to the code that triggered the message.
  1035 +#endif // _WIN32
  1036 + }
1081 1037 }
1082 1038  
1083 1039 Context *br::Globals = NULL;
... ...
openbr/openbr_plugin.h
... ... @@ -794,12 +794,12 @@ public:
794 794 * By default <tt>share/openbr/openbr.bib</tt> will be searched for relative to:
795 795 * -# The working directory
796 796 * -# The executable's location
797   - * \param use_gui Create a QApplication instead of a QCoreApplication.
  797 + * \param useGui Create a QApplication instead of a QCoreApplication.
798 798 * \note Tiggers \em abort() on failure to locate <tt>share/openbr/openbr.bib</tt>.
799 799 * \note <a href="http://qt-project.org/">Qt</a> users should instead call this <i>after</i> initializing QApplication.
800 800 * \see finalize
801 801 */
802   - static void initialize(int &argc, char *argv[], QString sdkPath = "", bool use_gui = true);
  802 + static void initialize(int &argc, char *argv[], QString sdkPath = "", bool useGui = true);
803 803  
804 804 /*!
805 805 * \brief Call \em once at the end of the application to deallocate global variables.
... ...
openbr/plugins/draw.cpp
... ... @@ -40,10 +40,12 @@ class DrawTransform : public UntrainableTransform
40 40 Q_PROPERTY(bool points READ get_points WRITE set_points RESET reset_points STORED false)
41 41 Q_PROPERTY(bool rects READ get_rects WRITE set_rects RESET reset_rects STORED false)
42 42 Q_PROPERTY(bool inPlace READ get_inPlace WRITE set_inPlace RESET reset_inPlace STORED false)
  43 + Q_PROPERTY(int lineThickness READ get_lineThickness WRITE set_lineThickness RESET reset_lineThickness STORED false)
43 44 BR_PROPERTY(bool, verbose, false)
44 45 BR_PROPERTY(bool, points, true)
45 46 BR_PROPERTY(bool, rects, true)
46 47 BR_PROPERTY(bool, inPlace, false)
  48 + BR_PROPERTY(int, lineThickness, 1)
47 49  
48 50 void project(const Template &src, Template &dst) const
49 51 {
... ... @@ -61,7 +63,7 @@ class DrawTransform : public UntrainableTransform
61 63 }
62 64 if (rects) {
63 65 foreach (const Rect &rect, OpenCVUtils::toRects(src.file.namedRects() + src.file.rects()))
64   - rectangle(dst, rect, color);
  66 + rectangle(dst, rect, color, lineThickness);
65 67 }
66 68 }
67 69 };
... ...
openbr/plugins/eigen3.cpp
... ... @@ -302,8 +302,8 @@ class LDATransform : public Transform
302 302 Q_PROPERTY(int directLDA READ get_directLDA WRITE set_directLDA RESET reset_directLDA STORED false)
303 303 Q_PROPERTY(float directDrop READ get_directDrop WRITE set_directDrop RESET reset_directDrop STORED false)
304 304 Q_PROPERTY(QString inputVariable READ get_inputVariable WRITE set_inputVariable RESET reset_inputVariable STORED false)
305   - Q_PROPERTY(bool isBinary READ get_isBinary WRITE set_isBinary RESET reset_isBinary STORED true)
306   - Q_PROPERTY(bool normalize READ get_normalize WRITE set_normalize RESET reset_normalize STORED true)
  305 + Q_PROPERTY(bool isBinary READ get_isBinary WRITE set_isBinary RESET reset_isBinary STORED false)
  306 + Q_PROPERTY(bool normalize READ get_normalize WRITE set_normalize RESET reset_normalize STORED false)
307 307 BR_PROPERTY(float, pcaKeep, 0.98)
308 308 BR_PROPERTY(bool, pcaWhiten, false)
309 309 BR_PROPERTY(int, directLDA, 0)
... ... @@ -316,12 +316,6 @@ class LDATransform : public Transform
316 316 Eigen::VectorXf mean;
317 317 Eigen::MatrixXf projection;
318 318 float stdDev;
319   - bool trained;
320   -
321   - void init()
322   - {
323   - trained = false;
324   - }
325 319  
326 320 void train(const TemplateList &_trainingSet)
327 321 {
... ... @@ -461,9 +455,9 @@ class LDATransform : public Transform
461 455 projection = ((space2.eVecs.transpose() * space1.eVecs.transpose()) * pca.eVecs.transpose()).transpose();
462 456 dimsOut = dim2;
463 457  
  458 + stdDev = 1; // default initialize
464 459 if (isBinary) {
465 460 assert(dimsOut == 1);
466   - TemplateList projected;
467 461 float posVal = 0;
468 462 float negVal = 0;
469 463 Eigen::MatrixXf results(trainingSet.size(),1);
... ... @@ -493,8 +487,6 @@ class LDATransform : public Transform
493 487 if (normalize)
494 488 stdDev = sqrt(results.array().square().sum() / trainingSet.size());
495 489 }
496   -
497   - trained = true;
498 490 }
499 491  
500 492 void project(const Template &src, Template &dst) const
... ... @@ -508,18 +500,22 @@ class LDATransform : public Transform
508 500 // Do projection
509 501 outMap = projection.transpose() * (inMap - mean);
510 502  
511   - if (normalize && isBinary && trained)
  503 + if (normalize && isBinary)
512 504 dst.m().at<float>(0,0) = dst.m().at<float>(0,0) / stdDev;
513 505 }
514 506  
515 507 void store(QDataStream &stream) const
516 508 {
517   - stream << pcaKeep << directLDA << directDrop << dimsOut << mean << projection << stdDev << normalize << isBinary << trained;
  509 + stream << pcaKeep << directLDA << directDrop << dimsOut << mean << projection;
  510 + if (normalize && isBinary)
  511 + stream << stdDev;
518 512 }
519 513  
520 514 void load(QDataStream &stream)
521 515 {
522   - stream >> pcaKeep >> directLDA >> directDrop >> dimsOut >> mean >> projection >> stdDev >> normalize >> isBinary >> trained;
  516 + stream >> pcaKeep >> directLDA >> directDrop >> dimsOut >> mean >> projection;
  517 + if (normalize && isBinary)
  518 + stream >> stdDev;
523 519 }
524 520 };
525 521  
... ...
openbr/plugins/process.cpp
... ... @@ -531,8 +531,6 @@ class ProcessWrapperTransform : public TimeVaryingTransform
531 531 baseKey = id.toString();
532 532  
533 533 QStringList argumentList;
534   - argumentList.append("-useGui");
535   - argumentList.append("0");
536 534 argumentList.append("-algorithm");
537 535 argumentList.append(transform);
538 536 if (!Globals->path.isEmpty()) {
... ...
openbr/plugins/stream.cpp
... ... @@ -1079,8 +1079,7 @@ public:
1079 1079  
1080 1080 // Wait for the stream to process the last frame available from
1081 1081 // the data source.
1082   - bool wait_res = false;
1083   - wait_res = readStage->dataSource.waitLast();
  1082 + readStage->dataSource.waitLast();
1084 1083  
1085 1084 // Now that there are no more incoming frames, call finalize
1086 1085 // on each transform in turn to collect any last templates
... ...
scripts/evalAgeRegression-PCSO.sh
... ... @@ -4,7 +4,7 @@ if [ ! -f evalAgeRegression-PCSO.sh ]; then
4 4 exit
5 5 fi
6 6  
7   -export BR="../build/app/br/br -useGui 0"
  7 +export BR=../build/app/br/br
8 8 export PCSO_DIR=/user/pripshare/Databases/FaceDatabases/PCSO/PCSO/
9 9 export ageAlg=AgeRegression
10 10  
... ...
scripts/evalFaceRecognition-LFW.sh
... ... @@ -20,7 +20,7 @@ if [ ! -e Algorithm_Dataset ]; then
20 20 fi
21 21  
22 22 # Run the LFW test protocol
23   -br -useGui 0 -algorithm $ALGORITHM -path ../data/LFW/img/ -crossValidate 10 -pairwiseCompare ../data/LFW/sigset/test_image_restricted_target.xml ../data/LFW/sigset/test_image_restricted_query.xml ${ALGORITHM}_LFW.mtx -convert Output ${ALGORITHM}_lfw.mtx Algorithm_Dataset/${ALGORITHM}_LFW%1.eval
  23 +br -algorithm $ALGORITHM -path ../data/LFW/img/ -crossValidate 10 -pairwiseCompare ../data/LFW/sigset/test_image_restricted_target.xml ../data/LFW/sigset/test_image_restricted_query.xml ${ALGORITHM}_LFW.mtx -convert Output ${ALGORITHM}_lfw.mtx Algorithm_Dataset/${ALGORITHM}_LFW%1.eval
24 24  
25 25 # Plot results
26   -br -useGui 0 -plot Algorithm_Dataset/* 'lfw_results.pdf[smooth=Dataset,rocOptions[yLimits=(0,1)]]'
  26 +br -plot Algorithm_Dataset/* 'lfw_results.pdf[smooth=Dataset,rocOptions[yLimits=(0,1)]]'
... ...
scripts/evalFaceRecognition-MEDS.sh
... ... @@ -20,11 +20,11 @@ if [ ! -e Algorithm_Dataset ]; then
20 20 fi
21 21  
22 22 if [ ! -e MEDS.mask ]; then
23   - br -useGui 0 -makeMask ../data/MEDS/sigset/MEDS_frontal_target.xml ../data/MEDS/sigset/MEDS_frontal_query.xml MEDS.mask
  23 + br -makeMask ../data/MEDS/sigset/MEDS_frontal_target.xml ../data/MEDS/sigset/MEDS_frontal_query.xml MEDS.mask
24 24 fi
25 25  
26 26 # Run Algorithm on MEDS
27   -br -useGui 0 -algorithm ${ALGORITHM} -path ../data/MEDS/img -compare ../data/MEDS/sigset/MEDS_frontal_target.xml ../data/MEDS/sigset/MEDS_frontal_query.xml ${ALGORITHM}_MEDS.mtx -eval ${ALGORITHM}_MEDS.mtx MEDS.mask Algorithm_Dataset/${ALGORITHM}_MEDS.csv
  27 +br -algorithm ${ALGORITHM} -path ../data/MEDS/img -compare ../data/MEDS/sigset/MEDS_frontal_target.xml ../data/MEDS/sigset/MEDS_frontal_query.xml ${ALGORITHM}_MEDS.mtx -eval ${ALGORITHM}_MEDS.mtx MEDS.mask Algorithm_Dataset/${ALGORITHM}_MEDS.csv
28 28  
29 29 # Plot results
30   -br -useGui 0 -plot Algorithm_Dataset/*_MEDS.csv MEDS
  30 +br -plot Algorithm_Dataset/*_MEDS.csv MEDS
... ...
scripts/evalGenderClassification-PCSO.sh
... ... @@ -9,7 +9,7 @@ export ALGORITHM=GenderClassification
9 9 export PCSO_DIR=../data/PCSO/img
10 10  
11 11 # Create a file list by querying the database
12   -$BR -useGui 0 -quiet -algorithm Identity -enroll "$PCSO_DIR/PCSO.db[query='SELECT File,Gender,PersonID FROM PCSO', subset=1:8000]" terminal.txt > Input.txt
  12 +$BR -quiet -algorithm Identity -enroll "$PCSO_DIR/PCSO.db[query='SELECT File,Gender,PersonID FROM PCSO', subset=1:8000]" terminal.txt > Input.txt
13 13  
14 14 # Enroll the file list and evaluate performance
15   -$BR -useGui 0 -algorithm $ALGORITHM -path $PCSO_DIR -enroll Input.txt Output.txt -evalClassification Output.txt Input.txt Gender
16 15 \ No newline at end of file
  16 +$BR -algorithm $ALGORITHM -path $PCSO_DIR -enroll Input.txt Output.txt -evalClassification Output.txt Input.txt Gender
17 17 \ No newline at end of file
... ...
scripts/pedestrianBaselineLBP.sh
... ... @@ -27,8 +27,7 @@ else
27 27 TEST=testSmall.xml
28 28 fi
29 29  
30   -br -useGui 0 \
31   - -algorithm "${ALG}" \
  30 +br -algorithm "${ALG}" \
32 31 -path $INRIA_PATH/img \
33 32 -train $INRIA_PATH/sigset/train.xml pedModel \
34 33 -enroll $INRIA_PATH/sigset/$TEST pedResults.xml
... ...
scripts/trainAgeRegression-PCSO.sh
... ... @@ -13,4 +13,4 @@ export ageAlg=AgeRegression
13 13  
14 14 export PCSO_DIR=/user/pripshare/Databases/FaceDatabases/PCSO/PCSO/
15 15  
16   -$BR -useGui 0 -algorithm $ageAlg -path $PCSO_DIR/Images -train "$PCSO_DIR/PCSO.db[query='SELECT File,Age,PersonID FROM PCSO WHERE Age >= 17 AND AGE <= 68', subset=0:200]" ../share/openbr/models/algorithms/AgeRegression
  16 +$BR -algorithm $ageAlg -path $PCSO_DIR/Images -train "$PCSO_DIR/PCSO.db[query='SELECT File,Age,PersonID FROM PCSO WHERE Age >= 17 AND AGE <= 68', subset=0:200]" ../share/openbr/models/algorithms/AgeRegression
... ...
scripts/trainFaceRecognition-PCSO.sh
... ... @@ -14,7 +14,5 @@ export BR=../build/app/br/br
14 14  
15 15 export PCSO_DIR=/user/pripshare/Databases/FaceDatabases/PCSO/PCSO/
16 16  
17   -
18   -
19   -$BR -useGui 0 -algorithm FaceRecognition -path "$PCSO_DIR/Images/" -train "$PCSO_DIR/PCSO.db[query='SELECT File,PersonID as Label,PersonID FROM PCSO', subset=0:5:6000]" ../share/openbr/models/algorithms/FaceRecognition
  17 +$BR -algorithm FaceRecognition -path "$PCSO_DIR/Images/" -train "$PCSO_DIR/PCSO.db[query='SELECT File,PersonID as Label,PersonID FROM PCSO', subset=0:5:6000]" ../share/openbr/models/algorithms/FaceRecognition
20 18  
... ...
scripts/trainGenderClassification-PCSO.sh
... ... @@ -13,4 +13,4 @@ export genderAlg=GenderClassification
13 13  
14 14 export PCSO_DIR=/user/pripshare/Databases/FaceDatabases/PCSO/PCSO/
15 15  
16   -$BR -useGui 0 -algorithm $genderAlg -path $PCSO_DIR/Images -train "$PCSO_DIR/PCSO.db[query='SELECT File,Gender,PersonID FROM PCSO', subset=0:8000]" ../share/openbr/models/algorithms/GenderClassification
  16 +$BR -algorithm $genderAlg -path $PCSO_DIR/Images -train "$PCSO_DIR/PCSO.db[query='SELECT File,Gender,PersonID FROM PCSO', subset=0:8000]" ../share/openbr/models/algorithms/GenderClassification
... ...
share/openbr/cmake/OpenBRConfig.cmake
... ... @@ -8,6 +8,7 @@
8 8 # target_link_libraries(MY_TARGET_NAME ${OPENBR_LIBS})
9 9 # ================================================================
10 10  
  11 +string(REPLACE "/share/openbr/cmake" "" OPENBR_DIR ${OPENBR_DIR})
11 12 include_directories(${OPENBR_DIR}/include)
12 13 link_directories(${OPENBR_DIR}/lib)
13 14 set(OPENBR_LIBS "openbr")
... ...