Commit c0b68a0f9b34d7d9cc41a444cae9b0c7fbe5b44b
Merge branch 'master' of https://github.com/biometrics/openbr into pp5_rework
Showing
31 changed files
with
331 additions
and
631 deletions
CHANGELOG.md
| 1 | -0.3.0 - ??/??/?? | |
| 1 | +0.4.0 - ??/??/?? | |
| 2 | 2 | ================ |
| 3 | + | |
| 4 | +0.3.0 - 5/22/13 | |
| 5 | +=============== | |
| 3 | 6 | * Added wrapper to NEC Latent SDK |
| 4 | 7 | * Enrolling files/folders are now sorted naturally instead of alpha numerically |
| 5 | 8 | * YouTubeFacesDBTransform implements Dr. Wolf's experimental protocol |
| ... | ... | @@ -10,6 +13,7 @@ |
| 10 | 13 | * Reorganized GUI code and include paths (#31) |
| 11 | 14 | * 'br -daemon' to listen for commands on stdin |
| 12 | 15 | * Generalized 'br -convert', now requires three parameters |
| 16 | +* Official icon, thanks @sklum! | |
| 13 | 17 | |
| 14 | 18 | 0.2.0 - 2/23/13 |
| 15 | 19 | =============== | ... | ... |
CMakeLists.txt
| ... | ... | @@ -9,7 +9,7 @@ set(CPACK_PACKAGE_VENDOR "OpenBR") |
| 9 | 9 | set(CPACK_PACKAGE_DESCRIPTION "Open Source Biometric Recognition") |
| 10 | 10 | set(CPACK_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME}) |
| 11 | 11 | set(CPACK_PACKAGE_VERSION_MAJOR 0) |
| 12 | -set(CPACK_PACKAGE_VERSION_MINOR 3) | |
| 12 | +set(CPACK_PACKAGE_VERSION_MINOR 4) | |
| 13 | 13 | set(CPACK_PACKAGE_VERSION_PATCH 0) |
| 14 | 14 | set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}") |
| 15 | 15 | set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.txt") |
| ... | ... | @@ -25,13 +25,13 @@ endif() |
| 25 | 25 | |
| 26 | 26 | # Define resources |
| 27 | 27 | if(WIN32) |
| 28 | - set(CPACK_PACKAGE_ICON "${BR_SHARE_DIR}\\\\openbr-small.png") | |
| 28 | + set(CPACK_PACKAGE_ICON "${BR_SHARE_DIR}\\\\openbr_small.png") | |
| 29 | 29 | set(NATIVE_ICON "${BR_SHARE_DIR}/openbr.ico") |
| 30 | 30 | elseif(APPLE) |
| 31 | - set(CPACK_PACKAGE_ICON "${BR_SHARE_DIR}/openbr-small.png") | |
| 31 | + set(CPACK_PACKAGE_ICON "${BR_SHARE_DIR}/openbr_small.png") | |
| 32 | 32 | set(NATIVE_ICON "${BR_SHARE_DIR}/openbr.icns") |
| 33 | 33 | else() |
| 34 | - set(CPACK_PACKAGE_ICON "${BR_SHARE_DIR}/openbr-small.png") | |
| 34 | + set(CPACK_PACKAGE_ICON "${BR_SHARE_DIR}/openbr_small.png") | |
| 35 | 35 | set(NATIVE_ICON "${BR_SHARE_DIR}/openbr.png") |
| 36 | 36 | endif() |
| 37 | 37 | |
| ... | ... | @@ -69,7 +69,7 @@ set(BR_THIRDPARTY_LIBS ${BR_THIRDPARTY_LIBS} ${Qt5Core_QTMAIN_LIBRARIES}) |
| 69 | 69 | |
| 70 | 70 | # Find OpenCV |
| 71 | 71 | find_package(OpenCV REQUIRED) |
| 72 | -set(OPENCV_DEPENDENCIES opencv_core opencv_features2d opencv_flann opencv_highgui opencv_imgproc opencv_ml opencv_nonfree opencv_objdetect opencv_photo) | |
| 72 | +set(OPENCV_DEPENDENCIES opencv_core opencv_features2d opencv_flann opencv_gpu opencv_highgui opencv_imgproc opencv_ml opencv_nonfree opencv_objdetect opencv_photo) | |
| 73 | 73 | set(BR_THIRDPARTY_LIBS ${BR_THIRDPARTY_LIBS} ${OpenCV_LIBS}) |
| 74 | 74 | |
| 75 | 75 | # Find Alphanum | ... | ... |
openbr/core/core.cpp
| ... | ... | @@ -289,14 +289,18 @@ private: |
| 289 | 289 | if (Globals->abbreviations.contains(description)) |
| 290 | 290 | return init(Globals->abbreviations[description]); |
| 291 | 291 | |
| 292 | + //! [Parsing the algorithm description] | |
| 292 | 293 | QStringList words = QtUtils::parse(description.flat(), ':'); |
| 293 | 294 | if ((words.size() < 1) || (words.size() > 2)) qFatal("Invalid algorithm format."); |
| 295 | + //! [Parsing the algorithm description] | |
| 294 | 296 | |
| 295 | 297 | if (description.getBool("distribute", true)) |
| 296 | 298 | words[0] = "DistributeTemplate(" + words[0] + ")"; |
| 297 | 299 | |
| 300 | + //! [Creating the template generation and comparison methods] | |
| 298 | 301 | transform = QSharedPointer<Transform>(Transform::make(words[0], NULL)); |
| 299 | 302 | if (words.size() > 1) distance = QSharedPointer<Distance>(Distance::make(words[1], NULL)); |
| 303 | + //! [Creating the template generation and comparison methods] | |
| 300 | 304 | } |
| 301 | 305 | }; |
| 302 | 306 | ... | ... |
openbr/core/plot.cpp
| ... | ... | @@ -499,6 +499,7 @@ bool Plot(const QStringList &files, const br::File &destination, bool show) |
| 499 | 499 | (p.minor.size > 1 ? QString(" + scale_linetype_discrete(\"%1\")").arg(p.minor.header) : QString()) + |
| 500 | 500 | QString(" + scale_x_log10(labels=percent) + scale_y_log10(labels=percent) + annotation_logticks()\n\n"))); |
| 501 | 501 | |
| 502 | + | |
| 502 | 503 | p.file.write(qPrintable(QString("qplot(X, data=SD, geom=\"histogram\", fill=Y, position=\"identity\", alpha=I(1/2)") + |
| 503 | 504 | QString(", xlab=\"Score%1\"").arg((p.flip ? p.major.size : p.minor.size) > 1 ? " / " + (p.flip ? p.major.header : p.minor.header) : QString()) + |
| 504 | 505 | QString(", ylab=\"Frequency%1\"").arg((p.flip ? p.minor.size : p.major.size) > 1 ? " / " + (p.flip ? p.minor.header : p.major.header) : QString()) + |
| ... | ... | @@ -507,11 +508,11 @@ bool Plot(const QStringList &files, const br::File &destination, bool show) |
| 507 | 508 | QString(" + theme(aspect.ratio=1)\n\n"))); |
| 508 | 509 | |
| 509 | 510 | p.file.write(qPrintable(QString("ggplot(CMC, aes(x=X, y=Y%1%2)) + xlab(\"Rank\") + ylab(\"Retrieval Rate\")").arg(p.major.size > 1 ? QString(" ,colour=factor(%1)").arg(p.major.header) : QString(), p.minor.size > 1 ? QString(", linetype=factor(%1)").arg(p.minor.header) : QString()) + |
| 510 | - ((p.major.smooth || p.minor.smooth) ? (minimalist ? " + stat_summary(geom=\"line\", lwd=3, fun.y=mean)" : " + stat_summary(geom=\"line\", fun.y=min, aes(linetype=\"Min/Max\")) + stat_summary(geom=\"line\", fun.y=max, aes(linetype=\"Min/Max\")) + stat_summary(geom=\"line\", fun.y=mean, aes(linetype=\"Mean\")) + scale_linetype_manual(\"Legend\", values=c(\"Mean\"=1, \"Min/Max\"=2))") : " + geom_line()") + | |
| 511 | + ((p.major.smooth || p.minor.smooth) ? (minimalist ? " + stat_summary(geom=\"line\", fun.y=mean)" : " + stat_summary(geom=\"line\", fun.y=min, aes(linetype=\"Min/Max\")) + stat_summary(geom=\"line\", fun.y=max, aes(linetype=\"Min/Max\")) + stat_summary(geom=\"line\", fun.y=mean, aes(linetype=\"Mean\")) + scale_linetype_manual(\"Legend\", values=c(\"Mean\"=1, \"Min/Max\"=2))") : " + geom_line()") + | |
| 511 | 512 | (minimalist ? "" : " + scale_x_log10(labels=c(1,5,10,50,100), breaks=c(1,5,10,50,100)) + annotation_logticks(sides=\"b\")") + |
| 512 | 513 | (p.major.size > 1 ? getScale("colour", p.major.header, p.major.size) : QString()) + |
| 513 | 514 | (p.minor.size > 1 ? QString(" + scale_linetype_discrete(\"%1\")").arg(p.minor.header) : QString()) + |
| 514 | - QString(" + theme_blank() + scale_y_continuous(labels=percent)\n\n"))); | |
| 515 | + QString(" + theme_minimal() + scale_y_continuous(labels=percent)\n\n"))); | |
| 515 | 516 | |
| 516 | 517 | p.file.write(qPrintable(QString("qplot(factor(%1)%2, data=BC, %3").arg(p.major.smooth ? (p.minor.header.isEmpty() ? "Algorithm" : p.minor.header) : p.major.header, (p.major.smooth || p.minor.smooth) ? ", Y" : "", (p.major.smooth || p.minor.smooth) ? "geom=\"boxplot\"" : "geom=\"bar\", position=\"dodge\", weight=Y") + |
| 517 | 518 | (p.major.size > 1 ? QString(", fill=factor(%1)").arg(p.major.header) : QString()) + | ... | ... |
openbr/gui/imageviewer.cpp
| ... | ... | @@ -18,6 +18,7 @@ |
| 18 | 18 | #include <QMutexLocker> |
| 19 | 19 | #include <QSizePolicy> |
| 20 | 20 | #include <QTimer> |
| 21 | +#include <QDebug> | |
| 21 | 22 | |
| 22 | 23 | #include "imageviewer.h" |
| 23 | 24 | |
| ... | ... | @@ -36,6 +37,7 @@ void br::ImageViewer::setDefaultText(const QString &text) |
| 36 | 37 | |
| 37 | 38 | void br::ImageViewer::setImage(const QString &file, bool async) |
| 38 | 39 | { |
| 40 | + QMutexLocker locker(&mutex); | |
| 39 | 41 | if(file.isNull()) src = QImage(); // Gets rid of runtime FileEngine::open warning |
| 40 | 42 | else src = QImage(file); |
| 41 | 43 | updatePixmap(async); |
| ... | ... | @@ -43,12 +45,14 @@ void br::ImageViewer::setImage(const QString &file, bool async) |
| 43 | 45 | |
| 44 | 46 | void br::ImageViewer::setImage(const QImage &image, bool async) |
| 45 | 47 | { |
| 48 | + QMutexLocker locker(&mutex); | |
| 46 | 49 | src = image.copy(); |
| 47 | 50 | updatePixmap(async); |
| 48 | 51 | } |
| 49 | 52 | |
| 50 | 53 | void br::ImageViewer::setImage(const QPixmap &pixmap, bool async) |
| 51 | 54 | { |
| 55 | + QMutexLocker locker(&mutex); | |
| 52 | 56 | src = pixmap.toImage(); |
| 53 | 57 | updatePixmap(async); |
| 54 | 58 | } | ... | ... |
openbr/openbr_export.cpp
| ... | ... | @@ -28,8 +28,10 @@ |
| 28 | 28 | * |
| 29 | 29 | * \section get_started Get Started |
| 30 | 30 | * - \ref installation - \copybrief installation |
| 31 | + * - \ref qmake_integration - \copybrief qmake_integration | |
| 31 | 32 | * |
| 32 | 33 | * \section learn_more Learn More |
| 34 | + * - \ref algorithm_grammar - \copybrief algorithm_grammar | |
| 33 | 35 | * - \ref cli - \copybrief cli |
| 34 | 36 | * - \ref c_sdk - \copybrief c_sdk |
| 35 | 37 | * - \ref cpp_plugin_sdk - \copybrief cpp_plugin_sdk |
| ... | ... | @@ -45,8 +47,7 @@ |
| 45 | 47 | * - \subpage windows_msvc |
| 46 | 48 | * - \subpage windows_mingw |
| 47 | 49 | * - \subpage osx_clang |
| 48 | - * - \subpage linux_gcc | |
| 49 | - * - \subpage linux_icc | |
| 50 | + * - \subpage linux_all | |
| 50 | 51 | * |
| 51 | 52 | * \section installation_from_binary From Binary |
| 52 | 53 | * Pre-compiled releases are not currently provided, but they can be built from source using the instructions above. |
| ... | ... | @@ -58,7 +59,7 @@ |
| 58 | 59 | $ cd bin |
| 59 | 60 | $ export LD_LIBRARY_PATH=../lib:${LD_LIBRARY_PATH} |
| 60 | 61 | $ sudo ldconfig |
| 61 | -$ sudo cp ../share/70-yubikey.rules /etc/udev/rules.d # Only needed if you were given a license dongle. | |
| 62 | +$ sudo cp ../share/openbr/70-yubikey.rules /etc/udev/rules.d # Only needed if you were given a license dongle. | |
| 62 | 63 | \endverbatim |
| 63 | 64 | * \par OS X |
| 64 | 65 | \verbatim |
| ... | ... | @@ -88,17 +89,17 @@ $ br -help |
| 88 | 89 | * -# You will have to register with Microsoft after installation, but it's free. |
| 89 | 90 | * -# Grab any available <a href="http://www.microsoft.com/visualstudio/eng/downloads#d-visual-studio-2012-update">Visual Studio Updates</a>. |
| 90 | 91 | * -# Download and install <a href="http://msdn.microsoft.com/en-us/windows/hardware/hh852363.aspx">Windows 8 SDK</a>. |
| 91 | - * -# <a href="http://www.cmake.org/files/v2.8/cmake-2.8.10.2-win32-x86.exe">Download CMake 2.8.10.2</a> and install. | |
| 92 | + * -# <a href="http://www.cmake.org/files/v2.8/cmake-2.8.10.2-win32-x86.exe">Download and Install CMake 2.8.10.2</a> | |
| 92 | 93 | * -# During installation setup select "add CMake to PATH". |
| 93 | - * -# <a href="http://downloads.sourceforge.net/project/opencvlibrary/opencv-unix/2.4.4/OpenCV-2.4.4.tar.bz2">Download OpenCV 2.4.4</a>. | |
| 94 | + * -# <a href="http://downloads.sourceforge.net/project/opencvlibrary/opencv-unix/2.4.5/opencv-2.4.5.tar.gz">Download OpenCV 2.4.5</a> | |
| 94 | 95 | * -# Consider the free open source program <a href="http://www.7-zip.org/">7-Zip</a> if you need a program to unarchive tarballs. |
| 95 | - * -# Move the "OpenCV-2.4.4" folder to "C:\". | |
| 96 | + * -# Move the "opencv-2.4.5" folder to "C:\". | |
| 96 | 97 | * -# 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: |
| 97 | 98 | * \code |
| 98 | - * $ cd C:\OpenCV-2.4.4 | |
| 99 | + * $ cd C:\opencv-2.4.5 | |
| 99 | 100 | * $ mkdir build-msvc2012 |
| 100 | 101 | * $ cd build-msvc2012 |
| 101 | - * $ cmake -G "NMake Makefiles" -DBUILD_opencv_java=OFF -DBUILD_opencv_world=ON -DBUILD_PERF_TESTS=OFF -DBUILD_TESTS=OFF -DWITH_FFMPEG=OFF -DCMAKE_BUILD_TYPE=Debug .. | |
| 102 | + * $ cmake -G "NMake Makefiles" -DBUILD_PERF_TESTS=OFF -DBUILD_TESTS=OFF -DWITH_FFMPEG=OFF -DCMAKE_BUILD_TYPE=Debug .. | |
| 102 | 103 | * $ nmake |
| 103 | 104 | * $ nmake install |
| 104 | 105 | * $ cmake -DCMAKE_BUILD_TYPE=Release .. |
| ... | ... | @@ -106,19 +107,7 @@ $ br -help |
| 106 | 107 | * $ nmake install |
| 107 | 108 | * $ nmake clean |
| 108 | 109 | * \endcode |
| 109 | - * -# <a href="http://releases.qt-project.org/qt5/5.0.1/single/qt-everywhere-opensource-src-5.0.1.zip">Download Qt 5.0.1</a> and unzip. | |
| 110 | - * -# 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. | |
| 111 | - * -# <a href="http://www.microsoft.com/en-us/download/confirmation.aspx?id=6812">Download Direct X Software Developement Kit</a> and install. | |
| 112 | - * -# From the VS2012 x64 Cross Tools Command Prompt: | |
| 113 | - * \code | |
| 114 | - * $ cd qt-everywhere-opensource-src-5.0.1 | |
| 115 | - * $ configure -prefix C:\Qt\5.0.1\msvc2012 -opensource -confirm-license -nomake examples -nomake tests | |
| 116 | - * $ nmake | |
| 117 | - * $ nmake install | |
| 118 | - * $ cd .. | |
| 119 | - * $ rmdir /Q /S qt-everywhere-opensource-src-5.0.1 | |
| 120 | - * \endcode | |
| 121 | - * -# nmake will take several hours to finish. | |
| 110 | + * -# <a href="http://download.qt-project.org/official_releases/qt/5.0/5.0.2/qt-windows-opensource-5.0.2-msvc2012_64-x64-offline.exe">Download and Install Qt 5.0.2</a> | |
| 122 | 111 | * -# Create a <a href="github.com">GitHub</a> account and follow their instructions for <a href="https://help.github.com/articles/set-up-git">setting up Git</a>. |
| 123 | 112 | * -# Launch "Git Bash" from the Desktop and clone OpenBR: |
| 124 | 113 | * \code |
| ... | ... | @@ -134,50 +123,49 @@ $ br -help |
| 134 | 123 | * $ cd C:\openbr |
| 135 | 124 | * $ mkdir build-msvc2012 |
| 136 | 125 | * $ cd build-msvc2012 |
| 137 | - * $ cmake -G "CodeBlocks - NMake Makefiles" -DCMAKE_PREFIX_PATH="C:/OpenCV-2.4.4/build-msvc2012/install;C:/Qt/5.0.1/msvc2012" -DCMAKE_INSTALL_PREFIX="./install" -DBR_INSTALL_DEPENDENCIES=ON -DCMAKE_BUILD_TYPE=Release .. | |
| 126 | + * $ 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 .. | |
| 138 | 127 | * $ nmake |
| 139 | 128 | * $ nmake install |
| 140 | 129 | * \endcode |
| 141 | 130 | * -# Check out the "install" folder. |
| 142 | 131 | * -# Hack OpenBR! |
| 143 | - * -# <a href="http://releases.qt-project.org/qtcreator/2.6.2/qt-creator-windows-opensource-2.6.2.exe">Download Qt Creator</a> IDE and install. | |
| 144 | 132 | * -# From the VS2012 x64 Cross Tools Command Prompt: |
| 145 | 133 | * \code |
| 146 | - * $ C:\Qt\qtcreator-2.6.2\bin\qtcreator.exe | |
| 134 | + * $ C:\Qt\Qt5.0.2\Tools\QtCreator\bin\qtcreator.exe | |
| 147 | 135 | * \endcode |
| 148 | 136 | * -# From the Qt Creator "Tools" menu select "Options..." |
| 149 | 137 | * -# Under "Kits" select "Desktop (default)" |
| 150 | - * -# For "Compiler:" select "Microsoft Visual C++ Compiler 11.0 (amd64)" and click "OK" | |
| 138 | + * -# For "Compiler:" select "Microsoft Visual C++ Compiler 11.0 (x86_amd64)" and click "OK" | |
| 151 | 139 | * -# From the Qt Creator "File" menu select "Open File or Project...". |
| 152 | 140 | * -# Select "C:\openbr\CMakeLists.txt" then "Open". |
| 153 | - * -# Browse to your prexisting build directory "C:\openbr\build-msvc2012" then select "Next". | |
| 154 | - * -# Clear any text in the "arguments" box then select "Run CMake" then "Finish". | |
| 155 | - * -# You're all set! You can find more information on Qt Creator <a href="http://qt-project.org/doc/qtcreator-2.6/">here</a> if you need. | |
| 141 | + * -# If prompted for the location of CMake, enter "C:\Program Files (x86)\CMake 2.8\bin\cmake.exe". | |
| 142 | + * -# Browse to your pre-existing build directory "C:\openbr\build-msvc2012" then select "Next". | |
| 143 | + * -# Select "Run CMake" then "Finish". | |
| 144 | + * -# You're all set! You can find more information on Qt Creator <a href="http://qt-project.org/doc/qtcreator">here</a> if you need. | |
| 156 | 145 | * -# (Optional) Package OpenBR! |
| 157 | - * -# <a href="http://sourceforge.net/projects/nsis/files/NSIS%202/2.46/nsis-2.46-setup.exe/download?use_mirror=iweb&download=">Download NSIS 2.46</a> and install. | |
| 158 | 146 | * -# From the VS2012 x64 Cross Tools Command Prompt: |
| 159 | 147 | * \code |
| 160 | 148 | * $ cd C:\openbr\build-msvc2012 |
| 161 | - * $ nmake package | |
| 149 | + * $ cpack -G ZIP | |
| 162 | 150 | * \endcode |
| 163 | 151 | */ |
| 164 | 152 | |
| 165 | 153 | /*! |
| 166 | 154 | * \page windows_mingw Windows 7 - MinGW-w64 2.0 - x64 |
| 167 | - * -# <a href="http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/rubenvb/gcc-4.7-release/x86_64-w64-mingw32-gcc-4.7.2-release-win64_rubenvb.7z/download">Download MinGW-w64 GCC 4.7.2</a> and unarchive. | |
| 155 | + * -# <a href="http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/rubenvb/gcc-4.7-release/x86_64-w64-mingw32-gcc-4.7.2-release-win64_rubenvb.7z/download">Download and Unarchive MinGW-w64 GCC 4.7.2</a> | |
| 168 | 156 | * -# Use the free open source program <a href="http://www.7-zip.org/">7-Zip</a> to unarchive. |
| 169 | 157 | * -# Move "x86_64-w64-mingw32-gcc-4.7.2-release-win64_rubenvb\mingw64" to "C:\". |
| 170 | - * -# <a href="http://www.cmake.org/files/v2.8/cmake-2.8.10.2-win32-x86.exe">Download CMake 2.8.10.2</a> and install. | |
| 158 | + * -# <a href="http://www.cmake.org/files/v2.8/cmake-2.8.10.2-win32-x86.exe">Download and Install CMake 2.8.10.2</a> | |
| 171 | 159 | * -# During installation setup select "add CMake to PATH". |
| 172 | - * -# <a href="http://downloads.sourceforge.net/project/opencvlibrary/opencv-unix/2.4.4/OpenCV-2.4.4.tar.bz2">Download OpenCV 2.4.4</a>. | |
| 160 | + * -# <a href="http://downloads.sourceforge.net/project/opencvlibrary/opencv-unix/2.4.5/opencv-2.4.5.tar.gz">Download OpenCV 2.4.5</a> | |
| 173 | 161 | * -# Consider the free open source program <a href="http://www.7-zip.org/">7-Zip</a> if you need a program to unarchive tarballs. |
| 174 | - * -# Move the "OpenCV-2.4.4" folder to "C:\". | |
| 162 | + * -# Move the "opencv-2.4.5" folder to "C:\". | |
| 175 | 163 | * -# From the MinGW-w64 Command Prompt (double-click "C:\mingw64\mingw64env.cmd"): |
| 176 | 164 | * \code |
| 177 | - * $ cd C:\OpenCV-2.4.4 | |
| 165 | + * $ cd C:\opencv-2.4.5 | |
| 178 | 166 | * $ mkdir build-mingw64 |
| 179 | 167 | * $ cd build-mingw64 |
| 180 | - * $ cmake -G "MinGW Makefiles" -DBUILD_opencv_java=OFF -DBUILD_opencv_world=ON -DBUILD_PERF_TESTS=OFF -DBUILD_TESTS=OFF -DWITH_FFMPEG=OFF -DCMAKE_BUILD_TYPE=Debug .. | |
| 168 | + * $ cmake -G "MinGW Makefiles" -DBUILD_PERF_TESTS=OFF -DBUILD_TESTS=OFF -DWITH_FFMPEG=OFF -DCMAKE_BUILD_TYPE=Debug .. | |
| 181 | 169 | * $ mingw32-make |
| 182 | 170 | * $ mingw32-make install |
| 183 | 171 | * $ cmake -DCMAKE_BUILD_TYPE=Release .. |
| ... | ... | @@ -185,17 +173,17 @@ $ br -help |
| 185 | 173 | * $ mingw32-make install |
| 186 | 174 | * $ mingw32-make clean |
| 187 | 175 | * \endcode |
| 188 | - * -# <a href="http://releases.qt-project.org/qt5/5.0.1/single/qt-everywhere-opensource-src-5.0.1.zip">Download Qt 5.0.1</a> and unzip. | |
| 176 | + * -# <a href="http://download.qt-project.org/official_releases/qt/5.0/5.0.2/single/qt-everywhere-opensource-src-5.0.2.zip">Download and Unzip Qt 5.0.2</a> | |
| 189 | 177 | * -# 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. |
| 190 | - * -# <a href="http://www.microsoft.com/en-us/download/confirmation.aspx?id=6812">Download Direct X Software Developement Kit</a> and install. You may also need to install the latest OpenGL drivers from your graphics card manufacturer. | |
| 178 | + * -# <a href="http://www.microsoft.com/en-us/download/confirmation.aspx?id=6812">Download and Install Direct X Software Developement Kit</a>, you may also need to install the latest OpenGL drivers from your graphics card manufacturer. | |
| 191 | 179 | * -# From the MinGW-w64 Command Prompt: |
| 192 | 180 | * \code |
| 193 | - * $ cd qt-everywhere-opensource-src-5.0.1 | |
| 194 | - * $ configure -prefix C:\Qt\5.0.1\mingw64 -opensource -confirm-license -nomake examples -nomake tests -opengl desktop | |
| 181 | + * $ cd qt-everywhere-opensource-src-5.0.2 | |
| 182 | + * $ configure -prefix C:\Qt\Qt5.0.2\5.0.2\mingw64 -opensource -confirm-license -nomake examples -nomake tests -opengl desktop | |
| 195 | 183 | * $ mingw32-make |
| 196 | 184 | * $ mingw32-make install |
| 197 | 185 | * $ cd .. |
| 198 | - * $ rmdir /Q /S qt-everywhere-opensource-src-5.0.1 | |
| 186 | + * $ rmdir /Q /S qt-everywhere-opensource-src-5.0.2 | |
| 199 | 187 | * \endcode |
| 200 | 188 | * -# mingw32-make will take several hours to finish. |
| 201 | 189 | * -# Create a <a href="github.com">GitHub</a> account and follow their instructions for <a href="https://help.github.com/articles/set-up-git">setting up Git</a>. |
| ... | ... | @@ -213,31 +201,30 @@ $ br -help |
| 213 | 201 | * $ cd C:\openbr |
| 214 | 202 | * $ mkdir build-mingw64 |
| 215 | 203 | * $ cd build-mingw64 |
| 216 | - * $ cmake -G "CodeBlocks - MinGW Makefiles" -DCMAKE_RC_COMPILER="C:/mingw64/bin/windres.exe" -DCMAKE_PREFIX_PATH="C:/OpenCV-2.4.4/build-mingw64/install;C:/Qt/5.0.1/mingw64" -DCMAKE_INSTALL_PREFIX="./install" -DBR_INSTALL_DEPENDENCIES=ON -DCMAKE_BUILD_TYPE=Release .. | |
| 204 | + * $ 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 .. | |
| 217 | 205 | * $ mingw32-make |
| 218 | 206 | * $ mingw32-make install |
| 219 | 207 | * \endcode |
| 220 | 208 | * -# Check out the "install" folder. |
| 221 | 209 | * -# Hack OpenBR! |
| 222 | - * -# <a href="http://releases.qt-project.org/qtcreator/2.6.2/qt-creator-windows-opensource-2.6.2.exe">Download Qt Creator</a> IDE and install. | |
| 223 | 210 | * -# From the MinGW-w64 Command Prompt: |
| 224 | 211 | * \code |
| 225 | - * $ "C:\Qt\qtcreator-2.6.2\bin\qtcreator.exe" | |
| 212 | + * $ C:\Qt\Qt5.0.2\Tools\QtCreator\bin\qtcreator.exe | |
| 226 | 213 | * \endcode |
| 227 | 214 | * -# From the Qt Creator "Tools" menu select "Options..." |
| 228 | 215 | * -# Under "Kits" select "Desktop (default)" |
| 229 | - * -# For "Compiler:" select "MinGW (x86 64bit)" and click "OK" | |
| 216 | + * -# For "Compiler:" select "MinGW (x86 64bit in C:\mingw64\bin)" and click "OK" | |
| 230 | 217 | * -# From the Qt Creator "File" menu select "Open File or Project...". |
| 231 | 218 | * -# Select "C:\openbr\CMakeLists.txt" then "Open". |
| 232 | - * -# Browse to your prexisting build directory "C:\openbr\build-mingw64" then select "Next". | |
| 219 | + * -# If prompted for the location of CMake, enter "C:\Program Files (x86)\CMake 2.8\bin\cmake.exe". | |
| 220 | + * -# Browse to your pre-existing build directory "C:\openbr\build-mingw64" then select "Next". | |
| 233 | 221 | * -# Clear any text in the "arguments" box then select "Run CMake" then "Finish". |
| 234 | - * -# You're all set! You can find more information on Qt Creator <a href="http://qt-project.org/doc/qtcreator-2.6/">here</a> if you need. | |
| 222 | + * -# You're all set! You can find more information on Qt Creator <a href="http://qt-project.org/doc/qtcreator">here</a> if you need. | |
| 235 | 223 | * -# (Optional) Package OpenBR! |
| 236 | - * -# <a href="http://sourceforge.net/projects/nsis/files/NSIS%202/2.46/nsis-2.46-setup.exe/download?use_mirror=iweb&download=">Download NSIS 2.46</a> and install. | |
| 237 | 224 | * -# From the MinGW-w64 Command Prompt: |
| 238 | 225 | * \code |
| 239 | 226 | * $ cd C:\openbr\build-mingw64 |
| 240 | - * $ mingw32-make package | |
| 227 | + * $ cpack -G ZIP | |
| 241 | 228 | * \endcode |
| 242 | 229 | */ |
| 243 | 230 | |
| ... | ... | @@ -278,8 +265,7 @@ $ br -help |
| 278 | 265 | * \endcode |
| 279 | 266 | * -# Build OpenBR! |
| 280 | 267 | * \code |
| 281 | - * $ cd openbr | |
| 282 | - * $ mkdir build | |
| 268 | + * $ mkdir build # from the OpenBR root directory | |
| 283 | 269 | * $ cd build |
| 284 | 270 | * $ cmake -DCMAKE_PREFIX_PATH=~/Qt5.0.2/5.0.2/clang_64 -DCMAKE_BUILD_TYPE=Release .. |
| 285 | 271 | * $ make -j4 |
| ... | ... | @@ -292,7 +278,7 @@ $ br -help |
| 292 | 278 | * \endcode |
| 293 | 279 | * -# From the Qt Creator "File" menu select "Open File or Project...". |
| 294 | 280 | * -# Select "openbr/CMakeLists.txt" then "Open". |
| 295 | - * -# Browse to your prexisting build directory "openbr/build" then select "Continue". | |
| 281 | + * -# Browse to your pre-existing build directory "openbr/build" then select "Continue". | |
| 296 | 282 | * -# Select "Run CMake" then "Done". |
| 297 | 283 | * -# You're all set! You can find more information on Qt Creator <a href="http://qt-project.org/doc/qtcreator">here</a> if you need. |
| 298 | 284 | * -# (Optional) Test OpenBR! |
| ... | ... | @@ -305,7 +291,7 @@ $ br -help |
| 305 | 291 | * -# (Optional) Package OpenBR! |
| 306 | 292 | * \code |
| 307 | 293 | * $ cd openbr/build |
| 308 | - * $ cpack -G TGZ | |
| 294 | + * $ sudo cpack -G TGZ | |
| 309 | 295 | * \endcode |
| 310 | 296 | * -# (Optional) Build OpenBR documentation! |
| 311 | 297 | * -# <a href="ftp://ftp.stack.nl/pub/users/dimitri/doxygen-1.8.2.src.tar.gz">Download Doxygen 1.8.2</a> |
| ... | ... | @@ -329,42 +315,33 @@ $ br -help |
| 329 | 315 | */ |
| 330 | 316 | |
| 331 | 317 | /*! |
| 332 | - * \page linux_gcc Ubuntu 12.04 LTS - GCC 4.6.3 - x64 | |
| 333 | - * -# Install GCC 4.6.3. | |
| 318 | + * \page linux_all Ubuntu 13.04 - GCC 4.7.3 or ICC 13.1.1 - x64 | |
| 319 | + * -# Install GCC 4.7.3 | |
| 334 | 320 | * \code |
| 335 | 321 | * $ sudo apt-get update |
| 336 | 322 | * $ sudo apt-get install build-essential |
| 337 | 323 | * \endcode |
| 338 | - * -# <a href="http://www.cmake.org/files/v2.8/cmake-2.8.10.2.tar.gz">Download CMake 2.8.10.2</a>. | |
| 324 | + * -# (Optional) Assuming you meet the eligibility requirements and you want to use ICC instead of GCC, <a href="http://software.intel.com/en-us/non-commercial-software-development">Download and Install Intel C++ Studio XE 2013</a>. | |
| 325 | + * -# Install CMake 2.8.10.1 | |
| 339 | 326 | * \code |
| 340 | - * $ cd ~/Downloads | |
| 341 | - * $ tar -xf cmake-2.8.10.2.tar.gz | |
| 342 | - * $ cd cmake-2.8.10.2 | |
| 343 | - * $ ./configure | |
| 344 | - * $ make -j4 | |
| 345 | - * $ sudo make install | |
| 346 | - * $ cd .. | |
| 347 | - * $ rm -r cmake-2.8.10.2 | |
| 327 | + * $ sudo apt-get install cmake cmake-curses-gui | |
| 348 | 328 | * \endcode |
| 349 | - * -# <a href="http://downloads.sourceforge.net/project/opencvlibrary/opencv-unix/2.4.4/OpenCV-2.4.4.tar.bz2">Download OpenCV 2.4.4</a>. | |
| 329 | + * -# <a href="http://downloads.sourceforge.net/project/opencvlibrary/opencv-unix/2.4.5/opencv-2.4.5.tar.gz">Download OpenCV 2.4.5</a> | |
| 350 | 330 | * \code |
| 351 | 331 | * $ cd ~/Downloads |
| 352 | - * $ tar -xf OpenCV-2.4.4.tar.bz2 | |
| 353 | - * $ cd OpenCV-2.4.4 | |
| 332 | + * $ tar -xf opencv-2.4.5.tar.gz | |
| 333 | + * $ cd opencv-2.4.5 | |
| 354 | 334 | * $ mkdir build |
| 355 | 335 | * $ cd build |
| 356 | - * $ cmake -DBUILD_opencv_java=OFF -DBUILD_opencv_world=ON -DCMAKE_BUILD_TYPE=Release .. | |
| 336 | + * $ cmake -DCMAKE_BUILD_TYPE=Release .. | |
| 357 | 337 | * $ make -j4 |
| 358 | 338 | * $ sudo make install |
| 359 | 339 | * $ cd ../.. |
| 360 | - * $ rm -r OpenCV-2.4.4 | |
| 340 | + * $ rm -rf opencv-2.4.5* | |
| 361 | 341 | * \endcode |
| 362 | - * -# <a href="http://releases.qt-project.org/qt5/5.0.1/qt-linux-opensource-5.0.1-x86_64-offline.run">Download Qt 5.0.1</a>. | |
| 342 | + * -# Install Qt 5.0.1 | |
| 363 | 343 | * \code |
| 364 | - * $ cd ~/Downloads | |
| 365 | - * $ chmod +x qt-linux-opensource-5.0.1-x86_64-offline.run | |
| 366 | - * $ ./qt-linux-opensource-5.0.1-x86_64-offline.run | |
| 367 | - * $ rm qt-linux-opensource-5.0.1-x86_64-offline.run | |
| 344 | + * $ sudo apt-get install qt5-default libqt5svg5-dev qtcreator | |
| 368 | 345 | * \endcode |
| 369 | 346 | * -# Create a <a href="github.com">GitHub</a> account, follow their instructions for <a href="https://help.github.com/articles/set-up-git">setting up Git</a>. |
| 370 | 347 | * \code |
| ... | ... | @@ -375,98 +352,117 @@ $ br -help |
| 375 | 352 | * \endcode |
| 376 | 353 | * -# Build OpenBR! |
| 377 | 354 | * \code |
| 378 | - * $ cd openbr | |
| 379 | - * $ mkdir build | |
| 355 | + * $ mkdir build # from the OpenBR root directory | |
| 380 | 356 | * $ cd build |
| 381 | - * $ cmake -DCMAKE_PREFIX_PATH=~/Qt5.0.1/5.0.1/gcc_64 -DCMAKE_BUILD_TYPE=Release .. | |
| 357 | + * $ cmake -DCMAKE_BUILD_TYPE=Release .. # GCC Only | |
| 358 | + * $ cmake -DCMAKE_C_COMPILER=/opt/intel/bin/icc -DCMAKE_CXX_COMPILER=/opt/intel/bin/icpc -DCMAKE_BUILD_TYPE=Release .. # ICC Only | |
| 382 | 359 | * $ make -j4 |
| 383 | 360 | * $ sudo make install |
| 384 | 361 | * \endcode |
| 385 | 362 | * -# Hack OpenBR! |
| 386 | 363 | * -# Open Qt Creator IDE |
| 387 | 364 | * \code |
| 388 | - * $ ~/Qt5.0.1/Tools/QtCreator/bin/qtcreator & | |
| 365 | + * $ qtcreator & | |
| 389 | 366 | * \endcode |
| 390 | 367 | * -# From the Qt Creator "File" menu select "Open File or Project...". |
| 391 | - * -# Select "~/openbr/CMakeLists.txt" then "Open". | |
| 392 | - * -# Browse to your prexisting build directory "~/openbr/build" then select "Next". | |
| 368 | + * -# Select "openbr/CMakeLists.txt" then "Open". | |
| 369 | + * -# Browse to your pre-existing build directory "openbr/build" then select "Next". | |
| 393 | 370 | * -# Select "Run CMake" then "Finish". |
| 394 | - * -# You're all set! You can find more information on Qt Creator <a href="http://qt-project.org/doc/qtcreator-2.6/">here</a> if you need. | |
| 395 | - * -# (Optional) Package OpenBR! | |
| 396 | - * \code | |
| 397 | - * $ cd openbr/build | |
| 398 | - * $ make package | |
| 399 | - * \endcode | |
| 400 | - */ | |
| 401 | - | |
| 402 | -/*! | |
| 403 | - * \page linux_icc Ubuntu 12.04 LTS - Intel C++ Studio XE 2013 - x64 | |
| 404 | - * -# Assuming you meet the eligibility requirements, <a href="http://software.intel.com/en-us/non-commercial-software-development">Download Intel C++ Studio XE 2013</a> and install. | |
| 405 | - * -# <a href="http://www.cmake.org/files/v2.8/cmake-2.8.10.2.tar.gz">Download CMake 2.8.10.2</a>. | |
| 406 | - * \code | |
| 407 | - * $ cd ~/Downloads | |
| 408 | - * $ tar -xf cmake-2.8.10.2.tar.gz | |
| 409 | - * $ cd cmake-2.8.10.2 | |
| 410 | - * $ ./configure | |
| 411 | - * $ make -j4 | |
| 412 | - * $ sudo make install | |
| 413 | - * $ cd .. | |
| 414 | - * $ rm -r cmake-2.8.10.2 | |
| 415 | - * \endcode | |
| 416 | - * -# <a href="http://downloads.sourceforge.net/project/opencvlibrary/opencv-unix/2.4.4/OpenCV-2.4.4.tar.bz2">Download OpenCV 2.4.4</a>. | |
| 417 | - * \code | |
| 418 | - * $ cd ~/Downloads | |
| 419 | - * $ tar -xf OpenCV-2.4.4.tar.bz2 | |
| 420 | - * $ cd OpenCV-2.4.4 | |
| 421 | - * $ mkdir build | |
| 422 | - * $ cd build | |
| 423 | - * $ cmake cmake -DBUILD_opencv_java=OFF -DBUILD_opencv_world=ON -DCMAKE_BUILD_TYPE=Release .. | |
| 424 | - * $ make -j4 | |
| 425 | - * $ sudo make install | |
| 426 | - * $ cd ../.. | |
| 427 | - * $ rm -r OpenCV-2.4.4 | |
| 428 | - * \endcode | |
| 429 | - * -# <a href="http://releases.qt-project.org/qt5/5.0.1/qt-linux-opensource-5.0.1-x86_64-offline.run">Download Qt 5.0.1</a>. | |
| 430 | - * \code | |
| 431 | - * $ cd ~/Downloads | |
| 432 | - * $ chmod +x qt-linux-opensource-5.0.1-x86_64-offline.run | |
| 433 | - * $ ./qt-linux-opensource-5.0.1-x86_64-offline.run | |
| 434 | - * $ rm qt-linux-opensource-5.0.1-x86_64-offline.run | |
| 435 | - * \endcode | |
| 436 | - * -# Create a <a href="github.com">GitHub</a> account, follow their instructions for <a href="https://help.github.com/articles/set-up-git">setting up Git</a>. | |
| 371 | + * -# You're all set! You can find more information on Qt Creator <a href="http://qt-project.org/doc/qtcreator">here</a> if you need. | |
| 372 | + * -# (Optional) Test OpenBR! | |
| 437 | 373 | * \code |
| 438 | - * $ git clone https://github.com/biometrics/openbr.git | |
| 439 | - * $ cd openbr | |
| 440 | - * $ git submodule init | |
| 441 | - * $ git submodule update | |
| 374 | + * $ cd openbr/scripts | |
| 375 | + * $ ./downloadDatasets.sh | |
| 376 | + * $ cd ../build | |
| 377 | + * $ make test | |
| 442 | 378 | * \endcode |
| 443 | - * -# Build OpenBR! | |
| 379 | + * -# (Optional) Package OpenBR! | |
| 444 | 380 | * \code |
| 445 | - * $ cd openbr | |
| 446 | - * $ mkdir build-icc | |
| 447 | - * $ cd build-icc | |
| 448 | - * $ cmake -DCMAKE_C_COMPILER=/opt/intel/bin/icc -DCMAKE_CXX_COMPILER=/opt/intel/bin/icpc -DCMAKE_PREFIX_PATH=~/Qt5.0.1/5.0.1/gcc_64 -DCMAKE_BUILD_TYPE=Release .. | |
| 449 | - * $ make -j4 | |
| 450 | - * $ sudo make install | |
| 381 | + * $ cd openbr/build | |
| 382 | + * $ sudo cpack -G TGZ | |
| 451 | 383 | * \endcode |
| 452 | - * -# Hack OpenBR! | |
| 453 | - * -# Open Qt Creator IDE | |
| 454 | - * \code | |
| 455 | - * $ ~/Qt5.0.1/Tools/QtCreator/bin/qtcreator & | |
| 456 | - * \endcode | |
| 457 | - * -# From the Qt Creator "File" menu select "Open File or Project...". | |
| 458 | - * -# Select "~/openbr/CMakeLists.txt" then "Open". | |
| 459 | - * -# Browse to your prexisting build directory "~/openbr/build" then select "Next". | |
| 460 | - * -# Select "Run CMake" then "Finish". | |
| 461 | - * -# You're all set! You can find more information on Qt Creator <a href="http://qt-project.org/doc/qtcreator-2.6/">here</a> if you need. | |
| 462 | - * -# (Optional) Package OpenBR! | |
| 384 | + * -# (Optional) Build OpenBR documentation! | |
| 463 | 385 | * \code |
| 386 | + * $ sudo apt-get install doxygen | |
| 464 | 387 | * $ cd openbr/build |
| 465 | - * $ make package | |
| 388 | + * $ cmake -DBR_BUILD_DOCUMENTATION=ON .. | |
| 389 | + * $ make -j4 | |
| 390 | + * $ sudo apt-get install libgnome2-bin | |
| 391 | + * $ gnome-open html/index.html | |
| 466 | 392 | * \endcode |
| 467 | 393 | */ |
| 468 | 394 | |
| 469 | 395 | /*! |
| 396 | + * \page qmake_integration QMake Integration | |
| 397 | + * \brief Add OpenBR to your Qt <tt>.pro</tt> project. | |
| 398 | + * | |
| 399 | + * After completing the \ref installation instructions, try launching Qt Creator and opening <tt>\<path_to_openbr_installation\>/share/openbr/qmake_tutorial/hello.pro</tt>. | |
| 400 | + * | |
| 401 | + * Happy hacking! | |
| 402 | + */ | |
| 403 | + | |
| 404 | +/*! | |
| 405 | + * \page algorithm_grammar Algorithm Grammar | |
| 406 | + * \brief How algorithms are constructed from string descriptions. | |
| 407 | + * | |
| 408 | + * <b>So you've run <tt>scripts/helloWorld.sh</tt> and it generally makes sense, except you have no idea what <tt>'Open+Cvt(Gray)+Cascade(FrontalFace)+ASEFEyes+Affine(128,128,0.33,0.45)+CvtFloat+PCA(0.95):Dist(L2)'</tt> means or how it is executed.</b> | |
| 409 | + * Well if this is the case, you've found the right documentation. | |
| 410 | + * Let's get started! | |
| 411 | + * | |
| 412 | + * In OpenBR an <i>algorithm</i> is a technique for enrolling templates associated with a technique for comparing them. | |
| 413 | + * Recall that our ultimate goal is to be able to say how similar two face images are (or two fingerprints, irises, etc.). | |
| 414 | + * Instead of storing the entire raw image for comparison, it is common practice to store an optimized representation, or <i>template</i>, of the image for the task at hand. | |
| 415 | + * The process of generating this optimized representatation is called <i>template enrollment</i> or <i>template generation</i>. | |
| 416 | + * Given two templates, <i>template comparison</i> computes the similarity between them, where the higher values indicate more probable matches and the threshold for determining what constitutes an adaquate match is determined operationally. | |
| 417 | + * The goal of template generation is to design templates that are small, accurate, and fast to compare. | |
| 418 | + * Ok, you probably knew all of this already, let's move on. | |
| 419 | + * | |
| 420 | + * The only way of creating an algorithm in OpenBR is from a text string that describes it. | |
| 421 | + * We call this string the <i>algorithm description</i>. | |
| 422 | + * The algorithm description is seperated into two parts by a ':', with the left hand side indicating how to generate templates and the right hand side indicating how to compare them. | |
| 423 | + * Some algorithms, like \ref cpp_gender_estimation and \ref cpp_age_estimation are <i>classifiers</i> that don't create templates. | |
| 424 | + * In these cases, the colon and the template comparison technique can be omitted from the algorithm description. | |
| 425 | + * | |
| 426 | + * There are several motivations for mandating that algorithms are defined from these strings, here are the most important: | |
| 427 | + * -# It ensures good software development practices by forcibly decoupling the development of each step in an algorithm, facilitating the modification of algorithms and the re-use of individual steps. | |
| 428 | + * -# It spares the creation and maintainance of a lot of very similar header files that would otherwise be needed for each step in an algorithm, observe the abscence of headers in <tt>openbr/plugins</tt>. | |
| 429 | + * -# It allows for algorithm parameter tuning without recompiling. | |
| 430 | + * -# It is completely unambiguous, both the OpenBR interpreter and anyone familiar with the project can understand exactly what your algorithm does just from this description. | |
| 431 | + * | |
| 432 | + * Let's look at some of the important parts of the code base that make this possible! | |
| 433 | + * | |
| 434 | + * In <tt>AlgorithmCore::init()</tt> in <tt>openbr/core/core.cpp</tt> you can see the code for splitting the algorithm description at the colon: | |
| 435 | + * \snippet openbr/core/core.cpp Parsing the algorithm description | |
| 436 | + * | |
| 437 | + * Shortly thereafter in this function we <i>make</i> the template generation and comparison methods: | |
| 438 | + * \snippet openbr/core/core.cpp Creating the template generation and comparison methods | |
| 439 | + * These make calls are defined in the public \ref cpp_plugin_sdk and can also be called from end user code. | |
| 440 | + * | |
| 441 | + * Below we discuss some of the source code for \ref br::Transform::make in <tt>openbr/openbr_plugin.cpp</tt>. | |
| 442 | + * Note, \ref br::Distance::make is similar in spirit and will not be covered. | |
| 443 | + * | |
| 444 | + * One of the first steps when converting the template enrollment description into a \ref br::Transform is to replace the operators, like '+', with their full form: | |
| 445 | + * \snippet openbr/openbr_plugin.cpp Make a pipe | |
| 446 | + * A pipe (see \ref br::PipeTransform in <tt>openbr/plugins/meta.cpp</tt>) is the standard way of chaining together multiple steps in series to form more sophisticated algorithms. | |
| 447 | + * PipeTransform takes a list of transforms, and <i>projects</i> templates through each transform in order. | |
| 448 | + * | |
| 449 | + * After operator expansion, the template enrollment description forms a tree, and the transform is constructed from this description starting recurively starting at the root of the tree: | |
| 450 | + * \snippet openbr/openbr_plugin.cpp Construct the root transform | |
| 451 | + * | |
| 452 | + * At this point we reach arguably the most important code in the entire framework, the <i>object factory</i> in <tt>openbr/openbr_plugin.h</tt>. | |
| 453 | + * The \ref br::Factory class is responsible for constructing an object from a string: | |
| 454 | + * \snippet openbr/openbr_plugin.h Factory make | |
| 455 | + * | |
| 456 | + * Going back to our original example, a \ref br::PipeTransform will be created with \ref br::OpenTransform, \ref br::CvtTransform, \ref br::CascadeTransform, \ref br::ASEFEyesTransform, \ref br::AffineTransform, \ref br::CvtFloatTransform, and \ref br::PCATransform as its children. | |
| 457 | + * If you want all the tedious details about what exactly this algoritm does, then you should read the \ref br::Transform::project function implemented by each of these plugins. | |
| 458 | + * The brief explanation is that it <i>reads the image from disk, converts it to grayscale, runs the face detector, runs the eye detector on any detected faces, uses the eye locations to normalize the face for rotation and scale, converts to floating point format, and then embeds it in a PCA subspaced trained on face images</i>. | |
| 459 | + * If you are familiar with face recognition, you will likely recognize this as the Eigenfaces \cite turk1991eigenfaces algorithm. | |
| 460 | + * | |
| 461 | + * As a final note, the Eigenfaces algorithms uses the Euclidean distance (or L2-norm) to compare templates. | |
| 462 | + * Since OpenBR expects <i>similarity</i> values when comparing templates, and not <i>distances</i>, \ref br::DistDistance will return <i>-log(distance+1)</i> so that larger values indicate more similarity. | |
| 463 | + */ | |
| 464 | + | |
| 465 | +/*! | |
| 470 | 466 | * \page bee Biometric Evaluation Environment |
| 471 | 467 | * \brief The <i>Biometric Evaluation Environment</i> (BEE) is a <a href="http://www.nist.gov/index.html">NIST</a> standard for evaluating biometric algorithms. |
| 472 | 468 | * | ... | ... |
openbr/openbr_plugin.cpp
| ... | ... | @@ -1098,11 +1098,13 @@ Transform *Transform::make(QString str, QObject *parent) |
| 1098 | 1098 | str.replace("!","+Expand+"); |
| 1099 | 1099 | } |
| 1100 | 1100 | |
| 1101 | + //! [Make a pipe] | |
| 1101 | 1102 | { // Check for use of '+' as shorthand for Pipe(...) |
| 1102 | 1103 | QStringList words = parse(str, '+'); |
| 1103 | 1104 | if (words.size() > 1) |
| 1104 | 1105 | return make("Pipe([" + words.join(",") + "])", parent); |
| 1105 | 1106 | } |
| 1107 | + //! [Make a pipe] | |
| 1106 | 1108 | |
| 1107 | 1109 | { // Check for use of '/' as shorthand for Fork(...) |
| 1108 | 1110 | QStringList words = parse(str, '/'); |
| ... | ... | @@ -1122,8 +1124,9 @@ Transform *Transform::make(QString str, QObject *parent) |
| 1122 | 1124 | if (str.startsWith('(') && str.endsWith(')')) |
| 1123 | 1125 | return make(str.mid(1, str.size()-2), parent); |
| 1124 | 1126 | |
| 1125 | - File f = "." + str; | |
| 1126 | - Transform *transform = Factory<Transform>::make(f); | |
| 1127 | + //! [Construct the root transform] | |
| 1128 | + Transform *transform = Factory<Transform>::make("." + str); | |
| 1129 | + //! [Construct the root transform] | |
| 1127 | 1130 | |
| 1128 | 1131 | if (transform->independent) { |
| 1129 | 1132 | File independent(".Independent"); | ... | ... |
openbr/openbr_plugin.h
| ... | ... | @@ -811,6 +811,7 @@ struct Factory |
| 811 | 811 | /*! |
| 812 | 812 | * \brief Constructs a plugin from a file. |
| 813 | 813 | */ |
| 814 | + //! [Factory make] | |
| 814 | 815 | static T *make(const File &file) |
| 815 | 816 | { |
| 816 | 817 | QString name = file.suffix(); |
| ... | ... | @@ -819,11 +820,11 @@ struct Factory |
| 819 | 820 | else if (names().contains("Default")) name = "Default"; |
| 820 | 821 | else qFatal("%s registry does not contain object named: %s", qPrintable(baseClassName()), qPrintable(name)); |
| 821 | 822 | } |
| 822 | - if (registry->contains("_"+name)) name.prepend('_'); // Hook to override with "native" implementation | |
| 823 | 823 | T *object = registry->value(name)->_make(); |
| 824 | 824 | object->init(file); |
| 825 | 825 | return object; |
| 826 | 826 | } |
| 827 | + //! [Factory make] | |
| 827 | 828 | |
| 828 | 829 | /*! |
| 829 | 830 | * \brief Constructs all the available plugins. | ... | ... |
openbr/plugins/eigen3.cmake
| ... | ... | @@ -3,5 +3,5 @@ set(BR_WITH_EIGEN3 ON CACHE BOOL "Build Eigen3 plugins") |
| 3 | 3 | if(${BR_WITH_EIGEN3}) |
| 4 | 4 | find_package(Eigen3 REQUIRED) |
| 5 | 5 | set(BR_THIRDPARTY_SRC ${BR_THIRDPARTY_SRC} plugins/eigen3.cpp) |
| 6 | - install(FILES ${EIGEN3_LICENSE} RENAME Eigen3.license DESTINATION .) | |
| 6 | + install(FILES ${EIGEN3_LICENSE} RENAME Eigen3 DESTINATION share/openbr/licenses) | |
| 7 | 7 | endif() | ... | ... |
openbr/plugins/mongoose.cmake
| ... | ... | @@ -2,5 +2,5 @@ set(BR_WITH_MONGOOSE OFF CACHE BOOL "Build with Mongoose") |
| 2 | 2 | if(${BR_WITH_MONGOOSE}) |
| 3 | 3 | find_package(Mongoose) |
| 4 | 4 | set(BR_THIRDPARTY_SRC ${BR_THIRDPARTY_SRC} plugins/mongoose.cpp ${MONGOOSE_SRC}) |
| 5 | - install(FILES ${MONGOOSE_LICENSE} RENAME mongoose.license DESTINATION .) | |
| 5 | + install(FILES ${MONGOOSE_LICENSE} RENAME mongoose DESTINATION share/openbr/licenses) | |
| 6 | 6 | endif() | ... | ... |
openbr/plugins/nec3.cmake deleted
openbr/plugins/nec3.cpp deleted
| 1 | -#ifdef WIN32 | |
| 2 | -#include <windows.h> | |
| 3 | -#endif | |
| 4 | - | |
| 5 | -#include <NeoFacePro.h> | |
| 6 | - | |
| 7 | -#include "openbr_internal.h" | |
| 8 | -#include "openbr/core/resource.h" | |
| 9 | - | |
| 10 | -using namespace br; | |
| 11 | - | |
| 12 | -/*! | |
| 13 | - * \ingroup initializers | |
| 14 | - * \brief Initialize NEC3 | |
| 15 | - * \author Josh Klontz \cite jklontz | |
| 16 | - * \author Scott Klum \cite sklum | |
| 17 | - * \warning Needs a maintainer | |
| 18 | - */ | |
| 19 | -class NEC3Initializer : public Initializer | |
| 20 | -{ | |
| 21 | - Q_OBJECT | |
| 22 | - | |
| 23 | - void initialize() const | |
| 24 | - { | |
| 25 | - int result = NeoFacePro::Initialize(); | |
| 26 | - if (result != NFP_SUCCESS) qWarning("NEC3 Initialize error [%d]", result); | |
| 27 | - Globals->abbreviations.insert("NEC3", "Open!NEC3Enroll:NEC3Compare"); | |
| 28 | - } | |
| 29 | - | |
| 30 | - void finalize() const | |
| 31 | - { | |
| 32 | - int result = NeoFacePro::Terminate(); | |
| 33 | - if (result != NFP_SUCCESS) qWarning("NEC3 Finalize error [%d]", result); | |
| 34 | - } | |
| 35 | -}; | |
| 36 | - | |
| 37 | -BR_REGISTER(Initializer, NEC3Initializer) | |
| 38 | - | |
| 39 | -/*! | |
| 40 | - * \brief NEC3 Context | |
| 41 | - * \author Scott Klum \cite sklum | |
| 42 | - */ | |
| 43 | - | |
| 44 | -struct NEC3Context | |
| 45 | -{ | |
| 46 | - NeoFacePro::CFaceInfo faceInfo; | |
| 47 | - NeoFacePro::CFaceFeature faceFeature; | |
| 48 | - | |
| 49 | - NEC3Context() { | |
| 50 | - faceInfo.SetParamAlgorithm(NFP_ALGORITHM003); | |
| 51 | - faceInfo.SetParamEyesRoll(15); | |
| 52 | - faceInfo.SetParamEyesMaxWidth(1000); | |
| 53 | - faceInfo.SetParamEyesMinWidth(30); | |
| 54 | - faceInfo.SetParamMaxFace(1); | |
| 55 | - faceInfo.SetParamReliability(0); | |
| 56 | - | |
| 57 | - faceFeature.SetParamFeatureType(NFP_FEATURE_S14); | |
| 58 | - } | |
| 59 | -}; | |
| 60 | - | |
| 61 | -/*! | |
| 62 | - * \ingroup transforms | |
| 63 | - * \brief Enroll a face image in NEC NeoFace 3 | |
| 64 | - * \author Josh Klontz \cite jklontz | |
| 65 | - * \author Scott Klum \cite sklum | |
| 66 | - * \warning Needs a maintainer | |
| 67 | - */ | |
| 68 | -class NEC3Enroll : public UntrainableTransform | |
| 69 | -{ | |
| 70 | - Q_OBJECT | |
| 71 | - Q_PROPERTY(bool detectOnly READ get_detectOnly WRITE set_detectOnly RESET reset_detectOnly STORED false) | |
| 72 | - BR_PROPERTY(bool, detectOnly, false) | |
| 73 | - | |
| 74 | - Resource<NEC3Context> contexts; | |
| 75 | - QSharedPointer<Transform> flip; | |
| 76 | - | |
| 77 | - void init() | |
| 78 | - { | |
| 79 | - contexts.setMaxResources(1); | |
| 80 | - flip = QSharedPointer<Transform>(Transform::make("Flip(X)")); | |
| 81 | - } | |
| 82 | - | |
| 83 | - void project(const Template &src, Template &dst) const | |
| 84 | - { | |
| 85 | - if (src.m().type() != CV_8UC3) qFatal("NEC3Enroll requires 8UC3 images."); | |
| 86 | - | |
| 87 | - // Bitmaps are stored upside down | |
| 88 | - Template flipped; | |
| 89 | - flip->project(src, flipped); | |
| 90 | - | |
| 91 | - cv::Mat input = flipped.m(); | |
| 92 | - input = input(cv::Rect(0, 0, (input.cols/4)*4, (input.rows/4)*4)).clone(); // For whatever reason, NEC requires images with 4 pixel alignment... | |
| 93 | - | |
| 94 | - BITMAPINFO binfo; | |
| 95 | - binfo.bmiHeader.biWidth = input.cols; | |
| 96 | - binfo.bmiHeader.biHeight = input.rows; | |
| 97 | - binfo.bmiHeader.biBitCount = 24; | |
| 98 | - | |
| 99 | - NEC3Context *context = contexts.acquire(); | |
| 100 | - int result = context->faceInfo.FindFace(binfo, input.data); | |
| 101 | - context->faceInfo.LocateEyes(); | |
| 102 | - | |
| 103 | - if (result == NFP_CANNOT_FIND_FACE) { | |
| 104 | - if (Globals->verbose) qDebug("NEC3Enroll face not found for file %s", qPrintable(src.file.flat())); | |
| 105 | - } else if (result != NFP_SUCCESS) { | |
| 106 | - qWarning("NEC3Enroll FindFace error %d for file %s", result, qPrintable(src.file.flat())); | |
| 107 | - } | |
| 108 | - | |
| 109 | - QList<QPointF> landmarks; | |
| 110 | - for (int i=0; i<context->faceInfo.GetFaceMax(); i++) { | |
| 111 | - if (context->faceInfo.SetFaceIndex(i) != NFP_SUCCESS) | |
| 112 | - continue; | |
| 113 | - POINT right = context->faceInfo.GetRightEye(); | |
| 114 | - POINT left = context->faceInfo.GetLeftEye(); | |
| 115 | - landmarks.append(QPointF(right.x, right.y)); | |
| 116 | - landmarks.append(QPointF(left.x, left.y)); | |
| 117 | - | |
| 118 | - if (detectOnly) { | |
| 119 | - dst += src.m(); | |
| 120 | - } else { | |
| 121 | - result = context->faceFeature.SetFeature(&context->faceInfo); | |
| 122 | - if (result != NFP_SUCCESS) { | |
| 123 | - qWarning("NEC3Enroll SetFeature error %d for file %s", result, qPrintable(src.file.flat())); | |
| 124 | - continue; | |
| 125 | - } | |
| 126 | - | |
| 127 | - void *data; | |
| 128 | - long size; | |
| 129 | - result = context->faceFeature.Serialize(&data, &size); | |
| 130 | - if (result != NFP_SUCCESS) { | |
| 131 | - qWarning("NEC3Enroll Serialize error %d for file %s", result, qPrintable(src.file.flat())); | |
| 132 | - continue; | |
| 133 | - } | |
| 134 | - | |
| 135 | - dst += cv::Mat(1, size, CV_8UC1, data).clone(); | |
| 136 | - NeoFacePro::CFaceFeature::FreeSerializeData(data); | |
| 137 | - } | |
| 138 | - | |
| 139 | - if (src.file.get<bool>("ForceEnrollment", false) && !dst.isEmpty()) break; | |
| 140 | - } | |
| 141 | - dst.file.appendPoints(landmarks); | |
| 142 | - | |
| 143 | - contexts.release(context); | |
| 144 | - | |
| 145 | - if (!src.file.get<bool>("enrollAll", false) && dst.isEmpty()) dst += cv::Mat(); | |
| 146 | - } | |
| 147 | -}; | |
| 148 | - | |
| 149 | -BR_REGISTER(Transform, NEC3Enroll) | |
| 150 | - | |
| 151 | -/*! | |
| 152 | - * \ingroup distances | |
| 153 | - * \brief Compare faces with NEC NeoFace 3 SDK | |
| 154 | - * \author Josh Klontz \cite jklontz | |
| 155 | - * \author Scott Klum \cite sklum | |
| 156 | - * \warning Needs a maintainer | |
| 157 | - */ | |
| 158 | -class NEC3Compare : public Distance | |
| 159 | -{ | |
| 160 | - Q_OBJECT | |
| 161 | - | |
| 162 | - Resource<NeoFacePro::CVerifier> verifierResource; | |
| 163 | - | |
| 164 | - float compare(const Template &a, const Template &b) const | |
| 165 | - { | |
| 166 | - float score = -std::numeric_limits<float>::max(); | |
| 167 | - if (a.m().data && b.m().data) { | |
| 168 | - NeoFacePro::CVerifier *verifier = verifierResource.acquire(); | |
| 169 | - int result = verifier->Verify(a.m().data, b.m().data, &score); | |
| 170 | - if (result != NFP_SUCCESS) qWarning("NEC3Compare verify error [%d]", result); | |
| 171 | - verifierResource.release(verifier); | |
| 172 | - } | |
| 173 | - return score; | |
| 174 | - } | |
| 175 | -}; | |
| 176 | - | |
| 177 | -BR_REGISTER(Distance, NEC3Compare) | |
| 178 | - | |
| 179 | -#include "nec3.moc" |
openbr/plugins/neclatent1.cmake deleted
| 1 | -set(BR_WITH_NECLATENT1 OFF CACHE BOOL "Build with NEC Latent SDK 1") | |
| 2 | - | |
| 3 | -if(${BR_WITH_NECLATENT1}) | |
| 4 | - find_package(NECLATENT1 REQUIRED) | |
| 5 | - set(BR_THIRDPARTY_SRC ${BR_THIRDPARTY_SRC} plugins/neclatent1.cpp) | |
| 6 | - set(BR_THIRDPARTY_LIBS ${BR_THIRDPARTY_LIBS} ${NECLATENT1_LIBS}) | |
| 7 | - install(DIRECTORY ${NECLATENT1_BIN_DIR}/ DESTINATION bin) | |
| 8 | -endif() |
openbr/plugins/neclatent1.cpp deleted
| 1 | -#include <LatentEFS.h> | |
| 2 | - | |
| 3 | -#include "openbr_internal.h" | |
| 4 | - | |
| 5 | -// Necessary to allocate a large memory though the actual template size may be much smaller | |
| 6 | -#define MAX_TEMPLATE_SIZE 400000 | |
| 7 | - | |
| 8 | -namespace br | |
| 9 | -{ | |
| 10 | - | |
| 11 | -/*! | |
| 12 | - * \ingroup initializers | |
| 13 | - * \brief Initialize the NEC Latent SDK wrapper. | |
| 14 | - * \author Josh Klontz \cite jklontz | |
| 15 | - */ | |
| 16 | -class NECLatent1Initialier : public Initializer | |
| 17 | -{ | |
| 18 | - Q_OBJECT | |
| 19 | - | |
| 20 | - void initialize() const | |
| 21 | - { | |
| 22 | - Globals->abbreviations.insert("NECTenprintLFML", "Open+Cvt(Gray)+NECLatent1Enroll(false,LFML):NECLatent1Compare(LFML)"); | |
| 23 | - Globals->abbreviations.insert("NECTenprintELFT", "Open+Cvt(Gray)+NECLatent1Enroll(false,ELFT):NECLatent1Compare(ELFT)"); | |
| 24 | - Globals->abbreviations.insert("NECTenprintELFTM", "Open+Cvt(Gray)+NECLatent1Enroll(false,ELFT_M):NECLatent1Compare(ELFT_M)"); | |
| 25 | - Globals->abbreviations.insert("NECLatentLFML", "Open+Cvt(Gray)+NECLatent1Enroll(true,LFML):NECLatent1Compare(LFML)"); | |
| 26 | - Globals->abbreviations.insert("NECLatentELFT", "Open+Cvt(Gray)+NECLatent1Enroll(true,ELFT):NECLatent1Compare(ELFT)"); | |
| 27 | - Globals->abbreviations.insert("NECLatentELFTM", "Open+NECLatent1Enroll(true,ELFT_M):NECLatent1Compare(ELFT_M)"); | |
| 28 | - } | |
| 29 | -}; | |
| 30 | - | |
| 31 | -BR_REGISTER(Initializer, NECLatent1Initialier) | |
| 32 | - | |
| 33 | -/*! | |
| 34 | - * \ingroup transforms | |
| 35 | - * \brief Enroll an NEC latent fingerprint. | |
| 36 | - * \author Josh Klontz \cite jklontz | |
| 37 | - * \warning Applications using this transform must have their working directory be the 'bin/win/32' folder of the NEC Latent SDK. | |
| 38 | - */ | |
| 39 | -class NECLatent1EnrollTransform : public UntrainableTransform | |
| 40 | -{ | |
| 41 | - Q_OBJECT | |
| 42 | - Q_ENUMS(Algorithm) | |
| 43 | - Q_PROPERTY(bool latent READ get_latent WRITE set_latent RESET reset_latent STORED false) | |
| 44 | - Q_PROPERTY(Algorithm algorithm READ get_algorithm WRITE set_algorithm RESET reset_algorithm STORED false) | |
| 45 | - | |
| 46 | -public: | |
| 47 | - enum Algorithm { LFML, | |
| 48 | - ELFT, | |
| 49 | - ELFT_M }; | |
| 50 | - | |
| 51 | -private: | |
| 52 | - BR_PROPERTY(bool, latent, false) | |
| 53 | - BR_PROPERTY(Algorithm, algorithm, LFML) | |
| 54 | - | |
| 55 | - void project(const Template &src, Template &dst) const | |
| 56 | - { | |
| 57 | - static QMutex mutex; | |
| 58 | - QMutexLocker locker(&mutex); // It seems that most of the API is not reentrant | |
| 59 | - | |
| 60 | - if (src.m().type() != CV_8UC1) qFatal("Requires 8UC1 data!"); | |
| 61 | - uchar *data = src.m().data; | |
| 62 | - const int rows = src.m().rows; | |
| 63 | - const int columns = src.m().cols; | |
| 64 | - | |
| 65 | - uchar buff[MAX_TEMPLATE_SIZE]; | |
| 66 | - uchar* pBuff = NULL; | |
| 67 | - int size, error; | |
| 68 | - if (latent) { | |
| 69 | - if (algorithm == LFML) error = NEC_LFML_ExtractLatent(data, rows, columns, 500, buff, &size); | |
| 70 | - else if (algorithm == ELFT) error = NEC_ELFT_ExtractLatent(data, rows, columns, 500, 32, buff, &size); | |
| 71 | - else error = NEC_ELFT_M_ExtractLatent(data, columns, 5, &pBuff, &size); | |
| 72 | - } else { | |
| 73 | - if (algorithm == LFML) error = NEC_LFML_ExtractTenprint(data, rows, columns, 500, buff, &size); | |
| 74 | - else if (algorithm == ELFT) error = NEC_ELFT_ExtractTenprint(data, rows, columns, 500, 8, buff, &size); | |
| 75 | - else error = NEC_ELFT_M_ExtractTenprint(data, rows, columns, 500, 5, &pBuff, &size); | |
| 76 | - } | |
| 77 | - | |
| 78 | - if (!error) { | |
| 79 | - cv::Mat n(1, size, CV_8UC1); | |
| 80 | - memcpy(n.data, pBuff ? pBuff : buff, size); | |
| 81 | - dst.m() = n; | |
| 82 | - } else { | |
| 83 | - qWarning("NECLatent1EnrollTransform error %d for file %s.", error, qPrintable(src.file.flat())); | |
| 84 | - dst.m() = cv::Mat(); | |
| 85 | - dst.file.set("FTE", true); | |
| 86 | - } | |
| 87 | - | |
| 88 | - if (pBuff != NULL) NEC_ELFT_M_FreeTemplate(&pBuff); | |
| 89 | - } | |
| 90 | -}; | |
| 91 | - | |
| 92 | -BR_REGISTER(Transform, NECLatent1EnrollTransform) | |
| 93 | - | |
| 94 | -/*! | |
| 95 | - * \ingroup distances | |
| 96 | - * \brief Compare two NEC latent fingerprints | |
| 97 | - * \author Josh Klontz \cite jklontz | |
| 98 | - */ | |
| 99 | -class NECLatent1CompareDistance : public Distance | |
| 100 | -{ | |
| 101 | - Q_OBJECT | |
| 102 | - Q_ENUMS(Algorithm) | |
| 103 | - Q_PROPERTY(Algorithm algorithm READ get_algorithm WRITE set_algorithm RESET reset_algorithm STORED false) | |
| 104 | - | |
| 105 | -public: | |
| 106 | - enum Algorithm { LFML, | |
| 107 | - ELFT, | |
| 108 | - ELFT_M }; | |
| 109 | - | |
| 110 | -private: | |
| 111 | - BR_PROPERTY(Algorithm, algorithm, LFML) | |
| 112 | - | |
| 113 | - float compare(const Template &a, const Template &b) const | |
| 114 | - { | |
| 115 | - uchar *aData = a.m().data; | |
| 116 | - uchar *bData = b.m().data; | |
| 117 | - if (!a.m().data || !b.m().data) return -std::numeric_limits<float>::max(); | |
| 118 | - int score, error; | |
| 119 | - if (algorithm == LFML) error = NEC_LFML_Verify(bData, b.m().total(), aData, a.m().total(), &score); | |
| 120 | - else if (algorithm == ELFT) error = NEC_ELFT_Verify(bData, aData, &score, 1); | |
| 121 | - else error = NEC_ELFT_M_Verify(bData, aData, &score, 1); | |
| 122 | - if (error) | |
| 123 | - qWarning("NECLatent1CompareDistance error %d", error); | |
| 124 | - return score; | |
| 125 | - } | |
| 126 | -}; | |
| 127 | - | |
| 128 | -BR_REGISTER(Distance, NECLatent1CompareDistance) | |
| 129 | - | |
| 130 | -} // namespace br | |
| 131 | - | |
| 132 | -#include "neclatent1.moc" |
openbr/plugins/qtnetwork.cmake
| ... | ... | @@ -4,5 +4,5 @@ if(${BR_WITH_QTNETWORK}) |
| 4 | 4 | find_package(HttpParser) |
| 5 | 5 | set(QT_DEPENDENCIES ${QT_DEPENDENCIES} Network) |
| 6 | 6 | set(BR_THIRDPARTY_SRC ${BR_THIRDPARTY_SRC} plugins/qtnetwork.cpp ${HTTPPARSER_SRC}) |
| 7 | - install(FILES ${HTTPPARSER_LICENSE} RENAME http-parser.license DESTINATION .) | |
| 7 | + install(FILES ${HTTPPARSER_LICENSE} RENAME http-parser DESTINATION share/openbr/license) | |
| 8 | 8 | endif() | ... | ... |
openbr/plugins/yubico.cmake
| ... | ... | @@ -4,9 +4,9 @@ if(${BR_WITH_YUBICO}) |
| 4 | 4 | find_package(YubiKey REQUIRED) # For decrypting YubiKeys |
| 5 | 5 | find_package(YKPers REQUIRED) # For reading YubiKeys |
| 6 | 6 | |
| 7 | - install(FILES ${YUBIKEY_LICENSE} DESTINATION doc RENAME YubiKey.license) | |
| 8 | - install(FILES ${YKPERS_LICENSE} DESTINATION doc RENAME YKPers.license) | |
| 9 | - install(FILES ${YKPERS_RULES} DESTINATION share) | |
| 7 | + install(FILES ${YUBIKEY_LICENSE} RENAME YubiKey DESTINATION share/openbr/licenses) | |
| 8 | + install(FILES ${YKPERS_LICENSE} RENAME YKPers DESTINATION share/openbr/licenses) | |
| 9 | + install(FILES ${YKPERS_RULES} DESTINATION share/openbr) | |
| 10 | 10 | |
| 11 | 11 | set(BR_THIRDPARTY_SRC ${BR_THIRDPARTY_SRC} ${YUBIKEY_SRC} ${YKPERS_SRC} plugins/yubico.cpp) |
| 12 | 12 | set(BR_THIRDPARTY_LIBS ${BR_THIRDPARTY_LIBS} ${YKPERS_LIBS}) | ... | ... |
share/openbr/cmake/FindNEC3.cmake deleted
share/openbr/cmake/FindNECLatent1.cmake deleted
| 1 | -find_path(NECLATENT1_DIR include/LatentEFS.h ${CMAKE_SOURCE_DIR}/3rdparty/*) | |
| 2 | - | |
| 3 | -set(NECLATENT1_SUBDIR /win/${BITNESS}) | |
| 4 | -set(NECLATENT1_LIB_DIR ${NECLATENT1_DIR}/lib${NECLATENT1_SUBDIR}) | |
| 5 | -set(NECLATENT1_BIN_DIR ${NECLATENT1_DIR}/bin${NECLATENT1_SUBDIR}) | |
| 6 | - | |
| 7 | -include_directories(${NECLATENT1_DIR}/include) | |
| 8 | -link_directories(${NECLATENT1_LIB_DIR}) | |
| 9 | - | |
| 10 | -if(MSVC) | |
| 11 | - file(GLOB NECLATENT1_LIBS ${NECLATENT1_LIB_DIR}/*.lib) | |
| 12 | -else() | |
| 13 | - file(GLOB NECLATENT1_LIBS ${NECLATENT1_BIN_DIR}/*.dll) | |
| 14 | -endif() |
share/openbr/cmake/InstallDependencies.cmake
| ... | ... | @@ -33,7 +33,7 @@ function(install_qt_library lib) |
| 33 | 33 | if(${CMAKE_BUILD_TYPE} MATCHES Debug) |
| 34 | 34 | set(BR_INSTALL_DEPENDENCIES_SUFFIX "d") |
| 35 | 35 | endif() |
| 36 | - install(FILES ${_qt5Core_install_prefix}/lib/Qt5${lib}${BR_INSTALL_DEPENDENCIES_SUFFIX}.dll DESTINATION bin) | |
| 36 | + install(FILES ${_qt5Core_install_prefix}/bin/Qt5${lib}${BR_INSTALL_DEPENDENCIES_SUFFIX}.dll DESTINATION bin) | |
| 37 | 37 | elseif(CMAKE_HOST_APPLE) |
| 38 | 38 | install(DIRECTORY ${_qt5Core_install_prefix}/lib/Qt${lib}.framework DESTINATION lib) |
| 39 | 39 | else() | ... | ... |
share/openbr/matlab/loadBin.m deleted
| 1 | -function [x2] = loadBin(filename,reverse) | |
| 2 | -% [x2] = loadBin(filename,reverse) | |
| 3 | - | |
| 4 | - if nargin < 2, | |
| 5 | - reverse = false; | |
| 6 | - end | |
| 7 | - | |
| 8 | - z = fopen(filename,'r'); | |
| 9 | - if z == -1, | |
| 10 | - fprintf('Error opening file %s\n',filename); | |
| 11 | - x2 = 0; | |
| 12 | - return | |
| 13 | - end | |
| 14 | - | |
| 15 | - x = fread(z,1,'int32'); | |
| 16 | - x1 = fread(z,1,'int32'); | |
| 17 | - x2 = fread(z,[x1 x],'float32'); | |
| 18 | - x2 = x2'; | |
| 19 | - fclose(z); | |
| 20 | - | |
| 21 | - if reverse, | |
| 22 | - sz = size(x2); | |
| 23 | - x2 = x2'; | |
| 24 | - x2 = reshape(x2,sz); | |
| 25 | - end |
share/openbr/matlab/loadMtx.m deleted
| 1 | -function [x2] = loadMtx(filename,isRowMajor) | |
| 2 | -% [x2] = loadMtx(filename,reverse) | |
| 3 | -% | |
| 4 | -% Loads a *.mtx file into a Matlab matrix. | |
| 5 | -% 'filename' - the name of the mtx file | |
| 6 | -% 'isRowMajor' - determines whether the | |
| 7 | -% matrix is read in row major or | |
| 8 | -% column major order (optional, default is false) | |
| 9 | -% | |
| 10 | -% This file can likely be improved in terms of effeciency. | |
| 11 | - | |
| 12 | - | |
| 13 | - if nargin < 2, | |
| 14 | - reverse = false; | |
| 15 | - end | |
| 16 | - | |
| 17 | - z = fopen(filename,'r'); | |
| 18 | - if z == -1, | |
| 19 | - fprintf('Error opening file %s\n',filename); | |
| 20 | - x2 = 0; | |
| 21 | - return | |
| 22 | - end | |
| 23 | - | |
| 24 | - buf = zeros(100,1); | |
| 25 | - str_list = cell(4,1); | |
| 26 | - for i = 1:4, | |
| 27 | - cnt = 0; | |
| 28 | - while true | |
| 29 | - cnt = cnt + 1; | |
| 30 | - [a ] = fread(z,1,'uchar'); | |
| 31 | - if a == 10 | |
| 32 | - break; | |
| 33 | - end | |
| 34 | - buf(cnt) = a; | |
| 35 | - end | |
| 36 | - str_list{i} = char(buf(1:cnt-1)'); | |
| 37 | - end | |
| 38 | - | |
| 39 | - s = strsplit(' ',str_list{4}); | |
| 40 | - x = str2num(s{2}); | |
| 41 | - x1 = str2num(s{3}); | |
| 42 | - typ = s{1}(2); | |
| 43 | - | |
| 44 | - %x2 = fread(z,[x1 x],'float32'); | |
| 45 | - if strcmp(typ,'F') | |
| 46 | - x2 = fread(z,[x1 x],'single'); | |
| 47 | - elseif strcmp(typ,'B') | |
| 48 | - x2 = fread(z,[x1 x],'int8'); | |
| 49 | - else | |
| 50 | - assert(0); | |
| 51 | - end | |
| 52 | - x2 = x2'; | |
| 53 | - fclose(z); | |
| 54 | - | |
| 55 | - if reverse, | |
| 56 | - sz = size(x2); | |
| 57 | - x2 = x2'; | |
| 58 | - x2 = reshape(x2,sz); | |
| 59 | - end | |
| 60 | 0 | \ No newline at end of file |
share/openbr/openbr-small.png deleted
2.82 KB
share/openbr/openbr.icns
No preview for this file type
share/openbr/openbr.ico
No preview for this file type
share/openbr/openbr.png
share/openbr/openbr.svg
| ... | ... | @@ -9,12 +9,15 @@ |
| 9 | 9 | xmlns="http://www.w3.org/2000/svg" |
| 10 | 10 | xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" |
| 11 | 11 | xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" |
| 12 | - width="512" | |
| 13 | - height="512" | |
| 12 | + width="744.09448819" | |
| 13 | + height="1052.3622047" | |
| 14 | 14 | id="svg2" |
| 15 | 15 | version="1.1" |
| 16 | 16 | inkscape:version="0.48.2 r9819" |
| 17 | - sodipodi:docname="openbr.svg"> | |
| 17 | + sodipodi:docname="logo.svg" | |
| 18 | + inkscape:export-filename="/Users/scottklum/openbr/share/openbr/logo.png" | |
| 19 | + inkscape:export-xdpi="78.628136" | |
| 20 | + inkscape:export-ydpi="78.628136"> | |
| 18 | 21 | <defs |
| 19 | 22 | id="defs4" /> |
| 20 | 23 | <sodipodi:namedview |
| ... | ... | @@ -24,17 +27,17 @@ |
| 24 | 27 | borderopacity="1.0" |
| 25 | 28 | inkscape:pageopacity="0.0" |
| 26 | 29 | inkscape:pageshadow="2" |
| 27 | - inkscape:zoom="1.1572757" | |
| 28 | - inkscape:cx="285.7618" | |
| 29 | - inkscape:cy="191.07932" | |
| 30 | + inkscape:zoom="1.5306292" | |
| 31 | + inkscape:cx="337.72687" | |
| 32 | + inkscape:cy="469.27528" | |
| 30 | 33 | inkscape:document-units="px" |
| 31 | 34 | inkscape:current-layer="layer1" |
| 32 | 35 | showgrid="false" |
| 33 | - inkscape:window-width="1389" | |
| 34 | - inkscape:window-height="856" | |
| 35 | - inkscape:window-x="51" | |
| 36 | + inkscape:window-width="1222" | |
| 37 | + inkscape:window-height="756" | |
| 38 | + inkscape:window-x="58" | |
| 36 | 39 | inkscape:window-y="0" |
| 37 | - inkscape:window-maximized="1" /> | |
| 40 | + inkscape:window-maximized="0" /> | |
| 38 | 41 | <metadata |
| 39 | 42 | id="metadata7"> |
| 40 | 43 | <rdf:RDF> |
| ... | ... | @@ -43,41 +46,132 @@ |
| 43 | 46 | <dc:format>image/svg+xml</dc:format> |
| 44 | 47 | <dc:type |
| 45 | 48 | rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> |
| 46 | - <dc:title /> | |
| 49 | + <dc:title></dc:title> | |
| 47 | 50 | </cc:Work> |
| 48 | 51 | </rdf:RDF> |
| 49 | 52 | </metadata> |
| 50 | 53 | <g |
| 51 | 54 | inkscape:label="Layer 1" |
| 52 | 55 | inkscape:groupmode="layer" |
| 53 | - id="layer1" | |
| 54 | - transform="translate(0,-540.36218)"> | |
| 55 | - <rect | |
| 56 | - style="fill:#ffffff;fill-opacity:0;fill-rule:evenodd;stroke:#000000;stroke-width:7.90251827;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" | |
| 57 | - id="rect2985" | |
| 58 | - width="376.09747" | |
| 59 | - height="376.09747" | |
| 60 | - x="67.951263" | |
| 61 | - y="640.31335" /> | |
| 56 | + id="layer1"> | |
| 57 | + <path | |
| 58 | + sodipodi:type="arc" | |
| 59 | + style="fill:#000000;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" | |
| 60 | + id="path2987" | |
| 61 | + sodipodi:cx="371.42856" | |
| 62 | + sodipodi:cy="579.50507" | |
| 63 | + sodipodi:rx="212.58394" | |
| 64 | + sodipodi:ry="212.58394" | |
| 65 | + d="m 584.0125,579.50507 a 212.58394,212.58394 0 1 1 -425.16788,0 212.58394,212.58394 0 1 1 425.16788,0 z" | |
| 66 | + transform="matrix(0.67143477,0,0,0.67143477,119.03851,174.90671)" /> | |
| 62 | 67 | <path |
| 63 | 68 | sodipodi:type="arc" |
| 64 | - style="fill:#ffffff;fill-opacity:0;stroke:#000000;stroke-width:7.859694;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" | |
| 65 | - id="path2991" | |
| 66 | - sodipodi:cx="350" | |
| 67 | - sodipodi:cy="393.79074" | |
| 68 | - sodipodi:rx="218.57143" | |
| 69 | - sodipodi:ry="218.57143" | |
| 70 | - d="m 568.57143,393.79074 a 218.57143,218.57143 0 1 1 -437.14286,0 218.57143,218.57143 0 1 1 437.14286,0 z" | |
| 71 | - transform="matrix(1.0067358,0,0,1.0067358,-96.357534,399.91894)" /> | |
| 69 | + style="fill:#ffffff" | |
| 70 | + id="path2989" | |
| 71 | + sodipodi:cx="401.42856" | |
| 72 | + sodipodi:cy="273.79074" | |
| 73 | + sodipodi:rx="150" | |
| 74 | + sodipodi:ry="150" | |
| 75 | + d="m 551.42856,273.79074 a 150,150 0 1 1 -300,0 150,150 0 1 1 300,0 z" | |
| 76 | + transform="matrix(0.86501586,0,0,0.85407393,21.11727,331.21667)" | |
| 77 | + inkscape:export-filename="/Users/scottklum/openbr/share/openbr/logo.png" | |
| 78 | + inkscape:export-xdpi="90" | |
| 79 | + inkscape:export-ydpi="90" /> | |
| 80 | + <path | |
| 81 | + style="fill:#000000" | |
| 82 | + d="" | |
| 83 | + id="path3033" | |
| 84 | + inkscape:connector-curvature="0" /> | |
| 85 | + <path | |
| 86 | + style="fill:#000000" | |
| 87 | + d="" | |
| 88 | + id="path3035" | |
| 89 | + inkscape:connector-curvature="0" /> | |
| 72 | 90 | <g |
| 73 | - transform="scale(1.1432502,0.87469915)" | |
| 74 | - style="font-size:602.20269775px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" | |
| 75 | - id="text3808"> | |
| 76 | - <path | |
| 77 | - d="m 139.95187,979.03625 0,114.32505 c 0,0 55.98075,0 83.97112,0 0,0 73.21541,0 83.97112,0 10.75572,0 27.99037,-35.1782 27.99037,-57.1625 0,-21.9843 -17.23464,-57.16255 -27.99037,-57.16255 -10.75573,10e-6 -83.97112,0 -83.97112,0 m -83.97112,-187.49303 0,114.32502 83.97112,0 83.97112,0 c 8.29626,0 27.99037,-35.17826 27.99037,-57.16251 0,-21.98425 -19.69398,-57.16251 -27.99037,-57.16251 l -83.97112,0 m 0,-64.02201 c 0,0 68.80967,0 90.96871,0 22.15905,0 41.98556,0 41.98556,0 l 34.98797,54.87601 0,64.02201 c 0,28.9222 -5.34568,57.28993 -20.99278,77.74101 l -13.99519,18.29201 13.99519,18.292 c 14.09205,18.4186 20.99278,51.69325 20.99278,77.74105 l 0,128.044 -55.98075,0 0,-45.73 c -33.40248,25.4228 -76.13986,45.488 -111.96149,45.73 -31.46502,-2.1586 -56.36563,-10.8805 -83.76198,-28.3596 l -0.20914,28.3596 -55.98075,0 0,-80.0275 -3e-6,-358.98059" | |
| 78 | - id="path3816" | |
| 79 | - inkscape:connector-curvature="0" | |
| 80 | - sodipodi:nodetypes="ccczzzccccszscccccsscssccccccccc" /> | |
| 91 | + id="g3045" | |
| 92 | + transform="translate(-2,0)" | |
| 93 | + inkscape:export-filename="/Users/scottklum/openbr/share/openbr/logo.png" | |
| 94 | + inkscape:export-xdpi="78.628136" | |
| 95 | + inkscape:export-ydpi="78.628136"> | |
| 96 | + <text | |
| 97 | + transform="scale(-1,1)" | |
| 98 | + sodipodi:linespacing="125%" | |
| 99 | + id="text2991" | |
| 100 | + y="617.177" | |
| 101 | + x="-382.20804" | |
| 102 | + style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" | |
| 103 | + xml:space="preserve"><tspan | |
| 104 | + style="font-size:144px" | |
| 105 | + y="617.177" | |
| 106 | + x="-382.20804" | |
| 107 | + id="tspan2993" | |
| 108 | + sodipodi:role="line">B</tspan></text> | |
| 109 | + <text | |
| 110 | + transform="scale(1.0549347,0.94792599)" | |
| 111 | + sodipodi:linespacing="125%" | |
| 112 | + id="text2995" | |
| 113 | + y="639.84802" | |
| 114 | + x="336.8999" | |
| 115 | + style="font-size:37.91703796px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" | |
| 116 | + xml:space="preserve"><tspan | |
| 117 | + style="font-size:136.50134277px" | |
| 118 | + y="639.84802" | |
| 119 | + x="336.8999" | |
| 120 | + id="tspan2997" | |
| 121 | + sodipodi:role="line" /></text> | |
| 81 | 122 | </g> |
| 123 | + <g | |
| 124 | + transform="matrix(-1,0,0,1,737.68951,0)" | |
| 125 | + id="g3013" | |
| 126 | + inkscape:export-xdpi="78.628136" | |
| 127 | + inkscape:export-ydpi="78.628136" | |
| 128 | + inkscape:export-filename="/Users/scottklum/openbr/share/openbr/logo.png"> | |
| 129 | + <text | |
| 130 | + xml:space="preserve" | |
| 131 | + style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" | |
| 132 | + x="-382.20804" | |
| 133 | + y="617.177" | |
| 134 | + id="text3015" | |
| 135 | + sodipodi:linespacing="125%" | |
| 136 | + transform="scale(-1,1)"><tspan | |
| 137 | + sodipodi:role="line" | |
| 138 | + id="tspan3017" | |
| 139 | + x="-382.20804" | |
| 140 | + y="617.177" | |
| 141 | + style="font-size:144px">B</tspan></text> | |
| 142 | + <text | |
| 143 | + xml:space="preserve" | |
| 144 | + style="font-size:37.91703796px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" | |
| 145 | + x="336.8999" | |
| 146 | + y="639.84802" | |
| 147 | + id="text3019" | |
| 148 | + sodipodi:linespacing="125%" | |
| 149 | + transform="scale(1.0549347,0.94792599)"><tspan | |
| 150 | + sodipodi:role="line" | |
| 151 | + id="tspan3021" | |
| 152 | + x="336.8999" | |
| 153 | + y="639.84802" | |
| 154 | + style="font-size:136.50134277px" /></text> | |
| 155 | + </g> | |
| 156 | + <rect | |
| 157 | + style="fill:#000000;fill-opacity:1;stroke:none" | |
| 158 | + id="rect3025" | |
| 159 | + width="14.95" | |
| 160 | + height="30.339096" | |
| 161 | + x="429.095" | |
| 162 | + y="586.8631" | |
| 163 | + inkscape:export-xdpi="78.628136" | |
| 164 | + inkscape:export-ydpi="78.628136" | |
| 165 | + inkscape:export-filename="/Users/scottklum/openbr/share/openbr/logo.png" /> | |
| 166 | + <rect | |
| 167 | + style="fill:#ffffff;fill-opacity:1;stroke:none" | |
| 168 | + id="rect3023" | |
| 169 | + width="45.287998" | |
| 170 | + height="47.707817" | |
| 171 | + x="383.81201" | |
| 172 | + y="586.75787" | |
| 173 | + inkscape:export-xdpi="78.628136" | |
| 174 | + inkscape:export-ydpi="78.628136" | |
| 175 | + inkscape:export-filename="/Users/scottklum/openbr/share/openbr/logo.png" /> | |
| 82 | 176 | </g> |
| 83 | 177 | </svg> | ... | ... |
share/openbr/openbr_small.png
0 → 100644
2.93 KB
share/openbr/openbr_white.png
0 → 100644
12.7 KB
share/openbr/qmake_tutorial/hello.pro
0 → 100644
share/openbr/qmake_tutorial/main.cpp
0 → 100644
| 1 | +#include <QApplication> | |
| 2 | +#include <QLabel> | |
| 3 | +#include <openbr/openbr.h> | |
| 4 | + | |
| 5 | +int main(int argc, char *argv[]) | |
| 6 | +{ | |
| 7 | + QApplication app(argc, argv); | |
| 8 | + br_initialize(argc, argv); | |
| 9 | + | |
| 10 | + QLabel label; | |
| 11 | + label.setText("Hello OpenBR!"); | |
| 12 | + label.show(); | |
| 13 | + | |
| 14 | + int result = app.exec(); | |
| 15 | + br_finalize(); | |
| 16 | + return result; | |
| 17 | +} | ... | ... |