Commit 82dcffcfef5bedf720bd135d60ff12bbe973e795
Merge branch 'master' of https://github.com/biometrics/openbr
Showing
21 changed files
with
532 additions
and
79 deletions
3rdparty/NaturalStringCompare2/NaturalStringCompare.cpp
0 → 100755
| 1 | +/* | |
| 2 | + * This software was written by people from OnShore Consulting services LLC | |
| 3 | + * <info@sabgroup.com> and placed in the public domain. | |
| 4 | + * | |
| 5 | + * We reserve no legal rights to any of this. You are free to do | |
| 6 | + * whatever you want with it. And we make no guarantee or accept | |
| 7 | + * any claims on damages as a result of this. | |
| 8 | + * | |
| 9 | + * If you change the software, please help us and others improve the | |
| 10 | + * code by sending your modifications to us. If you choose to do so, | |
| 11 | + * your changes will be included under this license, and we will add | |
| 12 | + * your name to the list of contributors. | |
| 13 | +*/ | |
| 14 | + | |
| 15 | +#include "NaturalStringCompare.h" | |
| 16 | +#include <QStringList> | |
| 17 | + | |
| 18 | +#define INCBUF() { buffer += curr; ++pos; curr = ( pos < string.length() ) ? string[ pos ] : QChar(); } | |
| 19 | + | |
| 20 | +void ExtractToken( QString & buffer, const QString & string, int & pos, bool & isNumber ) | |
| 21 | +{ | |
| 22 | + buffer.clear(); | |
| 23 | + if ( string.isNull() || pos >= string.length() ) | |
| 24 | + return; | |
| 25 | + | |
| 26 | + isNumber = false; | |
| 27 | + QChar curr = string[ pos ]; | |
| 28 | + if ( curr == '-' || curr == '+' || curr.isDigit() ) | |
| 29 | + { | |
| 30 | + if ( curr == '-' || curr == '+' ) | |
| 31 | + INCBUF(); | |
| 32 | + | |
| 33 | + if ( !curr.isNull() && curr.isDigit() ) | |
| 34 | + { | |
| 35 | + isNumber = true; | |
| 36 | + while ( curr.isDigit() ) | |
| 37 | + INCBUF(); | |
| 38 | + | |
| 39 | + if ( curr == '.' ) | |
| 40 | + { | |
| 41 | + INCBUF(); | |
| 42 | + while ( curr.isDigit() ) | |
| 43 | + INCBUF(); | |
| 44 | + } | |
| 45 | + | |
| 46 | + if ( !curr.isNull() && curr.toLower() == 'e' ) | |
| 47 | + { | |
| 48 | + INCBUF(); | |
| 49 | + if ( curr == '-' || curr == '+' ) | |
| 50 | + INCBUF(); | |
| 51 | + | |
| 52 | + if ( curr.isNull() || !curr.isDigit() ) | |
| 53 | + isNumber = false; | |
| 54 | + else | |
| 55 | + while ( curr.isDigit() ) | |
| 56 | + INCBUF(); | |
| 57 | + } | |
| 58 | + } | |
| 59 | + } | |
| 60 | + | |
| 61 | + if ( !isNumber ) | |
| 62 | + { | |
| 63 | + while ( curr != '-' && curr != '+' && !curr.isDigit() && pos < string.length() ) | |
| 64 | + INCBUF(); | |
| 65 | + } | |
| 66 | +} | |
| 67 | + | |
| 68 | +int NaturalStringCompare( const QString & lhs, const QString & rhs, Qt::CaseSensitivity caseSensitive ) | |
| 69 | +{ | |
| 70 | + int ii = 0; | |
| 71 | + int jj = 0; | |
| 72 | + | |
| 73 | + QString lhsBufferQStr; | |
| 74 | + QString rhsBufferQStr; | |
| 75 | + | |
| 76 | + int retVal = 0; | |
| 77 | + | |
| 78 | + // all status values are created on the stack outside the loop to make as fast as possible | |
| 79 | + bool lhsNumber = false; | |
| 80 | + bool rhsNumber = false; | |
| 81 | + | |
| 82 | + double lhsValue = 0.0; | |
| 83 | + double rhsValue = 0.0; | |
| 84 | + bool ok1; | |
| 85 | + bool ok2; | |
| 86 | + | |
| 87 | + while ( retVal == 0 && ii < lhs.length() && jj < rhs.length() ) | |
| 88 | + { | |
| 89 | + ExtractToken( lhsBufferQStr, lhs, ii, lhsNumber ); | |
| 90 | + ExtractToken( rhsBufferQStr, rhs, jj, rhsNumber ); | |
| 91 | + | |
| 92 | + if ( !lhsNumber && !rhsNumber ) | |
| 93 | + { | |
| 94 | + // both strings curr val is a simple strcmp | |
| 95 | + retVal = lhsBufferQStr.compare( rhsBufferQStr, caseSensitive ); | |
| 96 | + | |
| 97 | + int maxLen = qMin( lhsBufferQStr.length(), rhsBufferQStr.length() ); | |
| 98 | + QString tmpRight = rhsBufferQStr.left( maxLen ); | |
| 99 | + QString tmpLeft = lhsBufferQStr.left( maxLen ); | |
| 100 | + if ( tmpLeft.compare( tmpRight, caseSensitive ) == 0 ) | |
| 101 | + { | |
| 102 | + retVal = lhsBufferQStr.length() - rhsBufferQStr.length(); | |
| 103 | + if ( retVal ) | |
| 104 | + { | |
| 105 | + QChar nextChar; | |
| 106 | + if ( ii < lhs.length() ) // more on the lhs | |
| 107 | + nextChar = lhs[ ii ]; | |
| 108 | + else if ( jj < rhs.length() ) // more on the rhs | |
| 109 | + nextChar = rhs[ jj ]; | |
| 110 | + | |
| 111 | + bool nextIsNum = ( nextChar == '-' || nextChar == '+' || nextChar.isDigit() ); | |
| 112 | + | |
| 113 | + if ( nextIsNum ) | |
| 114 | + retVal = -1*retVal; | |
| 115 | + } | |
| 116 | + } | |
| 117 | + } | |
| 118 | + else if ( lhsNumber && rhsNumber ) | |
| 119 | + { | |
| 120 | + // both numbers, convert and compare | |
| 121 | + lhsValue = lhsBufferQStr.toDouble( &ok1 ); | |
| 122 | + rhsValue = rhsBufferQStr.toDouble( &ok2 ); | |
| 123 | + if ( !ok1 || !ok2 ) | |
| 124 | + retVal = lhsBufferQStr.compare( rhsBufferQStr, caseSensitive ); | |
| 125 | + else if ( lhsValue > rhsValue ) | |
| 126 | + retVal = 1; | |
| 127 | + else if ( lhsValue < rhsValue ) | |
| 128 | + retVal = -1; | |
| 129 | + } | |
| 130 | + else | |
| 131 | + { | |
| 132 | + // completely arebitrary that a number comes before a string | |
| 133 | + retVal = lhsNumber ? -1 : 1; | |
| 134 | + } | |
| 135 | + } | |
| 136 | + | |
| 137 | + if ( retVal != 0 ) | |
| 138 | + return retVal; | |
| 139 | + if ( ii < lhs.length() ) | |
| 140 | + return -1; | |
| 141 | + else if ( jj < rhs.length() ) | |
| 142 | + return 1; | |
| 143 | + else | |
| 144 | + return 0; | |
| 145 | +} | |
| 146 | + | |
| 147 | +bool NaturalStringCompareLessThan( const QString & lhs, const QString & rhs ) | |
| 148 | +{ | |
| 149 | + return NaturalStringCompare( lhs, rhs, Qt::CaseSensitive ) < 0; | |
| 150 | +} | |
| 151 | + | |
| 152 | +bool NaturalStringCaseInsensitiveCompareLessThan( const QString & lhs, const QString & rhs ) | |
| 153 | +{ | |
| 154 | + return NaturalStringCompare( lhs, rhs, Qt::CaseInsensitive ) < 0; | |
| 155 | +} | |
| 156 | + | |
| 157 | +QStringList NaturalStringSort( const QStringList & list, Qt::CaseSensitivity caseSensitive ) | |
| 158 | +{ | |
| 159 | + QStringList retVal = list; | |
| 160 | + if ( caseSensitive == Qt::CaseSensitive ) | |
| 161 | + qSort( retVal.begin(), retVal.end(), NaturalStringCompareLessThan ); | |
| 162 | + else | |
| 163 | + qSort( retVal.begin(), retVal.end(), NaturalStringCaseInsensitiveCompareLessThan ); | |
| 164 | + return retVal; | |
| 165 | +} | |
| 166 | + | |
| 167 | + | ... | ... |
3rdparty/NaturalStringCompare2/NaturalStringCompare.h
0 → 100755
| 1 | +#ifndef __NATURALSTRINGCOMPARE_H | |
| 2 | +#define __NATURALSTRINGCOMPARE_H | |
| 3 | + | |
| 4 | +/* | |
| 5 | + * This software was written by people from OnShore Consulting services LLC | |
| 6 | + * <info@sabgroup.com> and placed in the public domain. | |
| 7 | + * | |
| 8 | + * We reserve no legal rights to any of this. You are free to do | |
| 9 | + * whatever you want with it. And we make no guarantee or accept | |
| 10 | + * any claims on damages as a result of this. | |
| 11 | + * | |
| 12 | + * If you change the software, please help us and others improve the | |
| 13 | + * code by sending your modifications to us. If you choose to do so, | |
| 14 | + * your changes will be included under this license, and we will add | |
| 15 | + * your name to the list of contributors. | |
| 16 | +*/ | |
| 17 | + | |
| 18 | +#include <QString> | |
| 19 | +#include <QStringList> | |
| 20 | + | |
| 21 | +int NaturalStringCompare( const QString & lhs, const QString & rhs, Qt::CaseSensitivity caseSensitive=Qt::CaseSensitive ); | |
| 22 | +QStringList NaturalStringSort( const QStringList & list, Qt::CaseSensitivity caseSensitive=Qt::CaseSensitive ); | |
| 23 | +bool NaturalStringCompareLessThan( const QString & lhs, const QString & rhs ); | |
| 24 | +bool NaturalStringCaseInsensitiveCompareLessThan( const QString & lhs, const QString & rhs ); | |
| 25 | + | |
| 26 | +#endif | ... | ... |
3rdparty/NaturalStringCompare2/NaturalStringCompare.pro
0 → 100755
| 1 | +###################################################################### | |
| 2 | +# Automatically generated by qmake (2.01a) Mon Feb 25 10:13:54 2008 | |
| 3 | +###################################################################### | |
| 4 | + | |
| 5 | +TEMPLATE = app | |
| 6 | +TARGET = | |
| 7 | +DEPENDPATH += . | |
| 8 | +INCLUDEPATH += . | |
| 9 | + | |
| 10 | +# Input | |
| 11 | +HEADERS += NaturalStringCompare.h | |
| 12 | +SOURCES += main.cpp NaturalStringCompare.cpp | |
| 13 | + | |
| 14 | +CONFIG += console qtestlib | |
| 15 | +QT-=gui | |
| 16 | + | ... | ... |
3rdparty/NaturalStringCompare2/main.cpp
0 → 100755
| 1 | +/* | |
| 2 | + * This software was written by people from OnShore Consulting services LLC | |
| 3 | + * <info@sabgroup.com> and placed in the public domain. | |
| 4 | + * | |
| 5 | + * We reserve no legal rights to any of this. You are free to do | |
| 6 | + * whatever you want with it. And we make no guarantee or accept | |
| 7 | + * any claims on damages as a result of this. | |
| 8 | + * | |
| 9 | + * If you change the software, please help us and others improve the | |
| 10 | + * code by sending your modifications to us. If you choose to do so, | |
| 11 | + * your changes will be included under this license, and we will add | |
| 12 | + * your name to the list of contributors. | |
| 13 | +*/ | |
| 14 | + | |
| 15 | +#include <QCoreApplication> | |
| 16 | +#include <QtTest> | |
| 17 | +#include <QDebug> | |
| 18 | +#include "NaturalStringCompare.h" | |
| 19 | + | |
| 20 | +class CTestNaturalStringCompare : public QObject | |
| 21 | +{ | |
| 22 | + Q_OBJECT | |
| 23 | +private slots: | |
| 24 | + void compareString() | |
| 25 | + { | |
| 26 | + QString str1 = "abcdef"; | |
| 27 | + QString str2 = "aabc"; | |
| 28 | + QVERIFY( NaturalStringCompare(str1,str2) > 0 ); | |
| 29 | + QVERIFY( NaturalStringCompare(str2,str1) < 0 ); | |
| 30 | + QVERIFY( NaturalStringCompare(str1,str1) == 0 ); | |
| 31 | + QVERIFY( NaturalStringCompare(str2,str2) == 0 ); | |
| 32 | + | |
| 33 | + QVERIFY( NaturalStringCompare(str1,str1.left(2)) > 0 ); | |
| 34 | + QVERIFY( NaturalStringCompare(str1.left(2),str1) < 0 ); | |
| 35 | + } | |
| 36 | + | |
| 37 | + void compareInteger() | |
| 38 | + { | |
| 39 | + for( int ii = -15; ii <= 15; ii++ ) | |
| 40 | + { | |
| 41 | + QString currVal = QString( "%1" ).arg( ii ); | |
| 42 | + QString nextVal = QString( "%1" ).arg( ii+1 ); | |
| 43 | + | |
| 44 | + QVERIFY( NaturalStringCompare(currVal,nextVal) < 0 ); | |
| 45 | + QVERIFY( NaturalStringCompare( "prefix" + currVal, "prefix" + nextVal) < 0 ); | |
| 46 | + QVERIFY( NaturalStringCompare( currVal + "postfix", nextVal + "postfix") < 0 ); | |
| 47 | + QVERIFY( NaturalStringCompare( "prefix" + currVal + "postfix", "prefix" + nextVal + "postfix") < 0 ); | |
| 48 | + | |
| 49 | + QVERIFY( NaturalStringCompare(nextVal,currVal) > 0 ); | |
| 50 | + QVERIFY( NaturalStringCompare( "prefix" + nextVal, "prefix" + currVal) > 0 ); | |
| 51 | + QVERIFY( NaturalStringCompare( nextVal + "postfix", currVal + "postfix") > 0 ); | |
| 52 | + QVERIFY( NaturalStringCompare( "prefix" + nextVal + "postfix", "prefix" + currVal + "postfix") > 0 ); | |
| 53 | + | |
| 54 | + QVERIFY( NaturalStringCompare(currVal,currVal) == 0 ); | |
| 55 | + QVERIFY( NaturalStringCompare( "prefix" + currVal, "prefix" + currVal) == 0 ); | |
| 56 | + QVERIFY( NaturalStringCompare( currVal + "postfix", currVal + "postfix") == 0 ); | |
| 57 | + QVERIFY( NaturalStringCompare( "prefix" + currVal + "postfix", "prefix" + currVal + "postfix") == 0 ); | |
| 58 | + | |
| 59 | + QVERIFY( NaturalStringCompare( "prefix" + currVal + "middle" + currVal, "prefix" + currVal + "middle" + nextVal ) < 0 ); | |
| 60 | + QVERIFY( NaturalStringCompare( "prefix" + currVal + "middle" + nextVal, "prefix" + currVal + "middle" + currVal ) > 0 ); | |
| 61 | + } | |
| 62 | + } | |
| 63 | + | |
| 64 | + void compareDouble() | |
| 65 | + { | |
| 66 | + for( int ii = -15; ii <= 15; ii++ ) | |
| 67 | + { | |
| 68 | + QString currVal = QString( "%1" ).arg( 1.0*ii - 0.05 ); | |
| 69 | + QString nextVal = QString( "%1" ).arg( 1.0*ii + 0.05 ); | |
| 70 | + | |
| 71 | + QVERIFY( NaturalStringCompare(currVal,nextVal) < 0 ); | |
| 72 | + QVERIFY( NaturalStringCompare( "prefix" + currVal, "prefix" + nextVal) < 0 ); | |
| 73 | + QVERIFY( NaturalStringCompare( currVal + "postfix", nextVal + "postfix") < 0 ); | |
| 74 | + QVERIFY( NaturalStringCompare( "prefix" + currVal + "postfix", "prefix" + nextVal + "postfix") < 0 ); | |
| 75 | + | |
| 76 | + QVERIFY( NaturalStringCompare(nextVal,currVal) > 0 ); | |
| 77 | + QVERIFY( NaturalStringCompare( "prefix" + nextVal, "prefix" + currVal) > 0 ); | |
| 78 | + QVERIFY( NaturalStringCompare( nextVal + "postfix", currVal + "postfix") > 0 ); | |
| 79 | + QVERIFY( NaturalStringCompare( "prefix" + nextVal + "postfix", "prefix" + currVal + "postfix") > 0 ); | |
| 80 | + | |
| 81 | + QVERIFY( NaturalStringCompare(currVal,currVal) == 0 ); | |
| 82 | + QVERIFY( NaturalStringCompare( "prefix" + currVal, "prefix" + currVal) == 0 ); | |
| 83 | + QVERIFY( NaturalStringCompare( currVal + "postfix", currVal + "postfix") == 0 ); | |
| 84 | + QVERIFY( NaturalStringCompare( "prefix" + currVal + "postfix", "prefix" + currVal + "postfix") == 0 ); | |
| 85 | + | |
| 86 | + QVERIFY( NaturalStringCompare( "prefix" + currVal + "middle" + currVal, "prefix" + currVal + "middle" + nextVal ) < 0 ); | |
| 87 | + QVERIFY( NaturalStringCompare( "prefix" + currVal + "middle" + nextVal, "prefix" + currVal + "middle" + currVal ) > 0 ); | |
| 88 | + } | |
| 89 | + } | |
| 90 | + | |
| 91 | + void sortStringList() | |
| 92 | + { | |
| 93 | + QStringList orig; | |
| 94 | + for( int ii = 15; ii >= -15; ii-- ) | |
| 95 | + { | |
| 96 | + QString currVal = QString( "%1" ).arg( 1.0*ii - 0.05 ); | |
| 97 | + orig << "prefix" + currVal + "postfix"; | |
| 98 | + orig << "Prefix" + currVal + "posTfIx"; | |
| 99 | + currVal = QString( "%1" ).arg( ii ); | |
| 100 | + orig << "Prefix" + currVal; | |
| 101 | + orig << currVal + "PostFIX"; | |
| 102 | + orig << currVal + "PostFix"; | |
| 103 | + } | |
| 104 | + | |
| 105 | + QStringList toBeSorted = orig; | |
| 106 | + qSort( toBeSorted.begin(), toBeSorted.end(), NaturalStringCompareLessThan ); | |
| 107 | + | |
| 108 | + | |
| 109 | + int cnt = toBeSorted.count(); | |
| 110 | + QVERIFY( toBeSorted.count() == 31 * 5 ); | |
| 111 | + QVERIFY( toBeSorted.front() == "-15PostFIX" ); | |
| 112 | + QVERIFY( toBeSorted.back() == "prefix14.95postfix" ); | |
| 113 | + | |
| 114 | + QStringList tmp = NaturalStringSort( orig ); | |
| 115 | + QVERIFY( tmp.count() == toBeSorted.count() ); | |
| 116 | + for( int ii = 0; ii < tmp.count(); ++ii ) | |
| 117 | + { | |
| 118 | + QVERIFY( tmp[ ii ] == toBeSorted[ ii ] ); | |
| 119 | + } | |
| 120 | + | |
| 121 | + toBeSorted = orig; | |
| 122 | + qSort( toBeSorted.begin(), toBeSorted.end(), NaturalStringCaseInsensitiveCompareLessThan ); | |
| 123 | + cnt = toBeSorted.count(); | |
| 124 | + QVERIFY( toBeSorted.count() == 31 * 5 ); | |
| 125 | + // QVERIFY( toBeSorted.front() == "-15PostFix" ); for case insensitive, PostFix vs PostFIX is non-deterministic which comes firs | |
| 126 | + // QVERIFY( toBeSorted.back() == "Prefix15" ); | |
| 127 | + | |
| 128 | + tmp = NaturalStringSort( orig, Qt::CaseInsensitive ); | |
| 129 | + QVERIFY( tmp.count() == toBeSorted.count() ); | |
| 130 | + for( int ii = 0; ii < tmp.count(); ++ii ) | |
| 131 | + { | |
| 132 | + QVERIFY( tmp[ ii ] == toBeSorted[ ii ] ); | |
| 133 | + } | |
| 134 | + } | |
| 135 | + | |
| 136 | + void lingfaYangTest() | |
| 137 | + { | |
| 138 | + // this is actually not what the spec wants, however, the 8 causes the first compare to be | |
| 139 | + // ppt/slides/slide vs ppt/slides/slide.xml which means embedded numbers will come first. | |
| 140 | + | |
| 141 | + QVERIFY( NaturalStringCompare( "ppt/slides/slide8.xml", "ppt/slides/slide.xml2", Qt::CaseInsensitive ) > 0 ); | |
| 142 | + | |
| 143 | + QStringList orderedList = QStringList() // from Ligfa Ya email | |
| 144 | + << "[Content_Types].xml" | |
| 145 | + << "_rels/.rels" | |
| 146 | + << "ppt/media/image8.wmf" | |
| 147 | + << "ppt/media/image9.jpeg" | |
| 148 | + << "ppt/media/image10.png" | |
| 149 | + << "ppt/media/image11.gif" | |
| 150 | + << "ppt/slides/_rels/slide9.xml.rels" | |
| 151 | + << "ppt/slides/_rels/slide10.xml.rels" | |
| 152 | + << "ppt/slides/slide.xml" | |
| 153 | + << "ppt/slides/slide8.xml" | |
| 154 | + << "PPT/SLIDES/SLIDE9.XML" | |
| 155 | + << "ppt/slides/slide10.xml" | |
| 156 | + << "ppt/slides/slide11.xml" | |
| 157 | + << "slide.xml" | |
| 158 | + ; | |
| 159 | + | |
| 160 | + QStringList toBeSorted = QStringList(); | |
| 161 | + QStringList tmp = orderedList; | |
| 162 | + qsrand( QDateTime::currentDateTime().toTime_t() ); | |
| 163 | + while( !tmp.isEmpty() ) | |
| 164 | + { | |
| 165 | + double randVal = qrand(); | |
| 166 | + randVal /= RAND_MAX; | |
| 167 | + int val = (int)( tmp.count() - 1 ) * randVal; | |
| 168 | + toBeSorted << tmp[ val ]; | |
| 169 | + tmp.removeAt( val ); | |
| 170 | + } | |
| 171 | + tmp = NaturalStringSort( toBeSorted, Qt::CaseInsensitive ); | |
| 172 | + for( int ii = 0; ii < tmp.count(); ++ii ) | |
| 173 | + { | |
| 174 | + QVERIFY( tmp[ ii ] == orderedList[ ii ] ); | |
| 175 | + } | |
| 176 | + } | |
| 177 | + | |
| 178 | +}; | |
| 179 | + | |
| 180 | +QTEST_MAIN(CTestNaturalStringCompare) | |
| 181 | +#include "main.moc" | ... | ... |
CHANGELOG.md
CMakeLists.txt
| ... | ... | @@ -39,8 +39,6 @@ endif() |
| 39 | 39 | if(WIN32) |
| 40 | 40 | configure_file(${BR_SHARE_DIR}/resources.rc.in resources.rc) |
| 41 | 41 | set(BR_RESOURCES ${CMAKE_CURRENT_BINARY_DIR}/resources.rc) |
| 42 | -elseif(APPLE) | |
| 43 | - set(BR_RESOURCES ${NATIVE_ICON}) | |
| 44 | 42 | endif() |
| 45 | 43 | |
| 46 | 44 | # Build options |
| ... | ... | @@ -72,8 +70,11 @@ set(BR_THIRDPARTY_LIBS ${BR_THIRDPARTY_LIBS} ${Qt5Core_QTMAIN_LIBRARIES}) |
| 72 | 70 | |
| 73 | 71 | # Find OpenCV |
| 74 | 72 | find_package(OpenCV REQUIRED) |
| 73 | +set(OPENCV_DEPENDENCIES opencv_core opencv_features2d opencv_flann opencv_highgui opencv_imgproc opencv_ml opencv_nonfree opencv_objdetect opencv_photo) | |
| 75 | 74 | set(BR_THIRDPARTY_LIBS ${BR_THIRDPARTY_LIBS} ${OpenCV_LIBS}) |
| 76 | -set(OPENCV_DEPENDENCIES calib3d contrib core features2d flann gpu highgui imgproc legacy ml nonfree objdetect photo stitching video videostab) | |
| 75 | + | |
| 76 | +# Find NaturalStringCompare | |
| 77 | +find_package(NaturalStringCompare REQUIRED) | |
| 77 | 78 | |
| 78 | 79 | # Compiler flags |
| 79 | 80 | if(UNIX) | ... | ... |
app/examples/CMakeLists.txt
| ... | ... | @@ -5,5 +5,5 @@ foreach(EXAMPLE ${EXAMPLES}) |
| 5 | 5 | qt5_use_modules(${EXAMPLE_BASENAME} ${QT_DEPENDENCIES}) |
| 6 | 6 | target_link_libraries(${EXAMPLE_BASENAME} openbr ${BR_THIRDPARTY_LIBS}) |
| 7 | 7 | install(TARGETS ${EXAMPLE_BASENAME} RUNTIME DESTINATION bin) |
| 8 | - add_test("${EXAMPLE_BASENAME}_test" ${EXAMPLE_BASENAME}) | |
| 8 | + add_test(NAME ${EXAMPLE_BASENAME}_test WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMAND ${EXAMPLE_BASENAME}) | |
| 9 | 9 | endforeach() | ... | ... |
app/openbr-gui/CMakeLists.txt
| ... | ... | @@ -13,7 +13,6 @@ if(NOT ${BR_EMBEDDED}) |
| 13 | 13 | SOVERSION ${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR} |
| 14 | 14 | LINK_INTERFACE_LIBRARIES "") |
| 15 | 15 | target_link_libraries(openbr-gui openbr ${OpenCV_LIBS}) |
| 16 | - add_cppcheck(openbr-gui) | |
| 17 | 16 | |
| 18 | 17 | install(FILES ${HEADERS} DESTINATION include/openbr-gui) |
| 19 | 18 | install(TARGETS openbr-gui RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION lib) | ... | ... |
sdk/CMakeLists.txt
| ... | ... | @@ -7,7 +7,7 @@ aux_source_directory(. SRC) |
| 7 | 7 | aux_source_directory(core BR_CORE) |
| 8 | 8 | include(plugins/plugins.cmake) |
| 9 | 9 | |
| 10 | -add_library(openbr SHARED ${SRC} ${BR_CORE} ${BR_PLUGIN} ${BR_THIRDPARTY_SRC} ${BR_RESOURCES}) | |
| 10 | +add_library(openbr SHARED ${SRC} ${BR_CORE} ${BR_PLUGIN} ${BR_THIRDPARTY_SRC} ${BR_RESOURCES} ${NATURALSTRINGCOMPARE_SRC}) | |
| 11 | 11 | qt5_use_modules(openbr ${QT_DEPENDENCIES}) |
| 12 | 12 | set_target_properties(openbr PROPERTIES |
| 13 | 13 | DEFINE_SYMBOL BR_LIBRARY | ... | ... |
sdk/core/core.cpp
| ... | ... | @@ -174,12 +174,19 @@ struct AlgorithmCore |
| 174 | 174 | |
| 175 | 175 | void retrieveOrEnroll(const File &file, QScopedPointer<Gallery> &gallery, FileList &galleryFiles) |
| 176 | 176 | { |
| 177 | - gallery.reset(Gallery::make(file)); | |
| 178 | - if ((file.suffix() != "gal") && (file.suffix() != "mem")) { | |
| 179 | - enroll(file); | |
| 180 | - gallery.reset(Gallery::make(getMemoryGallery(file))); | |
| 177 | + if ((file.suffix() == "gal") || (file.suffix() == "mem")) { | |
| 178 | + // Retrieve it | |
| 179 | + gallery.reset(Gallery::make(file)); | |
| 181 | 180 | galleryFiles = gallery->files(); |
| 182 | 181 | } else { |
| 182 | + // Was it already enrolled in memory? | |
| 183 | + gallery.reset(Gallery::make(getMemoryGallery(file))); | |
| 184 | + galleryFiles = gallery->files(); | |
| 185 | + if (!galleryFiles.isEmpty()) return; | |
| 186 | + | |
| 187 | + // Enroll it | |
| 188 | + enroll(file); | |
| 189 | + gallery.reset(Gallery::make(getMemoryGallery(file))); | |
| 183 | 190 | galleryFiles = gallery->files(); |
| 184 | 191 | } |
| 185 | 192 | } |
| ... | ... | @@ -242,7 +249,7 @@ private: |
| 242 | 249 | if (!file.isEmpty()) description = file; |
| 243 | 250 | |
| 244 | 251 | if (QFileInfo(description).exists()) { |
| 245 | - qDebug("Loading %s", qPrintable(QFileInfo(description).fileName())); | |
| 252 | + if (Globals->verbose) qDebug("Loading %s", qPrintable(QFileInfo(description).fileName())); | |
| 246 | 253 | load(description); |
| 247 | 254 | return; |
| 248 | 255 | } | ... | ... |
sdk/core/qtutils.cpp
| ... | ... | @@ -28,6 +28,7 @@ |
| 28 | 28 | #include <QUrl> |
| 29 | 29 | #include <openbr_plugin.h> |
| 30 | 30 | |
| 31 | +#include "NaturalStringCompare.h" | |
| 31 | 32 | #include "qtutils.h" |
| 32 | 33 | |
| 33 | 34 | using namespace br; |
| ... | ... | @@ -37,12 +38,12 @@ QStringList QtUtils::getFiles(QDir dir, bool recursive) |
| 37 | 38 | dir = QDir(dir.canonicalPath()); |
| 38 | 39 | |
| 39 | 40 | QStringList files; |
| 40 | - foreach (const QString &file, dir.entryList(QDir::Files)) | |
| 41 | + foreach (const QString &file, NaturalStringSort(dir.entryList(QDir::Files))) | |
| 41 | 42 | files.append(QDir::cleanPath(dir.absoluteFilePath(file))); |
| 42 | 43 | |
| 43 | 44 | if (!recursive) return files; |
| 44 | 45 | |
| 45 | - foreach (const QString &folder, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) { | |
| 46 | + foreach (const QString &folder, NaturalStringSort(dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot))) { | |
| 46 | 47 | QDir subdir(dir); |
| 47 | 48 | bool success = subdir.cd(folder); if (!success) qFatal("cd failure."); |
| 48 | 49 | files.append(getFiles(subdir, true)); | ... | ... |
sdk/openbr_export.cpp
| ... | ... | @@ -84,19 +84,18 @@ $ br -help |
| 84 | 84 | * -# Grab any available <a href="http://www.microsoft.com/visualstudio/eng/downloads#d-visual-studio-2012-update">Visual Studio Updates</a>. |
| 85 | 85 | * -# <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. |
| 86 | 86 | * -# During installation setup select "add CMake to PATH". |
| 87 | - * -# <a href="http://sourceforge.net/projects/opencvlibrary/files/opencv-unix/2.4.3/OpenCV-2.4.3.tar.bz2/download">Download OpenCV 2.4.3</a> and unarchive. | |
| 87 | + * -# <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>. | |
| 88 | 88 | * -# Consider the free open source program <a href="http://www.7-zip.org/">7-Zip</a> if you need a program to unarchive tarballs. |
| 89 | - * -# Move the "OpenCV-2.4.3" folder to "C:\". | |
| 90 | - * -# In "C:\OpenCV-2.4.3\modules\objdetect\src\haar.cpp" line 55, change "#ifdev CV_AVX" to "#ifdef 0". | |
| 89 | + * -# Move the "OpenCV-2.4.4" folder to "C:\". | |
| 91 | 90 | * -# 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: |
| 92 | 91 | * \code |
| 93 | - * $ cd C:\OpenCV-2.4.3 | |
| 92 | + * $ cd C:\OpenCV-2.4.4 | |
| 94 | 93 | * $ mkdir build-msvc2012 |
| 95 | 94 | * $ cd build-msvc2012 |
| 96 | - * $ cmake -G "NMake Makefiles" -D BUILD_PERF_TESTS=OFF -D BUILD_TESTS=OFF -D WITH_FFMPEG=OFF -D CMAKE_BUILD_TYPE=Debug .. | |
| 95 | + * $ 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 .. | |
| 97 | 96 | * $ nmake |
| 98 | 97 | * $ nmake install |
| 99 | - * $ cmake -D CMAKE_BUILD_TYPE=Release .. | |
| 98 | + * $ cmake -DCMAKE_BUILD_TYPE=Release .. | |
| 100 | 99 | * $ nmake |
| 101 | 100 | * $ nmake install |
| 102 | 101 | * $ nmake clean |
| ... | ... | @@ -129,7 +128,7 @@ $ br -help |
| 129 | 128 | * $ cd C:\openbr |
| 130 | 129 | * $ mkdir build-msvc2012 |
| 131 | 130 | * $ cd build-msvc2012 |
| 132 | - * $ cmake -G "CodeBlocks - NMake Makefiles" -D CMAKE_PREFIX_PATH="C:/OpenCV-2.4.3/build-msvc2012/install;C:/Qt/5.0.1/msvc2012" -D CMAKE_INSTALL_PREFIX="./install" -D BR_INSTALL_DEPENDENCIES=ON -D CMAKE_BUILD_TYPE=Release .. | |
| 131 | + * $ 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 .. | |
| 133 | 132 | * $ nmake |
| 134 | 133 | * $ nmake install |
| 135 | 134 | * \endcode |
| ... | ... | @@ -164,18 +163,18 @@ $ br -help |
| 164 | 163 | * -# Move "x86_64-w64-mingw32-gcc-4.7.2-release-win64_rubenvb\mingw64" to "C:\". |
| 165 | 164 | * -# <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. |
| 166 | 165 | * -# During installation setup select "add CMake to PATH". |
| 167 | - * -# <a href="http://sourceforge.net/projects/opencvlibrary/files/opencv-unix/2.4.3/OpenCV-2.4.3.tar.bz2/download">Download OpenCV 2.4.3</a> and unarchive. | |
| 166 | + * -# <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>. | |
| 168 | 167 | * -# Consider the free open source program <a href="http://www.7-zip.org/">7-Zip</a> if you need a program to unarchive tarballs. |
| 169 | - * -# Move the "OpenCV-2.4.3" folder to "C:\". | |
| 168 | + * -# Move the "OpenCV-2.4.4" folder to "C:\". | |
| 170 | 169 | * -# From the MinGW-w64 Command Prompt (double-click "C:\mingw64\mingw64env.cmd"): |
| 171 | 170 | * \code |
| 172 | - * $ cd C:\OpenCV-2.4.3 | |
| 171 | + * $ cd C:\OpenCV-2.4.4 | |
| 173 | 172 | * $ mkdir build-mingw64 |
| 174 | 173 | * $ cd build-mingw64 |
| 175 | - * $ cmake -G "MinGW Makefiles" -D BUILD_PERF_TESTS=OFF -D BUILD_TESTS=OFF -D WITH_FFMPEG=OFF -D CMAKE_BUILD_TYPE=Debug .. | |
| 174 | + * $ 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 .. | |
| 176 | 175 | * $ mingw32-make |
| 177 | 176 | * $ mingw32-make install |
| 178 | - * $ cmake -D CMAKE_BUILD_TYPE=Release | |
| 177 | + * $ cmake -DCMAKE_BUILD_TYPE=Release | |
| 179 | 178 | * $ mingw32-make |
| 180 | 179 | * $ mingw32-make install |
| 181 | 180 | * $ mingw32-make clean |
| ... | ... | @@ -208,7 +207,7 @@ $ br -help |
| 208 | 207 | * $ cd C:\openbr |
| 209 | 208 | * $ mkdir build-mingw64 |
| 210 | 209 | * $ cd build-mingw64 |
| 211 | - * $ cmake -G "CodeBlocks - MinGW Makefiles" -D CMAKE_RC_COMPILER="C:/mingw64/bin/windres.exe" -D CMAKE_PREFIX_PATH="C:/OpenCV-2.4.3/build-mingw64/install;C:/Qt/5.0.1/mingw64" -D CMAKE_INSTALL_PREFIX="./install" -D BR_INSTALL_DEPENDENCIES=ON -D CMAKE_BUILD_TYPE=Release .. | |
| 210 | + * $ 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 .. | |
| 212 | 211 | * $ mingw32-make |
| 213 | 212 | * $ mingw32-make install |
| 214 | 213 | * \endcode |
| ... | ... | @@ -250,18 +249,18 @@ $ br -help |
| 250 | 249 | * $ cd .. |
| 251 | 250 | * $ rm -r cmake-2.8.10.2 |
| 252 | 251 | * \endcode |
| 253 | - * -# <a href="http://sourceforge.net/projects/opencvlibrary/files/opencv-unix/2.4.3/OpenCV-2.4.3.tar.bz2/download">Download OpenCV 2.4.3</a>. | |
| 252 | + * -# <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>. | |
| 254 | 253 | * \code |
| 255 | 254 | * $ cd ~/Downloads |
| 256 | - * $ tar -xf OpenCV-2.4.3.tar.bz2 | |
| 257 | - * $ cd OpenCV-2.4.3 | |
| 255 | + * $ tar -xf OpenCV-2.4.4.tar.bz2 | |
| 256 | + * $ cd OpenCV-2.4.4 | |
| 258 | 257 | * $ mkdir build |
| 259 | 258 | * $ cd build |
| 260 | - * $ cmake .. | |
| 259 | + * $ cmake -DBUILD_opencv_java=OFF -DBUILD_opencv_world=OFF -DCMAKE_BUILD_TYPE=Release .. | |
| 261 | 260 | * $ make -j4 |
| 262 | 261 | * $ sudo make install |
| 263 | 262 | * $ cd ../.. |
| 264 | - * $ rm -r OpenCV-2.4.3 | |
| 263 | + * $ rm -r OpenCV-2.4.4 | |
| 265 | 264 | * \endcode |
| 266 | 265 | * -# <a href="http://releases.qt-project.org/qt5/5.0.1/qt-mac-opensource-5.0.1-clang-offline.dmg">Download Qt 5.0.1</a> and install. |
| 267 | 266 | * -# 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>. |
| ... | ... | @@ -276,7 +275,7 @@ $ br -help |
| 276 | 275 | * $ cd openbr |
| 277 | 276 | * $ mkdir build |
| 278 | 277 | * $ cd build |
| 279 | - * $ cmake -D CMAKE_PREFIX_PATH=~/Qt5.0.1/5.0.1/clang_64 -D CMAKE_BUILD_TYPE=Release .. | |
| 278 | + * $ cmake -DCMAKE_PREFIX_PATH=~/Qt5.0.1/5.0.1/clang_64 -DCMAKE_BUILD_TYPE=Release .. | |
| 280 | 279 | * $ make -j4 |
| 281 | 280 | * $ make install |
| 282 | 281 | * \endcode |
| ... | ... | @@ -296,7 +295,7 @@ $ br -help |
| 296 | 295 | * $ make package |
| 297 | 296 | * \endcode |
| 298 | 297 | * -# Build OpenBR documentation! |
| 299 | - * -# <a href="ftp://ftp.stack.nl/pub/users/dimitri/doxygen-1.8.3.1.src.tar.gz">Download Doxygen 1.8.3.1</a> and install: | |
| 298 | + * -# <a href="ftp://ftp.stack.nl/pub/users/dimitri/doxygen-1.8.2.src.tar.gz">Download Doxygen 1.8.2</a> and install: | |
| 300 | 299 | * \code |
| 301 | 300 | * $ cd ~/Downloads |
| 302 | 301 | * $ tar -xf doxygen-1.8.2.src.tar.gz |
| ... | ... | @@ -310,7 +309,7 @@ $ br -help |
| 310 | 309 | * -# Modify build settings and recompile: |
| 311 | 310 | * \code |
| 312 | 311 | * $ cd openbr/build |
| 313 | - * $ cmake -D BR_BUILD_DOCUMENTATION=ON .. | |
| 312 | + * $ cmake -DBR_BUILD_DOCUMENTATION=ON .. | |
| 314 | 313 | * $ make -j4 |
| 315 | 314 | * $ open html/index.html |
| 316 | 315 | * \endcode |
| ... | ... | @@ -334,18 +333,18 @@ $ br -help |
| 334 | 333 | * $ cd .. |
| 335 | 334 | * $ rm -r cmake-2.8.10.2 |
| 336 | 335 | * \endcode |
| 337 | - * -# <a href="http://sourceforge.net/projects/opencvlibrary/files/opencv-unix/2.4.3/OpenCV-2.4.3.tar.bz2/download">Download OpenCV 2.4.3</a>. | |
| 336 | + * -# <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>. | |
| 338 | 337 | * \code |
| 339 | 338 | * $ cd ~/Downloads |
| 340 | - * $ tar -xf OpenCV-2.4.3.tar.bz2 | |
| 341 | - * $ cd OpenCV-2.4.3 | |
| 339 | + * $ tar -xf OpenCV-2.4.4.tar.bz2 | |
| 340 | + * $ cd OpenCV-2.4.4 | |
| 342 | 341 | * $ mkdir build |
| 343 | 342 | * $ cd build |
| 344 | - * $ cmake -D CMAKE_BUILD_TYPE=Release .. | |
| 343 | + * $ cmake -DBUILD_opencv_java=OFF -DBUILD_opencv_world=ON -DCMAKE_BUILD_TYPE=Release .. | |
| 345 | 344 | * $ make -j4 |
| 346 | 345 | * $ sudo make install |
| 347 | 346 | * $ cd ../.. |
| 348 | - * $ rm -r OpenCV-2.4.3 | |
| 347 | + * $ rm -r OpenCV-2.4.4 | |
| 349 | 348 | * \endcode |
| 350 | 349 | * -# <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>. |
| 351 | 350 | * \code |
| ... | ... | @@ -366,7 +365,7 @@ $ br -help |
| 366 | 365 | * $ cd openbr |
| 367 | 366 | * $ mkdir build |
| 368 | 367 | * $ cd build |
| 369 | - * $ cmake -D CMAKE_PREFIX_PATH=~/Qt5.0.1/5.0.1/gcc_64 -D CMAKE_BUILD_TYPE=Release .. | |
| 368 | + * $ cmake -DCMAKE_PREFIX_PATH=~/Qt5.0.1/5.0.1/gcc_64 -DCMAKE_BUILD_TYPE=Release .. | |
| 370 | 369 | * $ make -j4 |
| 371 | 370 | * $ make install |
| 372 | 371 | * \endcode |
| ... | ... | @@ -401,18 +400,18 @@ $ br -help |
| 401 | 400 | * $ cd .. |
| 402 | 401 | * $ rm -r cmake-2.8.10.2 |
| 403 | 402 | * \endcode |
| 404 | - * -# <a href="http://sourceforge.net/projects/opencvlibrary/files/opencv-unix/2.4.3/OpenCV-2.4.3.tar.bz2/download">Download OpenCV 2.4.3</a>. | |
| 403 | + * -# <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>. | |
| 405 | 404 | * \code |
| 406 | 405 | * $ cd ~/Downloads |
| 407 | - * $ tar -xf OpenCV-2.4.3.tar.bz2 | |
| 408 | - * $ cd OpenCV-2.4.3 | |
| 406 | + * $ tar -xf OpenCV-2.4.4.tar.bz2 | |
| 407 | + * $ cd OpenCV-2.4.4 | |
| 409 | 408 | * $ mkdir build |
| 410 | 409 | * $ cd build |
| 411 | - * $ cmake -D CMAKE_BUILD_TYPE=Release .. | |
| 410 | + * $ cmake cmake -DBUILD_opencv_java=OFF -DBUILD_opencv_world=ON -DCMAKE_BUILD_TYPE=Release .. | |
| 412 | 411 | * $ make -j4 |
| 413 | 412 | * $ sudo make install |
| 414 | 413 | * $ cd ../.. |
| 415 | - * $ rm -r OpenCV-2.4.3 | |
| 414 | + * $ rm -r OpenCV-2.4.4 | |
| 416 | 415 | * \endcode |
| 417 | 416 | * -# <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>. |
| 418 | 417 | * \code |
| ... | ... | @@ -433,7 +432,7 @@ $ br -help |
| 433 | 432 | * $ cd openbr |
| 434 | 433 | * $ mkdir build-icc |
| 435 | 434 | * $ cd build-icc |
| 436 | - * $ cmake -D CMAKE_C_COMPILER=/opt/intel/bin/icc -D CMAKE_CXX_COMPILER=/opt/intel/bin/icpc -D CMAKE_PREFIX_PATH=~/Qt5.0.1/5.0.1/gcc_64 -D CMAKE_BUILD_TYPE=Release .. | |
| 435 | + * $ 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 .. | |
| 437 | 436 | * $ make -j4 |
| 438 | 437 | * $ make install |
| 439 | 438 | * \endcode | ... | ... |
sdk/openbr_plugin.cpp
| ... | ... | @@ -24,9 +24,9 @@ |
| 24 | 24 | #ifdef BR_DISTRIBUTED |
| 25 | 25 | #include <mpi.h> |
| 26 | 26 | #endif // BR_DISTRIBUTED |
| 27 | -#include <openbr_plugin.h> | |
| 28 | - | |
| 29 | 27 | #include <algorithm> |
| 28 | +#include <iostream> | |
| 29 | +#include <openbr_plugin.h> | |
| 30 | 30 | |
| 31 | 31 | #include "version.h" |
| 32 | 32 | #include "core/bee.h" |
| ... | ... | @@ -450,10 +450,10 @@ QDataStream &br::operator>>(QDataStream &stream, Template &t) |
| 450 | 450 | TemplateList TemplateList::fromGallery(const br::File &gallery) |
| 451 | 451 | { |
| 452 | 452 | TemplateList templates; |
| 453 | - | |
| 454 | 453 | foreach (const br::File &file, gallery.split()) { |
| 455 | 454 | QScopedPointer<Gallery> i(Gallery::make(file)); |
| 456 | 455 | TemplateList newTemplates = i->read(); |
| 456 | + newTemplates = newTemplates.mid(gallery.getInt("pos", 0), gallery.getInt("length", -1)); | |
| 457 | 457 | if (gallery.getBool("reduce")) newTemplates = newTemplates.reduced(); |
| 458 | 458 | const int crossValidate = gallery.getInt("crossValidate"); |
| 459 | 459 | if (crossValidate > 0) srand(0); |
| ... | ... | @@ -940,7 +940,7 @@ void br::Context::messageHandler(QtMsgType type, const QMessageLogContext &conte |
| 940 | 940 | break; |
| 941 | 941 | } |
| 942 | 942 | |
| 943 | - fprintf(stderr, "%s", qPrintable(txt)); | |
| 943 | + std::cerr << txt.toStdString(); | |
| 944 | 944 | Globals->mostRecentMessage = txt; |
| 945 | 945 | |
| 946 | 946 | if (Globals->logFile.isWritable()) { | ... | ... |
sdk/plugins/draw.cpp
| ... | ... | @@ -33,7 +33,13 @@ class DrawTransform : public UntrainableTransform |
| 33 | 33 | { |
| 34 | 34 | Q_OBJECT |
| 35 | 35 | Q_PROPERTY(bool verbose READ get_verbose WRITE set_verbose RESET reset_verbose STORED false) |
| 36 | + Q_PROPERTY(bool named READ get_named WRITE set_named RESET reset_named STORED false) | |
| 37 | + Q_PROPERTY(bool unnamed READ get_unnamed WRITE set_unnamed RESET reset_unnamed STORED false) | |
| 38 | + Q_PROPERTY(bool ROI READ get_ROI WRITE set_ROI RESET reset_ROI STORED false) | |
| 36 | 39 | BR_PROPERTY(bool, verbose, false) |
| 40 | + BR_PROPERTY(bool, named, true) | |
| 41 | + BR_PROPERTY(bool, unnamed, true) | |
| 42 | + BR_PROPERTY(bool, ROI, true) | |
| 37 | 43 | |
| 38 | 44 | void project(const Template &src, Template &dst) const |
| 39 | 45 | { |
| ... | ... | @@ -43,14 +49,20 @@ class DrawTransform : public UntrainableTransform |
| 43 | 49 | |
| 44 | 50 | QList<Point2f> landmarks = OpenCVUtils::toPoints(src.file.landmarks()); |
| 45 | 51 | |
| 46 | - foreach (const Point2f &landmark, landmarks) | |
| 47 | - circle(dst, landmark, 3, color, -1); | |
| 48 | - QList<Point2f> namedLandmarks = OpenCVUtils::toPoints(src.file.namedLandmarks()); | |
| 49 | - foreach (const Point2f &landmark, namedLandmarks) | |
| 50 | - circle(dst, landmark, 3, color); | |
| 51 | - QList<Rect> ROIs = OpenCVUtils::toRects(src.file.ROIs()); | |
| 52 | - foreach (const Rect ROI, ROIs) | |
| 53 | - rectangle(dst, ROI, color); | |
| 52 | + if (unnamed) { | |
| 53 | + foreach (const Point2f &landmark, landmarks) | |
| 54 | + circle(dst, landmark, 3, color, -1); | |
| 55 | + } | |
| 56 | + if (named) { | |
| 57 | + QList<Point2f> namedLandmarks = OpenCVUtils::toPoints(src.file.namedLandmarks()); | |
| 58 | + foreach (const Point2f &landmark, namedLandmarks) | |
| 59 | + circle(dst, landmark, 3, color); | |
| 60 | + } | |
| 61 | + if (ROI) { | |
| 62 | + QList<Rect> ROIs = OpenCVUtils::toRects(src.file.ROIs()); | |
| 63 | + foreach (const Rect ROI, ROIs) | |
| 64 | + rectangle(dst, ROI, color); | |
| 65 | + } | |
| 54 | 66 | |
| 55 | 67 | if (verbose) |
| 56 | 68 | for (int i=0; i<landmarks.size(); i++) | ... | ... |
sdk/plugins/gallery.cpp
| ... | ... | @@ -24,6 +24,7 @@ |
| 24 | 24 | #endif // BR_EMBEDDED |
| 25 | 25 | #include <openbr_plugin.h> |
| 26 | 26 | |
| 27 | +#include "NaturalStringCompare.h" | |
| 27 | 28 | #include "core/bee.h" |
| 28 | 29 | #include "core/opencvutils.h" |
| 29 | 30 | #include "core/qtutils.h" |
| ... | ... | @@ -102,7 +103,7 @@ class EmptyGallery : public Gallery |
| 102 | 103 | |
| 103 | 104 | // Add immediate subfolders |
| 104 | 105 | QDir dir(file); |
| 105 | - foreach (const QString &folder, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) | |
| 106 | + foreach (const QString &folder, NaturalStringSort(dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot))) | |
| 106 | 107 | foreach (const QString &file, QtUtils::getFiles(dir.absoluteFilePath(folder), true)) |
| 107 | 108 | templates.append(File(file, folder)); |
| 108 | 109 | ... | ... |
sdk/plugins/misc.cpp
| ... | ... | @@ -40,7 +40,7 @@ class OpenTransform : public UntrainableMetaTransform |
| 40 | 40 | foreach (const File &file, src.file.split()) { |
| 41 | 41 | QScopedPointer<Format> format(Factory<Format>::make(file)); |
| 42 | 42 | Template t = format->read(); |
| 43 | - if (t.isEmpty()) qWarning("Can't open %s", qPrintable(file.flat())); | |
| 43 | + if (t.isEmpty()) qWarning("Can't open %s from %s", qPrintable(file.flat()), qPrintable(QDir::currentPath())); | |
| 44 | 44 | dst.append(t); |
| 45 | 45 | dst.file.append(t.file.localMetadata()); |
| 46 | 46 | } | ... | ... |
sdk/plugins/neclatent1.cpp
| ... | ... | @@ -19,7 +19,8 @@ class NECLatent1Initialier : public Initializer |
| 19 | 19 | |
| 20 | 20 | void initialize() const |
| 21 | 21 | { |
| 22 | - Globals->abbreviations.insert("NECLatent1", "Open+Cvt(Gray)+NECLatent1Enroll:NECLatent1Compare"); | |
| 22 | + Globals->abbreviations.insert("NECTenprint1", "Open+Cvt(Gray)+NECLatent1Enroll:NECLatent1Compare"); | |
| 23 | + Globals->abbreviations.insert("NECLatent1", "Open+Cvt(Gray)+NECLatent1Enroll(true):NECLatent1Compare"); | |
| 23 | 24 | } |
| 24 | 25 | }; |
| 25 | 26 | |
| ... | ... | @@ -29,17 +30,38 @@ BR_REGISTER(Initializer, NECLatent1Initialier) |
| 29 | 30 | * \ingroup transforms |
| 30 | 31 | * \brief Enroll an NEC latent fingerprint. |
| 31 | 32 | * \author Josh Klontz \cite jklontz |
| 33 | + * \warning Applications using this transform must have their working directory be the 'bin/win/32' folder of the NEC Latent SDK. | |
| 32 | 34 | */ |
| 33 | 35 | class NECLatent1EnrollTransform : public UntrainableTransform |
| 34 | 36 | { |
| 35 | 37 | Q_OBJECT |
| 38 | + Q_ENUMS(Algorithm) | |
| 39 | + Q_PROPERTY(bool latent READ get_latent WRITE set_latent RESET reset_latent STORED false) | |
| 40 | + Q_PROPERTY(Algorithm algorithm READ get_algorithm WRITE set_algorithm RESET reset_algorithm STORED false) | |
| 41 | + | |
| 42 | +public: | |
| 43 | + enum Algorithm { LFML, | |
| 44 | + ELFT }; | |
| 45 | + | |
| 46 | +private: | |
| 47 | + BR_PROPERTY(bool, latent, false) | |
| 48 | + BR_PROPERTY(Algorithm, algorithm, LFML) | |
| 36 | 49 | |
| 37 | 50 | void project(const Template &src, Template &dst) const |
| 38 | 51 | { |
| 39 | 52 | if (src.m().type() != CV_8UC1) qFatal("Requires 8UC1 data!"); |
| 40 | - unsigned char *data = new unsigned char[MAX_TEMPLATE_SIZE]; | |
| 53 | + unsigned char data[MAX_TEMPLATE_SIZE]; | |
| 41 | 54 | int size = 0; |
| 42 | - int error = NEC_LFML_ExtractLatent(src.m().data, src.m().rows, src.m().cols, 500, data, &size); | |
| 55 | + int error; | |
| 56 | + | |
| 57 | + if (latent) { | |
| 58 | + if (algorithm == LFML) error = NEC_LFML_ExtractLatent(src.m().data, src.m().rows, src.m().cols, 500, data, &size); | |
| 59 | + else error = NEC_ELFT_ExtractLatent(src.m().data, src.m().rows, src.m().cols, 500, 4, data, &size); | |
| 60 | + } else { | |
| 61 | + if (algorithm == LFML) error = NEC_LFML_ExtractTenprint(src.m().data, src.m().rows, src.m().cols, 500, data, &size); | |
| 62 | + else error = NEC_ELFT_ExtractTenprint(src.m().data, src.m().rows, src.m().cols, 500, 2, data, &size); | |
| 63 | + } | |
| 64 | + | |
| 43 | 65 | if (!error) { |
| 44 | 66 | cv::Mat n(1, size, CV_8UC1); |
| 45 | 67 | memcpy(n.data, data, size); |
| ... | ... | @@ -49,8 +71,6 @@ class NECLatent1EnrollTransform : public UntrainableTransform |
| 49 | 71 | dst.m() = cv::Mat(); |
| 50 | 72 | dst.file.set("FTE", true); |
| 51 | 73 | } |
| 52 | - | |
| 53 | - delete[] data; | |
| 54 | 74 | } |
| 55 | 75 | }; |
| 56 | 76 | |
| ... | ... | @@ -64,12 +84,22 @@ BR_REGISTER(Transform, NECLatent1EnrollTransform) |
| 64 | 84 | class NECLatent1CompareDistance : public Distance |
| 65 | 85 | { |
| 66 | 86 | Q_OBJECT |
| 87 | + Q_ENUMS(Algorithm) | |
| 88 | + Q_PROPERTY(Algorithm algorithm READ get_algorithm WRITE set_algorithm RESET reset_algorithm STORED false) | |
| 89 | + | |
| 90 | +public: | |
| 91 | + enum Algorithm { LFML, | |
| 92 | + ELFT }; | |
| 93 | + | |
| 94 | +private: | |
| 95 | + BR_PROPERTY(Algorithm, algorithm, LFML) | |
| 67 | 96 | |
| 68 | 97 | float compare(const Template &a, const Template &b) const |
| 69 | 98 | { |
| 70 | 99 | if (!a.m().data || !b.m().data) return -std::numeric_limits<float>::max(); |
| 71 | 100 | int score; |
| 72 | - NEC_LFML_Verify(b.m().data, b.m().total(), a.m().data, a.m().total(), &score); | |
| 101 | + if (algorithm == LFML) NEC_LFML_Verify(b.m().data, b.m().total(), a.m().data, a.m().total(), &score); | |
| 102 | + else NEC_ELFT_Verify(b.m().data, a.m().data, &score, 2); | |
| 73 | 103 | return score; |
| 74 | 104 | } |
| 75 | 105 | }; | ... | ... |
sdk/plugins/reduce.cpp
| ... | ... | @@ -107,11 +107,11 @@ private: |
| 107 | 107 | if ((statistic == Min) || (statistic == Max)) { |
| 108 | 108 | double min, max; |
| 109 | 109 | minMaxLoc(src, &min, &max); |
| 110 | - m.at<float>(1, 1) = (statistic == Min ? min : max); | |
| 110 | + m.at<float>(0,0) = (statistic == Min ? min : max); | |
| 111 | 111 | } else { |
| 112 | 112 | Scalar mean, stddev; |
| 113 | 113 | meanStdDev(src, mean, stddev); |
| 114 | - m.at<float>(1,1) = (statistic == Mean ? mean[0] : stddev[0]); | |
| 114 | + m.at<float>(0,0) = (statistic == Mean ? mean[0] : stddev[0]); | |
| 115 | 115 | } |
| 116 | 116 | dst = m; |
| 117 | 117 | } |
| ... | ... | @@ -122,6 +122,7 @@ BR_REGISTER(Transform, StatTransform) |
| 122 | 122 | /*! |
| 123 | 123 | * \ingroup transforms |
| 124 | 124 | * \brief Downsample the rows and columns of a matrix. |
| 125 | + * \author Lacey Best-Rowden \cite lbestrowden | |
| 125 | 126 | */ |
| 126 | 127 | class DownsampleTransform : public UntrainableTransform |
| 127 | 128 | { |
| ... | ... | @@ -131,9 +132,15 @@ class DownsampleTransform : public UntrainableTransform |
| 131 | 132 | |
| 132 | 133 | void project(const Template &src, Template &dst) const |
| 133 | 134 | { |
| 135 | + if (src.m().channels() != 1) | |
| 136 | + qFatal("Expected 1 channel matrix."); | |
| 134 | 137 | Mat input = src.m(); |
| 135 | - Mat output; | |
| 136 | - (void) input; // TODO: write me! | |
| 138 | + Mat output(ceil((double)input.rows/k), ceil((double)input.cols/k), CV_32FC1); | |
| 139 | + for (int r=0; r<output.rows; r++) { | |
| 140 | + for (int c=0; c<output.cols; c++) { | |
| 141 | + output.at<float>(r,c) = input.at<float>(r*k,c*k); | |
| 142 | + } | |
| 143 | + } | |
| 137 | 144 | dst.m() = output; |
| 138 | 145 | } |
| 139 | 146 | }; | ... | ... |
share/openbr/cmake/FindNaturalStringCompare.cmake
0 → 100644
share/openbr/cmake/InstallDependencies.cmake
| ... | ... | @@ -10,17 +10,12 @@ function(install_opencv_library lib) |
| 10 | 10 | if(NOT MSVC) |
| 11 | 11 | set(BR_INSTALL_DEPENDENCIES_PREFIX "lib") |
| 12 | 12 | endif() |
| 13 | - install(FILES ${OpenCV_DIR}/bin/${BR_INSTALL_DEPENDENCIES_PREFIX}opencv_${lib}${OpenCV_VERSION_MAJOR}${OpenCV_VERSION_MINOR}${OpenCV_VERSION_PATCH}${BR_INSTALL_DEPENDENCIES_SUFFIX}.dll DESTINATION bin) | |
| 14 | - elseif(CMAKE_HOST_APPLE) | |
| 15 | - set(OpenCV_LIB_DIR "/usr/local/lib") | |
| 16 | - install(FILES ${OpenCV_LIB_DIR}/libopencv_${lib}.${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.${OpenCV_VERSION_PATCH}.dylib DESTINATION lib) | |
| 17 | - install(FILES ${OpenCV_LIB_DIR}/libopencv_${lib}.${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.dylib DESTINATION lib) | |
| 18 | - install(FILES ${OpenCV_LIB_DIR}/libopencv_${lib}.dylib DESTINATION lib) | |
| 13 | + install(FILES ${OpenCV_DIR}/bin/${BR_INSTALL_DEPENDENCIES_PREFIX}${lib}${OpenCV_VERSION_MAJOR}${OpenCV_VERSION_MINOR}${OpenCV_VERSION_PATCH}${BR_INSTALL_DEPENDENCIES_SUFFIX}.dll DESTINATION bin) | |
| 19 | 14 | else() |
| 20 | 15 | set(OpenCV_LIB_DIR "/usr/local/lib") |
| 21 | - install(FILES ${OpenCV_LIB_DIR}/libopencv_${lib}.so.${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.${OpenCV_VERSION_PATCH} DESTINATION lib) | |
| 22 | - install(FILES ${OpenCV_LIB_DIR}/libopencv_${lib}.so.${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR} DESTINATION lib) | |
| 23 | - install(FILES ${OpenCV_LIB_DIR}/libopencv_${lib}.so DESTINATION lib) | |
| 16 | + install(FILES ${OpenCV_LIB_DIR}/lib${lib}.${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.${OpenCV_VERSION_PATCH}${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION lib) | |
| 17 | + install(FILES ${OpenCV_LIB_DIR}/lib${lib}.${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION lib) | |
| 18 | + install(FILES ${OpenCV_LIB_DIR}/lib${lib}${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION lib) | |
| 24 | 19 | endif() |
| 25 | 20 | endif() |
| 26 | 21 | endfunction() | ... | ... |
share/openbr/openbr.bib
| ... | ... | @@ -28,6 +28,11 @@ |
| 28 | 28 | Author = {Charles A. Otto}, |
| 29 | 29 | Howpublished = {https://github.com/caotto}, |
| 30 | 30 | Title = {ottochar at gmail.com}} |
| 31 | + | |
| 32 | +@misc{lbestrowden, | |
| 33 | + Author = {Lacey S. Best-Rowden}, | |
| 34 | + Howpublished = {https://github.com/lbestrowden}, | |
| 35 | + Title = {bestrow1 at msu.edu}} | |
| 31 | 36 | |
| 32 | 37 | |
| 33 | 38 | % Software | ... | ... |