diff --git a/.gitignore b/.gitignore index 4727cfa..2dc5649 100644 --- a/.gitignore +++ b/.gitignore @@ -37,3 +37,4 @@ scripts/results ### autogenerated sigsets ### data/INRIAPerson/sigset +data/KTH/sigset diff --git a/CHANGELOG.md b/CHANGELOG.md index 6445816..119ab3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ -0.4.0 - ??/??/?? +0.5.0 - ??/??/?? ================ + +0.4.0 - 9/17/13 +=============== +* Added simple GUI frontend * Added -evalLandmarking and -plotLandmarking for evaluating and plotting landmarking accuracy (#9) * Added -evalDetection and -plotDetection for evaluating and plotting object detection accuracy (#9) * Deprecated Transform::backProject diff --git a/CMakeLists.txt b/CMakeLists.txt index 907e780..1b6a00a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,11 +5,11 @@ cmake_minimum_required(VERSION 2.8.9) set(BR_SHARE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/share/openbr") set(CMAKE_AUTOMOC ON) set(CPACK_PACKAGE_NAME "OpenBR") -set(CPACK_PACKAGE_VENDOR "OpenBR") +set(CPACK_PACKAGE_VENDOR "OpenBiometrics") set(CPACK_PACKAGE_DESCRIPTION "Open Source Biometric Recognition") set(CPACK_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME}) set(CPACK_PACKAGE_VERSION_MAJOR 0) -set(CPACK_PACKAGE_VERSION_MINOR 4) +set(CPACK_PACKAGE_VERSION_MINOR 5) set(CPACK_PACKAGE_VERSION_PATCH 0) set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}") set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.txt") @@ -132,6 +132,8 @@ install(DIRECTORY share DESTINATION .) install(DIRECTORY ${BR_THIRDPARTY_SHARE} DESTINATION share) # Package +set(CPACK_PACKAGE_EXECUTABLES "OpenBR" "OpenBR") +set(CPACK_CREATE_DESKTOP_LINKS "OpenBR") if(CMAKE_HOST_WIN32) set(CPACK_NSIS_MODIFY_PATH ON) set(CPACK_NSIS_MUI_ICON ${NATIVE_ICON}) @@ -140,6 +142,7 @@ if(CMAKE_HOST_WIN32) if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") set(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES64") endif() + set(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\OpenBR.exe") elseif(CMAKE_HOST_APPLE) configure_file("${CMAKE_CURRENT_SOURCE_DIR}/README.md" "README.txt" COPYONLY) set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_BINARY_DIR}/README.txt") diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 9fbe2b8..af4aa9b 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -3,3 +3,6 @@ add_subdirectory(br) # Build examples/tests add_subdirectory(examples) + +# Build OpenBR GUI application +add_subdirectory(OpenBR) diff --git a/app/OpenBR/CMakeLists.txt b/app/OpenBR/CMakeLists.txt new file mode 100644 index 0000000..a9fe331 --- /dev/null +++ b/app/OpenBR/CMakeLists.txt @@ -0,0 +1,5 @@ +include_directories(${CMAKE_CURRENT_BINARY_DIR}) +add_executable(OpenBR WIN32 OpenBR.cpp ${BR_RESOURCES}) +qt5_use_modules(OpenBR ${QT_DEPENDENCIES}) +target_link_libraries(OpenBR openbr ${BR_THIRDPARTY_LIBS}) +install(TARGETS OpenBR RUNTIME DESTINATION bin) diff --git a/app/OpenBR/OpenBR.cpp b/app/OpenBR/OpenBR.cpp new file mode 100644 index 0000000..1de9dec --- /dev/null +++ b/app/OpenBR/OpenBR.cpp @@ -0,0 +1,108 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace br; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + explicit MainWindow(QWidget *parent = 0) + : QMainWindow(parent) + { + QGridLayout *gridLayout = new QGridLayout(); + TemplateViewer *target = new TemplateViewer(this); + TemplateViewer *query = new TemplateViewer(this); + target->setEditable(false); + query->setEditable(false); + TemplateMetadata *targetMetadata = new TemplateMetadata(this); + TemplateMetadata *queryMetadata = new TemplateMetadata(this); + targetMetadata->addClassifier("GenderClassification"); + targetMetadata->addClassifier("AgeRegression"); + queryMetadata->addClassifier("GenderClassification"); + queryMetadata->addClassifier("AgeRegression"); + Tail *tail = new Tail(this); + gridLayout->addWidget(target, 0, 1, 1, 1); + gridLayout->addWidget(query, 0, 0, 1, 1); + gridLayout->setRowStretch(0, 1); + gridLayout->addWidget(targetMetadata, 1, 1, 1, 1); + gridLayout->addWidget(queryMetadata, 1, 0, 1, 1); + gridLayout->setRowStretch(1, 0); + gridLayout->addWidget(tail, 2, 0, 1, 2); + gridLayout->setRowStretch(2, 0); + + QMenuBar *menuBar = new QMenuBar(); + QMenu *file = new QMenu("File"); + QAction *clear = new QAction("Clear", this); + clear->setShortcut(QKeySequence("Ctrl+C")); + connect(clear, SIGNAL(triggered()), tail, SLOT(clear())); + file->addAction(clear); + Algorithm *algorithm = new Algorithm(); + algorithm->addAlgorithm("FaceRecognition", "Face Recognition"); + algorithm->addAlgorithm("PP5", "PittPatt"); + QMenu *helpMenu = new QMenu("Help"); + QAction *aboutAction = new QAction("About", this); + QAction *contactAction = new QAction("Contact", this); + helpMenu->addAction(aboutAction); + helpMenu->addAction(contactAction); + connect(aboutAction, SIGNAL(triggered()), this, SLOT(about())); + connect(contactAction, SIGNAL(triggered()), this, SLOT(contact())); + menuBar->addMenu(file); + menuBar->addMenu(algorithm); + menuBar->addMenu(helpMenu); + + setGeometry(100, 100, 700, 500); + setMenuBar(menuBar); + setWindowIcon(QIcon(":/openbr.png")); + setWindowTitle("OpenBR"); + setCentralWidget(new QWidget(this)); + centralWidget()->setLayout(gridLayout); + setStatusBar(new Progress(this)); + + connect(target, SIGNAL(newInput(File)), tail, SLOT(setTargetGallery(File))); + connect(query, SIGNAL(newInput(File)), tail, SLOT(setQueryGallery(File))); + connect(tail, SIGNAL(newTargetFile(File)), target, SLOT(setFile(File))); + connect(tail, SIGNAL(newQueryFile(File)), query, SLOT(setFile(File))); + connect(tail, SIGNAL(newTargetFile(File)), targetMetadata, SLOT(setFile(File))); + connect(tail, SIGNAL(newQueryFile(File)), queryMetadata, SLOT(setFile(File))); + } + +private slots: + void about() + { + QMessageBox::about(this, "About", Context::about()); + } + + void contact() + { + QMessageBox::about(this, "Contact", "openbr-dev@googlegroups.com\n\nPlease reach out to us on our public mailing list!"); + } +}; + +int main(int argc, char *argv[]) +{ + QApplication application(argc, argv); + Context::initialize(argc, argv); + Globals->scoreNormalization = false; + + MainWindow mainWindow; + mainWindow.show(); + + const int result = application.exec(); + Context::finalize(); + return result; +} + +#include "OpenBR.moc" diff --git a/data/KTH/test_9ppl.xml b/data/KTH/test_9ppl.xml deleted file mode 100644 index 2d2a85d..0000000 --- a/data/KTH/test_9ppl.xml +++ /dev/null @@ -1,237 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/data/KTH/train_16ppl.xml b/data/KTH/train_16ppl.xml deleted file mode 100644 index 799f563..0000000 --- a/data/KTH/train_16ppl.xml +++ /dev/null @@ -1,417 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/data/PCSO/sigset/PCSO_2x1k_test.xml b/data/PCSO/sigset/PCSO_2x1k_test.xml new file mode 100644 index 0000000..e1f7b04 --- /dev/null +++ b/data/PCSO/sigset/PCSO_2x1k_test.xml @@ -0,0 +1,6003 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/data/PCSO/sigset/PCSO_2x1k_train.xml b/data/PCSO/sigset/PCSO_2x1k_train.xml new file mode 100644 index 0000000..e769ea6 --- /dev/null +++ b/data/PCSO/sigset/PCSO_2x1k_train.xml @@ -0,0 +1,6003 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/openbr/CMakeLists.txt b/openbr/CMakeLists.txt index e343c83..bc9b2b5 100644 --- a/openbr/CMakeLists.txt +++ b/openbr/CMakeLists.txt @@ -10,7 +10,7 @@ include(plugins/plugins.cmake) # Optional GUI module if(NOT ${BR_EMBEDDED}) aux_source_directory(gui BR_GUI) - qt5_add_resources(BR_ICONS icons/icons.qrc) + qt5_add_resources(BR_ICONS ../share/openbr/icons.qrc) file(GLOB HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/gui/*.h) install(FILES ${HEADERS} DESTINATION include/openbr/gui) endif() diff --git a/openbr/core/core.cpp b/openbr/core/core.cpp index 71e3d51..f44b1bb 100644 --- a/openbr/core/core.cpp +++ b/openbr/core/core.cpp @@ -41,6 +41,9 @@ struct AlgorithmCore void train(const File &input, const QString &model) { + qDebug("Training on %s%s", qPrintable(input.flat()), + model.isEmpty() ? "" : qPrintable(" to " + model)); + TemplateList data(TemplateList::fromGallery(input)); // set the Train bool metadata, in case a Transform's project @@ -111,8 +114,14 @@ struct AlgorithmCore FileList enroll(File input, File gallery = File()) { + qDebug("Enrolling %s%s", qPrintable(input.flat()), + gallery.isNull() ? "" : qPrintable(" to " + gallery.flat())); + FileList fileList; - if (gallery.isNull()) gallery = getMemoryGallery(input); + if (gallery.name.isEmpty()) { + if (input.name.isEmpty()) return FileList(); + else gallery = getMemoryGallery(input); + } QScopedPointer g(Gallery::make(gallery)); if (g.isNull()) qFatal("Null gallery!"); @@ -196,6 +205,10 @@ struct AlgorithmCore void compare(File targetGallery, File queryGallery, File output) { + qDebug("Comparing %s and %s%s", qPrintable(targetGallery.flat()), + qPrintable(queryGallery.flat()), + output.isNull() ? "" : qPrintable(" to " + output.flat())); + if (output.exists() && output.get("cache", false)) return; if (queryGallery == ".") queryGallery = targetGallery; @@ -210,7 +223,7 @@ struct AlgorithmCore if (!output.fileName().contains("%1")) qFatal("Output file name missing split number place marker (%%1)"); partitionSizes = output.getList("split"); for (int i=0; i("algorithm"))->train(input, model); } FileList br::Enroll(const File &input, const File &gallery) { - qDebug("Enrolling %s%s", qPrintable(input.flat()), - gallery.isNull() ? "" : qPrintable(" to " + gallery.flat())); return AlgorithmManager::getAlgorithm(gallery.get("algorithm"))->enroll(input, gallery); } void br::Compare(const File &targetGallery, const File &queryGallery, const File &output) { - qDebug("Comparing %s and %s%s", qPrintable(targetGallery.flat()), - qPrintable(queryGallery.flat()), - output.isNull() ? "" : qPrintable(" to " + output.flat())); AlgorithmManager::getAlgorithm(output.get("algorithm"))->compare(targetGallery, queryGallery, output); } diff --git a/openbr/core/eval.cpp b/openbr/core/eval.cpp index 0562309..646177d 100644 --- a/openbr/core/eval.cpp +++ b/openbr/core/eval.cpp @@ -374,7 +374,7 @@ struct DetectionOperatingPoint static QStringList computeDetectionResults(const QList &detections, int totalPositives, bool discrete) { QList points; - float TP = 0, FP = 0, prevFP = 0; + float TP = 0, FP = 0, prevFP = -1; for (int i=0; i &detec FP += 1 - detection.overlap; } if ((i == detections.size()-1) || (detection.confidence > detections[i+1].confidence)) { - if (FP > prevFP) { + if (FP > prevFP || (i == detections.size()-1)) { points.append(DetectionOperatingPoint(TP, FP, totalPositives)); prevFP = FP; } diff --git a/openbr/core/opencvutils.cpp b/openbr/core/opencvutils.cpp index 48601e9..bf91833 100644 --- a/openbr/core/opencvutils.cpp +++ b/openbr/core/opencvutils.cpp @@ -22,7 +22,7 @@ #include "qtutils.h" using namespace cv; - +using namespace std; int OpenCVUtils::getFourcc() { @@ -33,9 +33,9 @@ int OpenCVUtils::getFourcc() QString recovered_string = recovered_variant.toString(); if (recovered_string.length() == 4) { fourcc = CV_FOURCC(recovered_string[0].toLatin1(), - recovered_string[1].toLatin1(), - recovered_string[2].toLatin1(), - recovered_string[3].toLatin1()); + recovered_string[1].toLatin1(), + recovered_string[2].toLatin1(), + recovered_string[3].toLatin1()); } else if (recovered_string.compare("-1")) fourcc = -1; } @@ -119,6 +119,14 @@ Mat OpenCVUtils::toMat(const QList &src, int rows) return dst; } +Mat OpenCVUtils::toMat(const QList > &srcs, int rows) +{ + QList flat; + foreach (const QList &src, srcs) + flat.append(src); + return toMat(flat, rows); +} + Mat OpenCVUtils::toMat(const QList &src, int rows) { if (rows == -1) rows = src.size(); diff --git a/openbr/core/opencvutils.h b/openbr/core/opencvutils.h index 8deeb49..d01c807 100644 --- a/openbr/core/opencvutils.h +++ b/openbr/core/opencvutils.h @@ -35,6 +35,7 @@ namespace OpenCVUtils // To image cv::Mat toMat(const QList &src, int rows = -1); + cv::Mat toMat(const QList< QList > &srcs, int rows = -1); cv::Mat toMat(const QList &src, int rows = -1); cv::Mat toMat(const QList &src); // Data organized one matrix per row diff --git a/openbr/gui/algorithm.cpp b/openbr/gui/algorithm.cpp index 633122d..39fe742 100644 --- a/openbr/gui/algorithm.cpp +++ b/openbr/gui/algorithm.cpp @@ -6,10 +6,11 @@ /**** ALGORITHM ****/ /*** PUBLIC ***/ br::Algorithm::Algorithm(QWidget *parent) - : QComboBox(parent) + : QMenu(parent) { - setToolTip("Algorithm"); - connect(this, SIGNAL(currentIndexChanged(QString)), this, SLOT(setAlgorithm(QString))); + setTitle("Algorithm"); + br_set_property("enrollAll", "true"); + connect(this, SIGNAL(triggered(QAction*)), this, SLOT(setAlgorithm(QAction*))); } /*** PUBLIC SLOTS ***/ @@ -22,18 +23,24 @@ bool br::Algorithm::addAlgorithm(const QString &algorithm, const QString &displa if (!availableAlgorithms.contains(algorithm)) return false; + QString name; if (displayName.isEmpty()) { - addItem(algorithm); + name = algorithm; } else { displayNames.insert(displayName, algorithm); - addItem(displayName); + name = displayName; } + + QAction *action = addAction(name); + action->setCheckable(true); + if (actions().size() == 1) action->trigger(); return true; } /*** PRIVATE SLOTS ***/ -void br::Algorithm::setAlgorithm(QString algorithm) +void br::Algorithm::setAlgorithm(QAction *action) { + QString algorithm = action->text(); if (displayNames.contains(algorithm)) algorithm = displayNames[algorithm]; diff --git a/openbr/gui/algorithm.h b/openbr/gui/algorithm.h index d6bc2a4..e6c489f 100644 --- a/openbr/gui/algorithm.h +++ b/openbr/gui/algorithm.h @@ -1,15 +1,15 @@ #ifndef BR_ALGORITHM_H #define BR_ALGORITHM_H -#include +#include #include -#include +#include #include namespace br { -class BR_EXPORT Algorithm : public QComboBox +class BR_EXPORT Algorithm : public QMenu { Q_OBJECT QHash displayNames; @@ -21,7 +21,7 @@ public slots: bool addAlgorithm(const QString &algorithm, const QString &displayName = ""); private slots: - void setAlgorithm(QString algorithm); + void setAlgorithm(QAction *action); signals: void newAlgorithm(QString algorithm); diff --git a/openbr/gui/classifier.cpp b/openbr/gui/classifier.cpp index 71a3102..8fcfe8b 100644 --- a/openbr/gui/classifier.cpp +++ b/openbr/gui/classifier.cpp @@ -18,7 +18,6 @@ Classifier::Classifier(QWidget *parent) void Classifier::setAlgorithm(const QString &algorithm) { this->algorithm = algorithm; - _classify(File()); // Trigger algorithm initialization } /*** PUBLIC SLOTS ***/ @@ -31,7 +30,7 @@ void Classifier::classify(const File &file) void Classifier::setClassification(const QString &key, const QString &value) { if (key.isEmpty()) clear(); - else setText(QString("%1: %2").arg(key, value)); + else setText(QString("%1: %2").arg(key, value)); } /*** PRIVATE ***/ @@ -39,22 +38,14 @@ void Classifier::_classify(File file) { QString key, value; foreach (const File &f, Enroll(file.flat(), File("[algorithm=" + algorithm + "]"))) { + if (algorithm == "GenderClassification") key = "Gender"; + else if (algorithm == "AgeRegression") key = "Age"; + else key = algorithm; - if (algorithm == "GenderClassification") { - key = "Gender"; - } else if (algorithm == "AgeRegression") { - key = "Age"; - } else { - key = algorithm; - } + if (!f.contains(key)) continue; - if (!f.contains(key)) - continue; - - if (algorithm == "AgeRegression") - value = QString::number(int(f.get(key)+0.5)) + " Years"; - else - value = f.get(key); + if (algorithm == "AgeRegression") value = QString::number(int(f.get(key)+0.5)) + " Years"; + else value = f.get(key); break; } diff --git a/openbr/gui/galleryviewer.cpp b/openbr/gui/galleryviewer.cpp index adb20c7..e69e673 100644 --- a/openbr/gui/galleryviewer.cpp +++ b/openbr/gui/galleryviewer.cpp @@ -2,11 +2,12 @@ using namespace br; +/**** GALLERY_VIEWER ****/ +/*** PUBLIC ***/ GalleryViewer::GalleryViewer(QWidget *parent) : QMainWindow(parent) { addToolBar(Qt::TopToolBarArea, &gGallery); - addToolBar(Qt::BottomToolBarArea, &tmTemplateMetadata); setCentralWidget(&tvgTemplateViewerGrid); setWindowFlags(Qt::Widget); diff --git a/openbr/gui/imageviewer.cpp b/openbr/gui/imageviewer.cpp index c14bc5f..807aa37 100644 --- a/openbr/gui/imageviewer.cpp +++ b/openbr/gui/imageviewer.cpp @@ -34,13 +34,13 @@ br::ImageViewer::ImageViewer(QWidget *parent) void br::ImageViewer::setDefaultText(const QString &text) { defaultText = text; + updatePixmap(QImage()); } void br::ImageViewer::setImage(const QString &file, bool async) { QMutexLocker locker(&mutex); - if(file.isNull()) src = QImage(); // Gets rid of runtime FileEngine::open warning - else src = QImage(file); + src = file.isNull() ? QImage() : QImage(file); updatePixmap(src, async); } @@ -61,19 +61,20 @@ void br::ImageViewer::setImage(const QPixmap &pixmap, bool async) /*** PRIVATE ***/ void br::ImageViewer::updatePixmap(QImage image, bool async) { - // For the time being, disabling this is sufficient if (async) { - //QTimer::singleShot(0, this, SLOT(updatePixmap(image))); - //return; + QMetaObject::invokeMethod(this, "updatePixmap", Qt::QueuedConnection, Q_ARG(QImage, image), Q_ARG(bool, false)); + return; } QMutexLocker locker(&mutex); if (image.isNull() || size().isNull()) { - QLabel::setPixmap(QPixmap()); - QLabel::setText(defaultText); + setPixmap(QPixmap()); + setText(defaultText); + setFrameShape(QLabel::StyledPanel); } else { - QLabel::clear(); - QLabel::setPixmap(QPixmap::fromImage(image.scaled(size(), Qt::KeepAspectRatio))); + clear(); + setPixmap(QPixmap::fromImage(image.scaled(size(), Qt::KeepAspectRatio))); + setFrameShape(QLabel::NoFrame); } } diff --git a/openbr/gui/progress.cpp b/openbr/gui/progress.cpp index 4ac8318..fbe2bf6 100644 --- a/openbr/gui/progress.cpp +++ b/openbr/gui/progress.cpp @@ -1,5 +1,5 @@ #include -#include + #include "progress.h" /**** PROGRESS ****/ @@ -7,6 +7,7 @@ br::Progress::Progress(QWidget *parent) : QStatusBar(parent) { + setContentsMargins(0, 0, 0, 0); pbProgress.setVisible(false); pbProgress.setMaximum(100); pbProgress.setMinimum(0); diff --git a/openbr/gui/tail.cpp b/openbr/gui/tail.cpp new file mode 100644 index 0000000..13afff2 --- /dev/null +++ b/openbr/gui/tail.cpp @@ -0,0 +1,142 @@ +#include + +#include "tail.h" + +using namespace br; + +/**** TAIL ****/ +/*** PUBLIC ***/ +Tail::Tail(QWidget *parent) + : QWidget(parent) +{ + layout = new QHBoxLayout(this); + layout->setContentsMargins(0, 0, 0, 0); + slider = new QSlider(this); + slider->setOrientation(Qt::Horizontal); + lhs = new QLabel(this); + rhs = new QLabel(this); + layout->addWidget(lhs); + layout->addWidget(slider, 1); + layout->addWidget(rhs); + setFocusPolicy(Qt::StrongFocus); + setVisible(false); + connect(slider, SIGNAL(valueChanged(int)), this, SLOT(setIndex(int))); + connect(&compareWatcher, SIGNAL(finished()), this, SLOT(compareDone())); +} + +/*** PUBLIC SLOTS ***/ +void Tail::clear() +{ + targetGallery = File(); + queryGallery = File(); + targetFiles.clear(); + queryFiles.clear(); + scores.clear(); + slider->setMaximum(0); + setIndex(0); + setVisible(false); +} + +void Tail::setIndex(int index) +{ + index = std::min(std::max(slider->minimum(), index), slider->maximum()); + slider->setValue(index); + emit newTargetFile((index >= 0) && (index < targetFiles.size()) ? targetFiles[index] : File()); + emit newQueryFile((index >= 0) && (index < queryFiles.size()) ? queryFiles[index] : File()); + emit newScore((index >= 0) && (index < scores.size()) ? scores[index] : std::numeric_limits::quiet_NaN()); +} + +void Tail::setTargetGallery(const File &gallery) +{ + targetGallery = gallery; + compare(); +} + +void Tail::setQueryGallery(const File &gallery) +{ + queryGallery = gallery; + compare(); +} + +/*** PROTECTED ***/ +void Tail::keyPressEvent(QKeyEvent *event) +{ + QWidget::keyPressEvent(event); + event->accept(); + if (event->key() == Qt::Key_Up) first(); + else if (event->key() == Qt::Key_Left) previous(); + else if (event->key() == Qt::Key_Right) next(); + else if (event->key() == Qt::Key_Down) last(); +} + +void Tail::wheelEvent(QWheelEvent *event) +{ + QWidget::wheelEvent(event); + event->accept(); + if (event->delta() < 0) next(); + else previous(); +} + +/*** PRIVATE ***/ +void Tail::compare() +{ + targetFiles.clear(); + queryFiles.clear(); + scores.clear(); + + if (targetGallery.isNull() || queryGallery.isNull()) { + if (!targetGallery.isNull()) targetFiles = TemplateList::fromGallery(targetGallery).files(); + if (!queryGallery.isNull()) queryFiles = TemplateList::fromGallery(queryGallery).files(); + slider->setMaximum(std::max(targetFiles.size(), queryFiles.size()) - 1); + lhs->setText("First Image"); + rhs->setText("Last Image"); + setVisible(slider->maximum() > 1); + setIndex(0); + } else { + compareWatcher.setFuture(QtConcurrent::run(Compare, targetGallery.flat(), queryGallery.flat(), QString("buffer.tail[atMost=1000]"))); + } +} + +void Tail::first() +{ + setIndex(0); +} + +void Tail::previous() +{ + setIndex(slider->value()-1); +} + +void Tail::next() +{ + setIndex(slider->value()+1); +} + +void Tail::last() +{ + setIndex(scores.size()-1); +} + +void Tail::compareDone() +{ + QStringList lines = QString(Globals->buffer).split('\n'); + lines.takeFirst(); // Remove header + + foreach (const QString &line, lines) { + const QStringList words = Object::parse(line); + if (words.size() != 3) qFatal("Invalid tail file."); + bool ok; + float score = words[0].toFloat(&ok); assert(ok); + targetFiles.append(words[1]); + queryFiles.append(words[2]); + scores.append(score); + } + slider->setMaximum(scores.size()-1); + lhs->setText("Best Match"); + rhs->setText("Worst Match"); + + setVisible(slider->maximum() > 1); + setIndex(0); +} + +#include "moc_tail.cpp" diff --git a/openbr/gui/tail.h b/openbr/gui/tail.h new file mode 100644 index 0000000..e5146cb --- /dev/null +++ b/openbr/gui/tail.h @@ -0,0 +1,58 @@ +#ifndef BR_TAIL_H +#define BR_TAIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace br +{ + +class BR_EXPORT Tail : public QWidget +{ + Q_OBJECT + QHBoxLayout *layout; + QSlider *slider; + QLabel *lhs, *rhs; + File targetGallery, queryGallery; + FileList targetFiles, queryFiles; + QList scores; + QFutureWatcher compareWatcher; + +public: + explicit Tail(QWidget *parent = 0); + +public slots: + void clear(); + void setIndex(int index); + void setTargetGallery(const File &gallery); + void setQueryGallery(const File &gallery); + +protected: + void keyPressEvent(QKeyEvent *event); + void wheelEvent(QWheelEvent *event); + +private: + void compare(); + +private slots: + void first(); + void previous(); + void next(); + void last(); + void compareDone(); + +signals: + void newTargetFile(File file); + void newQueryFile(File file); + void newScore(float score); +}; + +} // namespace br + +#endif // BR_TAIL_H diff --git a/openbr/gui/templatemetadata.cpp b/openbr/gui/templatemetadata.cpp index 1c4b8b3..06d39cf 100644 --- a/openbr/gui/templatemetadata.cpp +++ b/openbr/gui/templatemetadata.cpp @@ -3,42 +3,51 @@ #include "templatemetadata.h" +using namespace br; + /*** PUBLIC ***/ -br::TemplateMetadata::TemplateMetadata(QWidget *parent) - : QToolBar("Template Metadata", parent) +TemplateMetadata::TemplateMetadata(QWidget *parent) + : QWidget(parent) { - lFile.setTextInteractionFlags(Qt::TextSelectableByMouse); - wSpacer.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - addWidget(&wOffset); - addWidget(&lFile); - addWidget(&wSpacer); - addWidget(&lQuality); + layout = new QHBoxLayout(this); + layout->setContentsMargins(0, 0, 0, 0); + lFile = new QLabel(this); + lFile->setTextInteractionFlags(Qt::TextSelectableByMouse); + lQuality = new QLabel(this); + layout->addWidget(lFile); + layout->addWidget(lQuality); + showQuality(false); } -void br::TemplateMetadata::addClassifier(const QString &classifier_, const QString algorithm) +void TemplateMetadata::addClassifier(const QString &classifier_, const QString algorithm) { QSharedPointer classifier(new Classifier()); classifier->setAlgorithm(classifier_); - QAction *action = addWidget(classifier.data()); - conditionalClassifiers.append(ConditionalClassifier(algorithm, classifier, action)); + layout->addWidget(classifier.data()); + conditionalClassifiers.append(ConditionalClassifier(algorithm, classifier)); } -/**** PRIVATE SLOTS ****/ -void br::TemplateMetadata::setFile(const br::File &file) +/*** PUBLIC SLOTS ***/ +void TemplateMetadata::setFile(const File &file) { - if (file.isNull()) lFile.clear(); - else lFile.setText("File: " + file.fileName()); - lQuality.setText(QString("Quality: %1").arg(file.get("FTE", false) ? "Low" : "High")); + if (file.isNull()) lFile->clear(); + else lFile->setText("File: " + file.fileName() + ""); + lQuality->setText(QString("Quality: %1").arg(file.get("FTE", false) ? "Low" : "High")); foreach (const ConditionalClassifier &classifier, conditionalClassifiers) - if (classifier.action->isVisible()) classifier.classifier->classify(file); + if (classifier.classifier->isVisible()) classifier.classifier->classify(file); } -void br::TemplateMetadata::setAlgorithm(const QString &algorithm) +void TemplateMetadata::setAlgorithm(const QString &algorithm) { foreach (const ConditionalClassifier &classifier, conditionalClassifiers) { classifier.classifier->clear(); - classifier.action->setVisible(classifier.algorithm.isEmpty() || classifier.algorithm == algorithm); + classifier.classifier->setVisible(classifier.algorithm.isEmpty() || classifier.algorithm == algorithm); } } +void TemplateMetadata::showQuality(bool visible) +{ + lQuality->setVisible(visible); +} + #include "moc_templatemetadata.cpp" diff --git a/openbr/gui/templatemetadata.h b/openbr/gui/templatemetadata.h index 95568c8..ab6c205 100644 --- a/openbr/gui/templatemetadata.h +++ b/openbr/gui/templatemetadata.h @@ -1,6 +1,7 @@ #ifndef BR_TEMPLATEMETADATA_H #define BR_TEMPLATEMETADATA_H +#include #include #include #include @@ -14,21 +15,20 @@ namespace br { -class BR_EXPORT TemplateMetadata : public QToolBar +class BR_EXPORT TemplateMetadata : public QWidget { Q_OBJECT - QLabel lFile, lQuality; - QWidget wOffset, wSpacer; + QHBoxLayout *layout; + QLabel *lFile, *lQuality; struct ConditionalClassifier { QString algorithm; QSharedPointer classifier; - QAction *action; - ConditionalClassifier() : action(NULL) {} - ConditionalClassifier(const QString &algorithm_, const QSharedPointer &classifier_, QAction *action_) - : algorithm(algorithm_), classifier(classifier_), action(action_) {} + ConditionalClassifier() {} + ConditionalClassifier(const QString &algorithm_, const QSharedPointer &classifier_) + : algorithm(algorithm_), classifier(classifier_) {} }; QList conditionalClassifiers; @@ -37,8 +37,9 @@ public: void addClassifier(const QString &classifier, const QString algorithm = ""); public slots: - void setFile(const br::File &file); + void setFile(const File &file); void setAlgorithm(const QString &algorithm); + void showQuality(bool visible); }; } // namespace br diff --git a/openbr/gui/templateviewer.cpp b/openbr/gui/templateviewer.cpp index 148e0a5..a811cb2 100644 --- a/openbr/gui/templateviewer.cpp +++ b/openbr/gui/templateviewer.cpp @@ -25,8 +25,8 @@ TemplateViewer::TemplateViewer(QWidget *parent) { setAcceptDrops(true); setMouseTracking(true); - setText("Drag Photo or Folder Here\n"); - format = "Registered"; + setDefaultText("Drag Photo or Folder Here\n"); + format = "Photo"; editable = true; setFile(File()); update(); diff --git a/openbr/gui/templateviewer.h b/openbr/gui/templateviewer.h index 90b04bc..932ac64 100644 --- a/openbr/gui/templateviewer.h +++ b/openbr/gui/templateviewer.h @@ -16,10 +16,10 @@ namespace br { -class BR_EXPORT TemplateViewer : public br::ImageViewer +class BR_EXPORT TemplateViewer : public ImageViewer { Q_OBJECT - br::File file; + File file; QPointF mousePoint; QString format; @@ -31,7 +31,7 @@ public: explicit TemplateViewer(QWidget *parent = 0); public slots: - void setFile(const br::File &file); + void setFile(const File &file); void setEditable(bool enabled); void setMousePoint(const QPointF &mousePoint); void setFormat(const QString &format); @@ -50,10 +50,10 @@ protected slots: void paintEvent(QPaintEvent *event); signals: - void newInput(br::File input); + void newInput(File input); void newInput(QImage input); void newMousePoint(QPointF mousePoint); - void selectedInput(br::File input); + void selectedInput(File input); }; } diff --git a/openbr/icons/glyphicons_190_circle_plus@2x.png b/openbr/icons/glyphicons_190_circle_plus@2x.png deleted file mode 100644 index e026a41..0000000 --- a/openbr/icons/glyphicons_190_circle_plus@2x.png +++ /dev/null diff --git a/openbr/icons/openbr.icns b/openbr/icons/openbr.icns deleted file mode 100644 index df9b60d..0000000 --- a/openbr/icons/openbr.icns +++ /dev/null diff --git a/openbr/icons/openbr.ico b/openbr/icons/openbr.ico deleted file mode 100644 index 16d0121..0000000 --- a/openbr/icons/openbr.ico +++ /dev/null diff --git a/openbr/icons/openbr.png b/openbr/icons/openbr.png deleted file mode 100644 index ea6ac53..0000000 --- a/openbr/icons/openbr.png +++ /dev/null diff --git a/openbr/openbr.h b/openbr/openbr.h index f175fe3..9a115ce 100644 --- a/openbr/openbr.h +++ b/openbr/openbr.h @@ -187,7 +187,6 @@ BR_EXPORT void br_finalize(); * \brief Perform score level fusion on similarity matrices. * \param num_input_simmats Size of \em input_simmats. * \param input_simmats Array of \ref simmat. All simmats must have the same dimensions. - * \param mask \ref mask used to indicate which, if any, values to ignore. * \param normalization Valid options are: * - \c None - No score normalization. * - \c MinMax - Scores normalized to [0,1]. diff --git a/openbr/openbr_export.cpp b/openbr/openbr_export.cpp index 8760c5d..8eef195 100644 --- a/openbr/openbr_export.cpp +++ b/openbr/openbr_export.cpp @@ -45,7 +45,7 @@ * \page introduction Introduction * \brief A high-level technical overview of OpenBR. * - * We strongly encourage users new to OpenBR to read our publication for an introduction to the core concepts. + * We strongly encourage users new to OpenBR to read our publication for an introduction to the core concepts. * Researchers incorporating OpenBR into their own work are kindly requested to cite this paper. */ @@ -57,9 +57,8 @@ * Installation from source is the recommended method for getting OpenBR on your machine. * If you need a little help getting started, choose from the list of build instructions for free C++ compilers below: * - \subpage windows_msvc - * - \subpage windows_mingw * - \subpage osx_clang - * - \subpage linux_all + * - \subpage linux_gcc * * \section installation_from_binary From Binary * Pre-compiled releases are not currently provided, but they can be built from source using the instructions above. @@ -96,50 +95,50 @@ $ br -help * -# You will have to register with Microsoft after installation, but it's free. * -# Grab any available Visual Studio Updates. * -# Download and install Windows 8 SDK. - * -# Download and Install CMake 2.8.10.2 + * -# Download and Install CMake 2.8.11.2 * -# During installation setup select "add CMake to PATH". - * -# Download OpenCV 2.4.5 + * -# Download OpenCV 2.4.6.1 * -# Consider the free open source program 7-Zip if you need a program to unarchive tarballs. - * -# Move the "opencv-2.4.5" folder to "C:\". + * -# Move the "opencv-2.4.6.1" folder to "C:\". * -# Open "VS2012 x64 Cross Tools Command Prompt" (from the Start Menu, select "All Programs" -> "Microsoft Visual Studio 2012" -> "Visual Studio Tools" -> "VS2012 x64 Cross Tools Command Prompt") and enter: - * \code - * $ cd C:\opencv-2.4.5 - * $ mkdir build-msvc2012 - * $ cd build-msvc2012 - * $ cmake -G "NMake Makefiles" -DBUILD_PERF_TESTS=OFF -DBUILD_TESTS=OFF -DWITH_FFMPEG=OFF -DCMAKE_BUILD_TYPE=Debug .. - * $ nmake - * $ nmake install - * $ cmake -DCMAKE_BUILD_TYPE=Release .. - * $ nmake - * $ nmake install - * $ nmake clean - * \endcode - * -# Download and Install Qt 5.0.2 + \code + $ cd C:\opencv-2.4.6.1 + $ mkdir build-msvc2012 + $ cd build-msvc2012 + $ cmake -G "NMake Makefiles" -DBUILD_PERF_TESTS=OFF -DBUILD_TESTS=OFF -DWITH_FFMPEG=OFF -DCMAKE_BUILD_TYPE=Debug .. + $ nmake + $ nmake install + $ cmake -DCMAKE_BUILD_TYPE=Release .. + $ nmake + $ nmake install + $ nmake clean + \endcode + * -# Download and Install Qt 5.1.1 * -# Create a GitHub account and follow their instructions for setting up Git. * -# Launch "Git Bash" from the Desktop and clone OpenBR: - * \code - * $ cd /c - * $ git clone https://github.com/biometrics/openbr.git - * $ cd openbr - * $ git submodule init - * $ git submodule update - * \endcode + \code + $ cd /c + $ git clone https://github.com/biometrics/openbr.git + $ cd openbr + $ git submodule init + $ git submodule update + \endcode * -# Build OpenBR! * -# From the VS2012 x64 Cross Tools Command Prompt: - * \code - * $ cd C:\openbr - * $ mkdir build-msvc2012 - * $ cd build-msvc2012 - * $ cmake -G "CodeBlocks - NMake Makefiles" -DCMAKE_PREFIX_PATH="C:/openCV-2.4.5/build-msvc2012/install;C:/Qt/Qt5.0.2/5.0.2/msvc2012_64" -DCMAKE_INSTALL_PREFIX="./install" -DBR_INSTALL_DEPENDENCIES=ON -DCMAKE_BUILD_TYPE=Release .. - * $ nmake - * $ nmake install - * \endcode + \code + $ cd C:\openbr + $ mkdir build-msvc2012 + $ cd build-msvc2012 + $ cmake -G "CodeBlocks - NMake Makefiles" -DCMAKE_PREFIX_PATH="C:/opencv-2.4.6.1/build-msvc2012/install;C:/Qt/Qt5.1.1/5.1.1/msvc2012_64" -DCMAKE_INSTALL_PREFIX="./install" -DBR_INSTALL_DEPENDENCIES=ON -DCMAKE_BUILD_TYPE=Release .. + $ nmake + $ nmake install + \endcode * -# Check out the "install" folder. * -# Hack OpenBR! * -# From the VS2012 x64 Cross Tools Command Prompt: - * \code - * $ C:\Qt\Qt5.0.2\Tools\QtCreator\bin\qtcreator.exe - * \endcode + \code + $ C:\Qt\Qt5.1.1\Tools\QtCreator\bin\qtcreator.exe + \endcode * -# From the Qt Creator "Tools" menu select "Options..." * -# Under "Kits" select "Desktop (default)" * -# For "Compiler:" select "Microsoft Visual C++ Compiler 11.0 (x86_amd64)" and click "OK" @@ -151,258 +150,178 @@ $ br -help * -# You're all set! You can find more information on Qt Creator here if you need. * -# (Optional) Package OpenBR! * -# From the VS2012 x64 Cross Tools Command Prompt: - * \code - * $ cd C:\openbr\build-msvc2012 - * $ cpack -G ZIP - * \endcode - */ - -/*! - * \page windows_mingw Windows 7 - MinGW-w64 2.0 - x64 - * -# Download and Unarchive MinGW-w64 GCC 4.7.2 - * -# Use the free open source program 7-Zip to unarchive. - * -# Move "x86_64-w64-mingw32-gcc-4.7.2-release-win64_rubenvb\mingw64" to "C:\". - * -# Download and Install CMake 2.8.10.2 - * -# During installation setup select "add CMake to PATH". - * -# Download OpenCV 2.4.5 - * -# Consider the free open source program 7-Zip if you need a program to unarchive tarballs. - * -# Move the "opencv-2.4.5" folder to "C:\". - * -# From the MinGW-w64 Command Prompt (double-click "C:\mingw64\mingw64env.cmd"): - * \code - * $ cd C:\opencv-2.4.5 - * $ mkdir build-mingw64 - * $ cd build-mingw64 - * $ cmake -G "MinGW Makefiles" -DBUILD_PERF_TESTS=OFF -DBUILD_TESTS=OFF -DWITH_FFMPEG=OFF -DCMAKE_BUILD_TYPE=Debug .. - * $ mingw32-make - * $ mingw32-make install - * $ cmake -DCMAKE_BUILD_TYPE=Release .. - * $ mingw32-make - * $ mingw32-make install - * $ mingw32-make clean - * \endcode - * -# Download and Unzip Qt 5.0.2 - * -# Install Perl/Python/Ruby dependencies as explained in the "Windows" section of "README". Make sure they are added to "path" when given the option during installation. - * -# Download and Install Direct X Software Developement Kit, you may also need to install the latest OpenGL drivers from your graphics card manufacturer. - * -# From the MinGW-w64 Command Prompt: - * \code - * $ cd qt-everywhere-opensource-src-5.0.2 - * $ configure -prefix C:\Qt\Qt5.0.2\5.0.2\mingw64 -opensource -confirm-license -nomake examples -nomake tests -opengl desktop - * $ mingw32-make - * $ mingw32-make install - * $ cd .. - * $ rmdir /Q /S qt-everywhere-opensource-src-5.0.2 - * \endcode - * -# mingw32-make will take several hours to finish. - * -# Create a GitHub account and follow their instructions for setting up Git. - * -# Launch "Git Bash" from the Desktop and clone OpenBR: - * \code - * $ cd /c - * $ git clone https://github.com/biometrics/openbr.git - * $ cd openbr - * $ git submodule init - * $ git submodule update - * \endcode - * -# Build OpenBR! - * -# From the MinGW-w64 Command Prompt: - * \code - * $ cd C:\openbr - * $ mkdir build-mingw64 - * $ cd build-mingw64 - * $ cmake -G "CodeBlocks - MinGW Makefiles" -DCMAKE_RC_COMPILER="C:/mingw64/bin/windres.exe" -DCMAKE_PREFIX_PATH="C:/opencv-2.4.5/build-mingw64/install;C:/Qt/Qt5.0.2/5.0.2/mingw64" -DCMAKE_INSTALL_PREFIX="./install" -DBR_INSTALL_DEPENDENCIES=ON -DCMAKE_BUILD_TYPE=Release .. - * $ mingw32-make - * $ mingw32-make install - * \endcode - * -# Check out the "install" folder. - * -# Hack OpenBR! - * -# From the MinGW-w64 Command Prompt: - * \code - * $ C:\Qt\Qt5.0.2\Tools\QtCreator\bin\qtcreator.exe - * \endcode - * -# From the Qt Creator "Tools" menu select "Options..." - * -# Under "Kits" select "Desktop (default)" - * -# For "Compiler:" select "MinGW (x86 64bit in C:\mingw64\bin)" and click "OK" - * -# From the Qt Creator "File" menu select "Open File or Project...". - * -# Select "C:\openbr\CMakeLists.txt" then "Open". - * -# If prompted for the location of CMake, enter "C:\Program Files (x86)\CMake 2.8\bin\cmake.exe". - * -# Browse to your pre-existing build directory "C:\openbr\build-mingw64" then select "Next". - * -# Clear any text in the "arguments" box then select "Run CMake" then "Finish". - * -# You're all set! You can find more information on Qt Creator here if you need. - * -# (Optional) Package OpenBR! - * -# From the MinGW-w64 Command Prompt: - * \code - * $ cd C:\openbr\build-mingw64 - * $ cpack -G ZIP - * \endcode + \code + $ cd C:\openbr\build-msvc2012 + $ cpack -G ZIP + \endcode */ /*! * \page osx_clang OS X Mountain Lion - Clang/LLVM 3.1 - x64 * -# Download and install the latest "Xcode" and "Command Line Tools" from the Apple Developer Downloads page. - * -# Download CMake 2.8.10.2 - * \code - * $ cd ~/Downloads - * $ tar -xf cmake-2.8.10.2.tar.gz - * $ cd cmake-2.8.10.2 - * $ ./configure - * $ make -j4 - * $ sudo make install - * $ cd .. - * $ rm -rf cmake-2.8.10.2* - * \endcode - * -# Download OpenCV 2.4.5 - * \code - * $ cd ~/Downloads - * $ tar -xf opencv-2.4.5.tar.gz - * $ cd opencv-2.4.5 - * $ mkdir build - * $ cd build - * $ cmake -DCMAKE_BUILD_TYPE=Release .. - * $ make -j4 - * $ sudo make install - * $ cd ../.. - * $ rm -rf opencv-2.4.5* - * \endcode - * -# Download and install Qt 5.0.2 + * -# Download CMake 2.8.11.2 + \code + $ cd ~/Downloads + $ tar -xf cmake-2.8.11.2.tar.gz + $ cd cmake-2.8.11.2 + $ ./configure + $ make -j4 + $ sudo make install + $ cd .. + $ rm -rf cmake-2.8.11.2* + \endcode + * -# Download OpenCV 2.4.6.1 + \code + $ cd ~/Downloads + $ tar -xf opencv-2.4.6.1.tar.gz + $ cd opencv-2.4.6.1 + $ mkdir build + $ cd build + $ cmake -DCMAKE_BUILD_TYPE=Release .. + $ make -j4 + $ sudo make install + $ cd ../.. + $ rm -rf opencv-2.4.6.1* + \endcode + * -# Download and install Qt 5.1.1 * -# Create a GitHub account, follow their instructions for setting up Git. - * \code - * $ git clone https://github.com/biometrics/openbr.git - * $ cd openbr - * $ git submodule init - * $ git submodule update - * \endcode + \code + $ git clone https://github.com/biometrics/openbr.git + $ cd openbr + $ git submodule init + $ git submodule update + \endcode * -# Build OpenBR! - * \code - * $ mkdir build # from the OpenBR root directory - * $ cd build - * $ cmake -DCMAKE_PREFIX_PATH=~/Qt5.0.2/5.0.2/clang_64 -DCMAKE_BUILD_TYPE=Release .. - * $ make -j4 - * $ sudo make install - * \endcode + \code + $ mkdir build # from the OpenBR root directory + $ cd build + $ cmake -DCMAKE_PREFIX_PATH=~/Qt5.1.1/5.1.1/clang_64 -DCMAKE_BUILD_TYPE=Release .. + $ make -j4 + $ sudo make install + \endcode * -# Hack OpenBR! * -# Open Qt Creator IDE - * \code - * $ open ~/Qt5.0.2/Qt\ Creator.app - * \endcode + \code + $ open ~/Qt5.1.1/Qt\ Creator.app + \endcode * -# From the Qt Creator "File" menu select "Open File or Project...". * -# Select "openbr/CMakeLists.txt" then "Open". * -# Browse to your pre-existing build directory "openbr/build" then select "Continue". * -# Select "Run CMake" then "Done". * -# You're all set! You can find more information on Qt Creator here if you need. * -# (Optional) Test OpenBR! - * \code - * $ cd openbr/scripts - * $ ./downloadDatasets.sh - * $ cd ../build - * $ make test - * \endcode + \code + $ cd openbr/scripts + $ ./downloadDatasets.sh + $ cd ../build + $ make test + \endcode * -# (Optional) Package OpenBR! - * \code - * $ cd openbr/build - * $ sudo cpack -G TGZ - * \endcode + \code + $ cd openbr/build + $ sudo cpack -G TGZ + \endcode * -# (Optional) Build OpenBR documentation! - * -# Download Doxygen 1.8.2 - * \code - * $ cd ~/Downloads - * $ tar -xf doxygen-1.8.2.src.tar.gz - * $ cd doxygen-1.8.2 - * $ ./configure - * $ make -j4 - * $ sudo make install - * $ cd .. - * $ rm -rf doxygen-1.8.2* - * \endcode + * -# Download Doxygen 1.8.5 + \code + $ cd ~/Downloads + $ tar -xf doxygen-1.8.5.src.tar.gz + $ cd doxygen-1.8.5 + $ ./configure + $ make -j4 + $ sudo make install + $ cd .. + $ rm -rf doxygen-1.8.5* + \endcode * -# Modify build settings and recompile. - * \code - * $ cd openbr/build - * $ cmake -DBR_BUILD_DOCUMENTATION=ON .. - * $ make -j4 - * $ open html/index.html - * \endcode + \code + $ cd openbr/build + $ cmake -DBR_BUILD_DOCUMENTATION=ON .. + $ make -j4 + $ open html/index.html + \endcode */ /*! - * \page linux_all Ubuntu 13.04 - GCC 4.7.3 or ICC 13.1.1 - x64 + * \page linux_gcc Ubuntu 13.04 - GCC 4.7.3 - x64 * -# Install GCC 4.7.3 - * \code - * $ sudo apt-get update - * $ sudo apt-get install build-essential - * \endcode - * -# (Optional) Assuming you meet the eligibility requirements and you want to use ICC instead of GCC, Download and Install Intel C++ Studio XE 2013. + \code + $ sudo apt-get update + $ sudo apt-get install build-essential + \endcode * -# Install CMake 2.8.10.1 - * \code - * $ sudo apt-get install cmake cmake-curses-gui - * \endcode + \code + $ sudo apt-get install cmake cmake-curses-gui + \endcode * -# Download OpenCV 2.4.5, note this - * \code - * $ cd ~/Downloads - * $ tar -xf opencv-2.4.5.tar.gz - * $ cd opencv-2.4.5 - * $ mkdir build - * $ cd build - * $ cmake -DCMAKE_BUILD_TYPE=Release .. - * $ make -j4 - * $ sudo make install - * $ cd ../.. - * $ rm -rf opencv-2.4.5* - * \endcode + \code + $ cd ~/Downloads + $ tar -xf opencv-2.4.5.tar.gz + $ cd opencv-2.4.5 + $ mkdir build + $ cd build + $ cmake -DCMAKE_BUILD_TYPE=Release .. + $ make -j4 + $ sudo make install + $ cd ../.. + $ rm -rf opencv-2.4.5* + \endcode * -# Install Qt 5.0.1 - * \code - * $ sudo apt-get install qt5-default libqt5svg5-dev qtcreator - * \endcode + \code + $ sudo apt-get install qt5-default libqt5svg5-dev qtcreator + \endcode * -# Create a GitHub account, follow their instructions for setting up Git. - * \code - * $ git clone https://github.com/biometrics/openbr.git - * $ cd openbr - * $ git submodule init - * $ git submodule update - * \endcode + \code + $ git clone https://github.com/biometrics/openbr.git + $ cd openbr + $ git submodule init + $ git submodule update + \endcode * -# Build OpenBR! - * \code - * $ mkdir build # from the OpenBR root directory - * $ cd build - * $ cmake -DCMAKE_BUILD_TYPE=Release .. # GCC Only - * $ cmake -DCMAKE_C_COMPILER=/opt/intel/bin/icc -DCMAKE_CXX_COMPILER=/opt/intel/bin/icpc -DCMAKE_BUILD_TYPE=Release .. # ICC Only - * $ make -j4 - * $ sudo make install - * \endcode + \code + $ mkdir build # from the OpenBR root directory + $ cd build + $ cmake -DCMAKE_BUILD_TYPE=Release .. + $ make -j4 + $ sudo make install + \endcode * -# Hack OpenBR! * -# Open Qt Creator IDE - * \code - * $ qtcreator & - * \endcode + \code + $ qtcreator & + \endcode * -# From the Qt Creator "File" menu select "Open File or Project...". * -# Select "openbr/CMakeLists.txt" then "Open". * -# Browse to your pre-existing build directory "openbr/build" then select "Next". * -# Select "Run CMake" then "Finish". * -# You're all set! You can find more information on Qt Creator here if you need. * -# (Optional) Test OpenBR! - * \code - * $ cd openbr/scripts - * $ ./downloadDatasets.sh - * $ cd ../build - * $ make test - * \endcode + \code + $ cd openbr/scripts + $ ./downloadDatasets.sh + $ cd ../build + $ make test + \endcode * -# (Optional) Package OpenBR! - * \code - * $ cd openbr/build - * $ sudo cpack -G TGZ - * \endcode + \code + $ cd openbr/build + $ sudo cpack -G TGZ + \endcode * -# (Optional) Build OpenBR documentation! - * \code - * $ sudo apt-get install doxygen - * $ cd openbr/build - * $ cmake -DBR_BUILD_DOCUMENTATION=ON .. - * $ make -j4 - * $ sudo apt-get install libgnome2-bin - * $ gnome-open html/index.html - * \endcode + \code + $ sudo apt-get install doxygen + $ cd openbr/build + $ cmake -DBR_BUILD_DOCUMENTATION=ON .. + $ make -j4 + $ sudo apt-get install libgnome2-bin + $ gnome-open html/index.html + \endcode */ /*! * \page help Help * - Developer mailing list: openbr-dev@googlegroups.com - * - IRC Channel: irc.freenode.net#openbr + * - IRC Channel: irc.freenode.net\#openbr */ /*! diff --git a/openbr/openbr_plugin.h b/openbr/openbr_plugin.h index 638cb3c..6153b77 100644 --- a/openbr/openbr_plugin.h +++ b/openbr/openbr_plugin.h @@ -671,6 +671,12 @@ public: BR_PROPERTY(QByteArray, buffer, QByteArray()) /*! + * \brief Enable/disable score normalization. + */ + Q_PROPERTY(bool scoreNormalization READ get_scoreNormalization WRITE set_scoreNormalization RESET reset_scoreNormalization) + BR_PROPERTY(bool, scoreNormalization, true) + + /*! * \brief Perform k-fold cross validation. */ Q_PROPERTY(int crossValidate READ get_crossValidate WRITE set_crossValidate RESET reset_crossValidate) diff --git a/openbr/plugins/cvt.cpp b/openbr/plugins/cvt.cpp index fdb83b2..a0b12e2 100644 --- a/openbr/plugins/cvt.cpp +++ b/openbr/plugins/cvt.cpp @@ -220,6 +220,23 @@ class MAddTransform : public UntrainableTransform BR_REGISTER(Transform, MAddTransform) +/*! + * \ingroup transforms + * \brief Computes the absolute value of each element. + * \author Josh Klontz \cite jklontz + */ +class AbsTransform : public UntrainableTransform +{ + Q_OBJECT + + void project(const Template &src, Template &dst) const + { + dst = abs(src); + } +}; + +BR_REGISTER(Transform, AbsTransform) + } // namespace br #include "cvt.moc" diff --git a/openbr/plugins/distance.cpp b/openbr/plugins/distance.cpp index d4a3808..31a6f71 100644 --- a/openbr/plugins/distance.cpp +++ b/openbr/plugins/distance.cpp @@ -145,7 +145,7 @@ BR_REGISTER(Distance, DefaultDistance) * \author Josh Klontz \cite jklontz * * The templates are compared using each br::Distance in order. - * If the result of the comparison with any given distance is -INT_MAX then this result is returned early. + * If the result of the comparison with any given distance is -FLOAT_MAX then this result is returned early. * Otherwise the returned result is the value of comparing the templates using the last br::Distance. */ class PipeDistance : public Distance diff --git a/openbr/plugins/ebif.cpp b/openbr/plugins/ebif.cpp new file mode 100644 index 0000000..718a3b9 --- /dev/null +++ b/openbr/plugins/ebif.cpp @@ -0,0 +1,131 @@ +#include + +#include "openbr_internal.h" +#include "openbr/core/common.h" +#include "openbr/core/opencvutils.h" + +using namespace cv; + +namespace br +{ + +/*! + * \ingroup transforms + * \brief Face Recognition Using Early Biologically Inspired Features + * Min Li (IBM China Research Lab, China), Nalini Ratha (IBM Watson Research Center, + * USA), Weihong Qian (IBM China Research Lab, China), Shenghua Bao (IBM China + * Research Lab, China), Zhong Su (IBM China Research Lab, China) + * \author Josh Klontz \cite jklontz + */ + +class EBIFTransform : public UntrainableTransform +{ + Q_OBJECT + Q_PROPERTY(int N READ get_N WRITE set_N RESET reset_N STORED false) // scales + Q_PROPERTY(int M READ get_M WRITE set_M RESET reset_M STORED false) // orientations + BR_PROPERTY(int, N, 6) + BR_PROPERTY(int, M, 9) + + QList orientations; + + void init() + { + for (int m=0; m > features; + foreach (Transform *orientation, orientations) { + // Compute the reponse wavelet response + Template response; + orientation->project(scales, response); + + // Pool for each two adjacent features + QList orientedFeatures; + for (int i=0; i localFeatures; localFeatures.reserve(2*M); + for (int m=0; m pool(const Mat &bottom, const Mat &top) const + { + QList features; + for (int i=0; i<=top.rows-3; i+=3) { + for (int j=0; j<=top.cols-3; j+=3) { + QList vals; vals.reserve(3*3 + 4*4); + + // Top values + for (int k=0; k<3; k++) { + const float *data = top.ptr(i+k, j); + for (int l=0; l<3; l++) + vals.append(data[l]); + } + + // Bottom values + for (int k=0; k<4; k++) { + const float *data = bottom.ptr(4*i/3+k, 4*j/3); + for (int l=0; l<4; l++) + vals.append(data[l]); + } + + double mean, stddev; + Common::MeanStdDev(vals, &mean, &stddev); + features.append(mean); + features.append(stddev); + } + } + + return features; + } +}; + +BR_REGISTER(Transform, EBIFTransform) + +} // namespace br + +#include "ebif.moc" diff --git a/openbr/plugins/output.cpp b/openbr/plugins/output.cpp index 7b643a6..9f8301b 100644 --- a/openbr/plugins/output.cpp +++ b/openbr/plugins/output.cpp @@ -268,7 +268,7 @@ class rrOutput : public MatrixOutput for (int i=0; i Pair; foreach (const Pair &pair, Common::Sort(OpenCVUtils::matrixToVector(data.row(i)), true, limit)) { @@ -384,7 +384,7 @@ class evalOutput : public MatrixOutput double mean, stddev; Common::MeanStdDev(TARs, &mean, &stddev); - qDebug("TAR @ FAR = 0.001: %.3f +/- %.3f", mean, stddev); + qDebug("TAR @ FAR = 0.01: %.3f +/- %.3f", mean, stddev); } } } diff --git a/openbr/plugins/qtnetwork.cmake b/openbr/plugins/qtnetwork.cmake index e2b5b3d..49e02e9 100644 --- a/openbr/plugins/qtnetwork.cmake +++ b/openbr/plugins/qtnetwork.cmake @@ -4,5 +4,5 @@ if(${BR_WITH_QTNETWORK}) find_package(HttpParser) set(QT_DEPENDENCIES ${QT_DEPENDENCIES} Network) set(BR_THIRDPARTY_SRC ${BR_THIRDPARTY_SRC} plugins/qtnetwork.cpp ${HTTPPARSER_SRC}) - install(FILES ${HTTPPARSER_LICENSE} RENAME http-parser DESTINATION share/openbr/license) + install(FILES ${HTTPPARSER_LICENSE} RENAME http-parser DESTINATION share/openbr/licenses) endif() diff --git a/openbr/plugins/quality.cpp b/openbr/plugins/quality.cpp index 54f8b21..7df4b54 100644 --- a/openbr/plugins/quality.cpp +++ b/openbr/plugins/quality.cpp @@ -184,8 +184,9 @@ class MatchProbabilityDistance : public Distance float compare(const Template &target, const Template &query) const { - float rawScore = distance->compare(target, query); + const float rawScore = distance->compare(target, query); if (rawScore == -std::numeric_limits::max()) return rawScore; + if (!Globals->scoreNormalization) return -log(rawScore+1); return mp(rawScore, gaussian); } diff --git a/openbr/plugins/stasm4.cpp b/openbr/plugins/stasm4.cpp index 0e9f667..acb7911 100644 --- a/openbr/plugins/stasm4.cpp +++ b/openbr/plugins/stasm4.cpp @@ -5,7 +5,6 @@ #include "openbr/core/qtutils.h" #include "openbr/core/opencvutils.h" #include -#include using namespace std; using namespace cv; @@ -77,7 +76,7 @@ class StasmTransform : public UntrainableTransform StasmCascadeClassifier *stasmCascade = stasmCascadeResource.acquire(); - int foundface; + int foundFace = 0; int nLandmarks = stasm_NLANDMARKS; float landmarks[2 * stasm_NLANDMARKS]; @@ -109,13 +108,14 @@ class StasmTransform : public UntrainableTransform else if (i == 39) /*Stasm Left Eye*/ { eyes[2*i] = leftEye.x(); eyes[2*i+1] = leftEye.y(); } else { eyes[2*i] = 0; eyes[2*i+1] = 0; } } - } else qFatal("Unable to interpret pinned eyes."); + stasm_search_pinned(landmarks, eyes, reinterpret_cast(src.m().data), src.m().cols, src.m().rows, NULL); - stasm_search_pinned(landmarks, eyes, reinterpret_cast(src.m().data), src.m().cols, src.m().rows, NULL); + // The ASM in Stasm is guaranteed to converge in this case + foundFace = 1; + } + } - // The ASM in Stasm is guaranteed to converge in this case - foundface = 1; - } stasm_search_single(&foundface, landmarks, reinterpret_cast(src.m().data), src.m().cols, src.m().rows, *stasmCascade, NULL, NULL); + if (!foundFace) stasm_search_single(&foundFace, landmarks, reinterpret_cast(src.m().data), src.m().cols, src.m().rows, *stasmCascade, NULL, NULL); if (stasm3Format) { nLandmarks = 76; @@ -130,8 +130,8 @@ class StasmTransform : public UntrainableTransform dst.file.clearRects(); } - if (!foundface) { - qWarning("No face found in %s", qPrintable(src.file.fileName())); + if (!foundFace) { + qWarning("No face found in %s.", qPrintable(src.file.fileName())); } else { for (int i = 0; i < nLandmarks; i++) { QPointF point(landmarks[2 * i], landmarks[2 * i + 1]); diff --git a/openbr/plugins/validate.cpp b/openbr/plugins/validate.cpp index c296949..71ef72f 100644 --- a/openbr/plugins/validate.cpp +++ b/openbr/plugins/validate.cpp @@ -74,9 +74,7 @@ class CrossValidateTransform : public MetaTransform // Remove template that was repeated to make the testOnly template if (subjectIndices.size() > 1 && subjectIndices.size() <= i) { removed.append(subjectIndices[i%subjectIndices.size()]); - } - // For the time being, we don't support addition training data added to every fold in the case of leaveOneImageOut - else if (partitionsBuffer[j] == i) { + } else if (partitionsBuffer[j] == i) { removed.append(j); } @@ -88,10 +86,6 @@ class CrossValidateTransform : public MetaTransform } else { j--; } - } else if (partitions[j] == -1) { - // Keep data for training, but modify the partition so we project into the correct space - partitionedData[j].file.set("Partition",i); - j--; } else if (partitions[j] == i) { // Remove data, it's designated for testing partitionedData.removeAt(j); @@ -106,7 +100,19 @@ class CrossValidateTransform : public MetaTransform void project(const Template &src, Template &dst) const { - transforms[src.file.get("Partition", 0)]->project(src, dst); + // Remember, the partition should never be -1 + // since it is assumed that the allPartitions + // flag is only used during comparison + // (i.e. only used when making a mask) + if (src.file.getBool("Train", false)) dst = src; + else { + // If we want to duplicate templates but use the same training data + // for all partitions (i.e. transforms.size() == 1), we need to + // restrict the partition + int partition = src.file.get("Partition", 0); + partition = (partition >= transforms.size()) ? 0 : partition; + transforms[partition]->project(src, dst); + } } void store(QDataStream &stream) const @@ -249,6 +255,37 @@ class MetadataDistance : public Distance BR_REGISTER(Distance, MetadataDistance) +/*! + * \ingroup distances + * \brief Sets distance to -FLOAT_MAX if a target template has/doesn't have a key. + * \author Scott Klum \cite sklum + */ +class RejectDistance : public Distance +{ + Q_OBJECT + + Q_PROPERTY(QStringList keys READ get_keys WRITE set_keys RESET reset_keys STORED false) + BR_PROPERTY(QStringList, keys, QStringList()) + Q_PROPERTY(bool rejectIfContains READ get_rejectIfContains WRITE set_rejectIfContains RESET reset_rejectIfContains STORED false) + BR_PROPERTY(bool, rejectIfContains, false) + + float compare(const Template &a, const Template &b) const + { + // We don't look at the query + (void) b; + + foreach (const QString &key, keys) + if ((rejectIfContains && a.file.contains(key)) || + (!rejectIfContains && !a.file.contains(key))) + return -std::numeric_limits::max(); + + return 0; + } +}; + + +BR_REGISTER(Distance, RejectDistance) + } // namespace br #include "validate.moc" diff --git a/scripts/btas2013.sh b/scripts/btas2013.sh new file mode 100755 index 0000000..2ff4af2 --- /dev/null +++ b/scripts/btas2013.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +if [ ! -f btas2013.sh ]; then + echo "Run this script from the scripts folder!" + exit +fi + +mkdir results + +# Train and evaluate Fisherfaces +br -algorithm "Open+Cvt(Gray)+Cascade(FrontalFace)+ASEFEyes+Affine(128,128,0.33,0.45)+CvtFloat+LDA(0.98)+Normalize(L2):Dist(L2)" -path ~/data/PCSO/ -train ../data/PCSO/sigset/PCSO_2x1k_train.xml Fisherfaces +br -algorithm Fisherfaces -path ~/data/PCSO/ -compare ../data/PCSO/sigset/PCSO_2x1k_test.xml . Fisherfaces.mtx + +# Train and evaluate Klarefaces +br -algorithm "Open+Cvt(Gray)+Cascade(FrontalFace)+ASEFEyes+Affine(128,128,0.33,0.45)+(Grid(10,10)+SIFTDescriptor(12)+ByRow)/(Blur(1.1)+Gamma(0.2)+DoG(1,2)+ContrastEq(0.1,10)+LBP(1,2)+RectRegions(8,8,6,6)+Hist(59))+PCA(0.95)+Normalize(L2)+Cat+Dup(22)+RndSubspace(0.05,1)+LDA(0.98)+Cat+PCA(0.95)+Normalize(L1)+Quantize:NegativeLogPlusOne(ByteL1)" -path ~/data/PCSO/ -train ../data/PCSO/sigset/PCSO_2x1k_train.xml Klarefaces +br -algorithm Klarefaces -path ~/data/PCSO/ -compare ../data/PCSO/sigset/PCSO_2x1k_test.xml . Klarefaces.mtx + +# Train and evaluate Klarefaces EBIF +br -algorithm "Open+Cvt(Gray)+Cascade(FrontalFace)+ASEFEyes+Affine(128,128,0.33,0.45)+(Grid(10,10)+SIFTDescriptor(12)+ByRow)/(Blur(1.1)+Gamma(0.2)+DoG(1,2)+ContrastEq(0.1,10)+LBP(1,2)+RectRegions(8,8,6,6)+Hist(59))/(Resize(64,64)+EBIF)+PCA(0.95)+Normalize(L2)+Cat+Dup(22)+RndSubspace(0.05,1)+LDA(0.98)+Cat+PCA(0.95)+Normalize(L1)+Quantize:NegativeLogPlusOne(ByteL1)" -path ~/data/PCSO/ -train ../data/PCSO/sigset/PCSO_2x1k_train.xml KlarefacesEBIF +br -algorithm KlarefacesEBIF -path ~/data/PCSO/ -compare ../data/PCSO/sigset/PCSO_2x1k_test.xml . KlarefacesEBIF.mtx + +# Evaluate and plot +br -makeMask ../data/PCSO/sigset/PCSO_2x1k_test.xml . PCSO.mask +br -eval Fisherfaces.mtx PCSO.mask results/Fisherfaces.csv +br -eval Klarefaces.mtx PCSO.mask results/Klarefaces.csv +br -eval KlarefacesEBIF.mtx PCSO.mask results/KlarefacesEBIF.csv +br -plot results/* plots.pdf \ No newline at end of file diff --git a/scripts/downloadDatasets.sh b/scripts/downloadDatasets.sh index 734573c..95f9a74 100755 --- a/scripts/downloadDatasets.sh +++ b/scripts/downloadDatasets.sh @@ -57,6 +57,7 @@ fi if [ ! -d ../data/KTH/vid ]; then echo "Downloading KTH..." mkdir ../data/KTH/vid + mkdir ../data/KTH/sigset for vidclass in {'boxing','handclapping','handwaving','jogging','running','walking'}; do if hash curl 2>/dev/null; then curl -OL http://www.nada.kth.se/cvap/actions/${vidclass}.zip @@ -69,6 +70,8 @@ if [ ! -d ../data/KTH/vid ]; then done # this file is corrupted rm -f ../data/KTH/vid/boxing/person01_boxing_d4_uncomp.avi + ./writeKTHSigset.sh 1 16 > ../data/KTH/sigset/train_16ppl.xml + ./writeKTHSigset.sh 17 25 > ../data/KTH/sigset/test_9ppl.xml fi # LFW diff --git a/scripts/writeKTHSigset.sh b/scripts/writeKTHSigset.sh new file mode 100644 index 0000000..5c2abd0 --- /dev/null +++ b/scripts/writeKTHSigset.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +echo '' +echo '' +for ((person=$1; person <= $2; person++)); do + printf "\t\n" $person + for vidClass in {'boxing','handclapping','handwaving','jogging','running','walking'}; do + + for i in {1..4}; do + # person13_handclapping_d3 is missing + if [ $vidClass = 'handclapping' -a $person -eq 13 -a $i -eq 3 ]; then + continue + fi + # person01_boxing_d4 was deleted (corrupted file) + if [ $vidClass = 'boxing' -a $person -eq 1 -a $i -eq 4 ]; then + continue + fi + + printf "\t\t\n" $vidClass $person $vidClass $i + done + done + echo -e "\t" +done +echo '' diff --git a/openbr/icons/icons.qrc b/share/openbr/icons.qrc index 7fb3fed..e4667ae 100644 --- a/openbr/icons/icons.qrc +++ b/share/openbr/icons.qrc @@ -1,8 +1,5 @@ - glyphicons_190_circle_plus@2x.png - openbr.icns - openbr.ico openbr.png