Commit 71a036f54767b094aeed26e542d07ba5206c6209

Authored by Charles Otto
2 parents 72a5968a 7dd634b3

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

openbr/core/common.h
@@ -153,11 +153,10 @@ void MeanStdDev(const V<T> &vals, double *mean, double *stddev) @@ -153,11 +153,10 @@ void MeanStdDev(const V<T> &vals, double *mean, double *stddev)
153 template<template<typename> class C, typename T> 153 template<template<typename> class C, typename T>
154 T Median(C<T> vals, T *q1 = 0, T *q3 = 0) 154 T Median(C<T> vals, T *q1 = 0, T *q3 = 0)
155 { 155 {
156 - if (vals.isEmpty()) return std::numeric_limits<float>::quiet_NaN();  
157 qSort(vals); 156 qSort(vals);
158 - if (q1 != 0) *q1 = vals[1*vals.size()/4];  
159 - if (q3 != 0) *q3 = vals[3*vals.size()/4];  
160 - return vals[vals.size()/2]; 157 + if (q1 != 0) *q1 = vals.isEmpty() ? 0 : vals[1*vals.size()/4];
  158 + if (q3 != 0) *q3 = vals.isEmpty() ? 0 : vals[3*vals.size()/4];
  159 + return vals.isEmpty() ? 0 : vals[vals.size()/2];
161 } 160 }
162 161
163 /*! 162 /*!
openbr/core/fuse.cpp
@@ -14,7 +14,6 @@ @@ -14,7 +14,6 @@
14 * limitations under the License. * 14 * limitations under the License. *
15 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 15 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
16 16
17 -#include <QFile>  
18 #include <QList> 17 #include <QList>
19 #include <QStringList> 18 #include <QStringList>
20 #include <limits> 19 #include <limits>
openbr/gui/imageviewer.cpp
@@ -36,7 +36,8 @@ void br::ImageViewer::setDefaultText(const QString &amp;text) @@ -36,7 +36,8 @@ void br::ImageViewer::setDefaultText(const QString &amp;text)
36 36
37 void br::ImageViewer::setImage(const QString &file, bool async) 37 void br::ImageViewer::setImage(const QString &file, bool async)
38 { 38 {
39 - src = QImage(file); 39 + if(file.isNull()) src = QImage(); // Gets rid of runtime FileEngine::open warning
  40 + else src = QImage(file);
40 updatePixmap(async); 41 updatePixmap(async);
41 } 42 }
42 43
openbr/openbr_export.cpp
@@ -24,7 +24,7 @@ @@ -24,7 +24,7 @@
24 * OpenBR originated within The MITRE Corporation from a need to streamline the process of prototyping new algorithms. 24 * OpenBR originated within The MITRE Corporation from a need to streamline the process of prototyping new algorithms.
25 * The project was later published as open source software under the <a href="http://www.apache.org/licenses/LICENSE-2.0.html">Apache 2</a> license and is <i>free for academic and commercial use</i>. 25 * The project was later published as open source software under the <a href="http://www.apache.org/licenses/LICENSE-2.0.html">Apache 2</a> license and is <i>free for academic and commercial use</i>.
26 * 26 *
27 - * \image html "share/openbr/abstraction.svg" "The two principal software artifacts are the shared library 'openbr' and command line application 'br'." 27 + * \image html "abstraction.svg" "The two principal software artifacts are the shared library 'openbr' and command line application 'br'."
28 * 28 *
29 * \section get_started Get Started 29 * \section get_started Get Started
30 * - \ref installation - \copybrief installation 30 * - \ref installation - \copybrief installation
@@ -70,13 +70,13 @@ $ export DYLD_FRAMEWORK_PATH=../lib:${DYLD_FRAMEWORK_PATH} @@ -70,13 +70,13 @@ $ export DYLD_FRAMEWORK_PATH=../lib:${DYLD_FRAMEWORK_PATH}
70 * No configuration is necessary! 70 * No configuration is necessary!
71 * 71 *
72 * \section installation_license_dongle License Dongle 72 * \section installation_license_dongle License Dongle
73 - * If you were given a USB License Dongle, then dongle must be in the computer in order to use the SDK. 73 + * In the unlikely event that you were given a USB License Dongle, then dongle must be in the computer in order to use the SDK.
74 * No configuration of the dongle is needed. 74 * No configuration of the dongle is needed.
75 * 75 *
76 * \section installation_done Start Working 76 * \section installation_done Start Working
77 * To test for successful installation: 77 * To test for successful installation:
78 \verbatim 78 \verbatim
79 -$ cd bin/ 79 +$ cd bin
80 $ br -help 80 $ br -help
81 \endverbatim 81 \endverbatim
82 */ 82 */
@@ -180,7 +180,7 @@ $ br -help @@ -180,7 +180,7 @@ $ br -help
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 .. 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 ..
181 * $ mingw32-make 181 * $ mingw32-make
182 * $ mingw32-make install 182 * $ mingw32-make install
183 - * $ cmake -DCMAKE_BUILD_TYPE=Release 183 + * $ cmake -DCMAKE_BUILD_TYPE=Release ..
184 * $ mingw32-make 184 * $ mingw32-make
185 * $ mingw32-make install 185 * $ mingw32-make install
186 * $ mingw32-make clean 186 * $ mingw32-make clean
@@ -244,7 +244,7 @@ $ br -help @@ -244,7 +244,7 @@ $ br -help
244 /*! 244 /*!
245 * \page osx_clang OS X Mountain Lion - Clang/LLVM 3.1 - x64 245 * \page osx_clang OS X Mountain Lion - Clang/LLVM 3.1 - x64
246 * -# Download and install the latest "Xcode" and "Command Line Tools" from the <a href="https://developer.apple.com/downloads/index.action#">Apple Developer Downloads</a> page. 246 * -# Download and install the latest "Xcode" and "Command Line Tools" from the <a href="https://developer.apple.com/downloads/index.action#">Apple Developer Downloads</a> page.
247 - * -# <a href="http://www.cmake.org/files/v2.8/cmake-2.8.10.2.tar.gz">Download CMake 2.8.10.2</a>. 247 + * -# <a href="http://www.cmake.org/files/v2.8/cmake-2.8.10.2.tar.gz">Download CMake 2.8.10.2</a>
248 * \code 248 * \code
249 * $ cd ~/Downloads 249 * $ cd ~/Downloads
250 * $ tar -xf cmake-2.8.10.2.tar.gz 250 * $ tar -xf cmake-2.8.10.2.tar.gz
@@ -253,22 +253,22 @@ $ br -help @@ -253,22 +253,22 @@ $ br -help
253 * $ make -j4 253 * $ make -j4
254 * $ sudo make install 254 * $ sudo make install
255 * $ cd .. 255 * $ cd ..
256 - * $ rm -r cmake-2.8.10.2 256 + * $ rm -rf cmake-2.8.10.2*
257 * \endcode 257 * \endcode
258 - * -# <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>. 258 + * -# <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>
259 * \code 259 * \code
260 * $ cd ~/Downloads 260 * $ cd ~/Downloads
261 - * $ tar -xf OpenCV-2.4.4.tar.bz2  
262 - * $ cd OpenCV-2.4.4 261 + * $ tar -xf opencv-2.4.5.tar.gz
  262 + * $ cd opencv-2.4.5
263 * $ mkdir build 263 * $ mkdir build
264 * $ cd build 264 * $ cd build
265 - * $ cmake -DBUILD_opencv_java=OFF -DBUILD_opencv_world=OFF -DCMAKE_BUILD_TYPE=Release .. 265 + * $ cmake -DCMAKE_BUILD_TYPE=Release ..
266 * $ make -j4 266 * $ make -j4
267 * $ sudo make install 267 * $ sudo make install
268 * $ cd ../.. 268 * $ cd ../..
269 - * $ rm -r OpenCV-2.4.4 269 + * $ rm -rf opencv-2.4.5*
270 * \endcode 270 * \endcode
271 - * -# <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. 271 + * -# <a href="http://download.qt-project.org/official_releases/qt/5.0/5.0.2/qt-mac-opensource-5.0.2-clang-offline.dmg">Download and install Qt 5.0.2</a>
272 * -# 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>. 272 * -# 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>.
273 * \code 273 * \code
274 * $ git clone https://github.com/biometrics/openbr.git 274 * $ git clone https://github.com/biometrics/openbr.git
@@ -281,27 +281,34 @@ $ br -help @@ -281,27 +281,34 @@ $ br -help
281 * $ cd openbr 281 * $ cd openbr
282 * $ mkdir build 282 * $ mkdir build
283 * $ cd build 283 * $ cd build
284 - * $ cmake -DCMAKE_PREFIX_PATH=~/Qt5.0.1/5.0.1/clang_64 -DCMAKE_BUILD_TYPE=Release .. 284 + * $ cmake -DCMAKE_PREFIX_PATH=~/Qt5.0.2/5.0.2/clang_64 -DCMAKE_BUILD_TYPE=Release ..
285 * $ make -j4 285 * $ make -j4
286 * $ sudo make install 286 * $ sudo make install
287 * \endcode 287 * \endcode
288 * -# Hack OpenBR! 288 * -# Hack OpenBR!
289 * -# Open Qt Creator IDE 289 * -# Open Qt Creator IDE
290 * \code 290 * \code
291 - * $ open ~/Qt5.0.1/Qt\ Creator.app 291 + * $ open ~/Qt5.0.2/Qt\ Creator.app
292 * \endcode 292 * \endcode
293 * -# From the Qt Creator "File" menu select "Open File or Project...". 293 * -# From the Qt Creator "File" menu select "Open File or Project...".
294 - * -# Select "~/openbr/CMakeLists.txt" then "Open".  
295 - * -# Browse to your prexisting build directory "~/openbr/build" then select "Continue". 294 + * -# Select "openbr/CMakeLists.txt" then "Open".
  295 + * -# Browse to your prexisting build directory "openbr/build" then select "Continue".
296 * -# Select "Run CMake" then "Done". 296 * -# Select "Run CMake" then "Done".
297 * -# 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. 297 * -# 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 + * -# (Optional) Test OpenBR!
  299 + * \code
  300 + * $ cd openbr/scripts
  301 + * $ ./downloadDatasets.sh
  302 + * $ cd ../build
  303 + * $ make test
  304 + * \endcode
298 * -# (Optional) Package OpenBR! 305 * -# (Optional) Package OpenBR!
299 * \code 306 * \code
300 * $ cd openbr/build 307 * $ cd openbr/build
301 - * $ make package 308 + * $ cpack -G TGZ
302 * \endcode 309 * \endcode
303 * -# (Optional) Build OpenBR documentation! 310 * -# (Optional) Build OpenBR documentation!
304 - * -# <a href="ftp://ftp.stack.nl/pub/users/dimitri/doxygen-1.8.2.src.tar.gz">Download Doxygen 1.8.2</a> and install: 311 + * -# <a href="ftp://ftp.stack.nl/pub/users/dimitri/doxygen-1.8.2.src.tar.gz">Download Doxygen 1.8.2</a>
305 * \code 312 * \code
306 * $ cd ~/Downloads 313 * $ cd ~/Downloads
307 * $ tar -xf doxygen-1.8.2.src.tar.gz 314 * $ tar -xf doxygen-1.8.2.src.tar.gz
@@ -310,9 +317,9 @@ $ br -help @@ -310,9 +317,9 @@ $ br -help
310 * $ make -j4 317 * $ make -j4
311 * $ sudo make install 318 * $ sudo make install
312 * $ cd .. 319 * $ cd ..
313 - * $ rm -r doxygen-1.8.2 320 + * $ rm -rf doxygen-1.8.2*
314 * \endcode 321 * \endcode
315 - * -# Modify build settings and recompile: 322 + * -# Modify build settings and recompile.
316 * \code 323 * \code
317 * $ cd openbr/build 324 * $ cd openbr/build
318 * $ cmake -DBR_BUILD_DOCUMENTATION=ON .. 325 * $ cmake -DBR_BUILD_DOCUMENTATION=ON ..
openbr/openbr_plugin.cpp
@@ -389,8 +389,6 @@ TemplateList TemplateList::fromGallery(const br::File &amp;gallery) @@ -389,8 +389,6 @@ TemplateList TemplateList::fromGallery(const br::File &amp;gallery)
389 if (crossValidate > 0) srand(0); 389 if (crossValidate > 0) srand(0);
390 390
391 for (int i=newTemplates.size()-1; i>=0; i--) { 391 for (int i=newTemplates.size()-1; i>=0; i--) {
392 - newTemplates[i].file.append(gallery.localMetadata());  
393 - newTemplates[i].file.append(file.localMetadata());  
394 newTemplates[i].file.set("Index", i+templates.size()); 392 newTemplates[i].file.set("Index", i+templates.size());
395 newTemplates[i].file.set("Gallery", gallery.name); 393 newTemplates[i].file.set("Gallery", gallery.name);
396 394
openbr/plugins/distance.cpp
@@ -298,46 +298,6 @@ class IdenticalDistance : public Distance @@ -298,46 +298,6 @@ class IdenticalDistance : public Distance
298 298
299 BR_REGISTER(Distance, IdenticalDistance) 299 BR_REGISTER(Distance, IdenticalDistance)
300 300
301 -class HeatMapDistance : public Distance  
302 -{  
303 - Q_OBJECT  
304 - Q_PROPERTY(br::Distance* distance READ get_distance WRITE set_distance RESET reset_distance STORED false)  
305 - BR_PROPERTY(br::Distance*, distance, make("Dist(L2)"))  
306 - Q_PROPERTY(int rows READ get_rows WRITE set_rows RESET reset_rows STORED false)  
307 - BR_PROPERTY(int, rows, -1)  
308 - Q_PROPERTY(int cols READ get_cols WRITE set_cols RESET reset_cols STORED false)  
309 - BR_PROPERTY(int, cols, -1)  
310 -  
311 - void train(const TemplateList &src)  
312 - {  
313 - distance->train(src);  
314 - }  
315 -  
316 -  
317 - float compare(const Template &a, const Template &b) const  
318 - {  
319 - qFatal("HeatMap expects a TemplateList");  
320 -  
321 - (void) a; (void) b;  
322 - }  
323 -  
324 - void compare(const TemplateList &target, const TemplateList &query, Output *output) const  
325 - {  
326 - if (rows*cols > target.size()) qFatal("Incompatible heatmap comparison dimensionality");  
327 -  
328 - int index = 0;  
329 - for (int col = 0; col < cols; col++) {  
330 - for (int row = 0; row < rows; row++) {  
331 - float score = distance->compare(target[index],query[index]);  
332 - output->setRelative(score, row, col);  
333 - index++;  
334 - }  
335 - }  
336 - }  
337 -};  
338 -  
339 -BR_REGISTER(Distance, HeatMapDistance)  
340 -  
341 } // namespace br 301 } // namespace br
342 302
343 #include "distance.moc" 303 #include "distance.moc"
openbr/plugins/output.cpp
@@ -97,33 +97,25 @@ BR_REGISTER(Output, csvOutput) @@ -97,33 +97,25 @@ BR_REGISTER(Output, csvOutput)
97 class heatOutput : public MatrixOutput 97 class heatOutput : public MatrixOutput
98 { 98 {
99 Q_OBJECT 99 Q_OBJECT
100 - Q_PROPERTY(int rows READ get_rows WRITE set_rows RESET reset_rows STORED false)  
101 - BR_PROPERTY(int, rows, -1)  
102 - Q_PROPERTY(int cols READ get_cols WRITE set_cols RESET reset_cols STORED false)  
103 - BR_PROPERTY(int, cols, -1) 100 + Q_PROPERTY(int patches READ get_patches WRITE set_patches RESET reset_patches STORED false)
  101 + BR_PROPERTY(int, patches, -1);
104 102
105 ~heatOutput() 103 ~heatOutput()
106 { 104 {
107 if (file.isNull() || targetFiles.isEmpty() || queryFiles.isEmpty()) return; 105 if (file.isNull() || targetFiles.isEmpty() || queryFiles.isEmpty()) return;
108 106
109 - if (rows*cols > targetFiles.size()) qFatal("Incompatible heatmap output dimensionality");  
110 -  
111 QStringList lines; 107 QStringList lines;
112 - for (int col = 0; col < cols; col++) {  
113 - QStringList words;  
114 - for (int row = 0; row < rows; row++)  
115 - words.append(toString(row,col));  
116 - lines.append(words.join(",")); 108 + for (int i=0; i<data.rows; i++) {
  109 + lines.append(toString(i,0));
117 } 110 }
118 QtUtils::writeFile(file, lines); 111 QtUtils::writeFile(file, lines);
119 } 112 }
120 113
121 void initialize(const FileList &targetFiles, const FileList &queryFiles) 114 void initialize(const FileList &targetFiles, const FileList &queryFiles)
122 { 115 {
123 - if (rows == -1 || cols == -1) qFatal("heatOutput requires dimensionality");  
124 - 116 + if (patches == -1) qFatal("Heat output requires the number of patches");
125 Output::initialize(targetFiles, queryFiles); 117 Output::initialize(targetFiles, queryFiles);
126 - data.create(rows, cols, CV_32FC1); 118 + data.create(patches, 1, CV_32FC1);
127 } 119 }
128 }; 120 };
129 121
openbr/plugins/quality.cpp
@@ -150,8 +150,7 @@ class MatchProbabilityDistance : public Distance @@ -150,8 +150,7 @@ class MatchProbabilityDistance : public Distance
150 Q_OBJECT 150 Q_OBJECT
151 Q_PROPERTY(br::Distance* distance READ get_distance WRITE set_distance RESET reset_distance STORED false) 151 Q_PROPERTY(br::Distance* distance READ get_distance WRITE set_distance RESET reset_distance STORED false)
152 Q_PROPERTY(bool gaussian READ get_gaussian WRITE set_gaussian RESET reset_gaussian STORED false) 152 Q_PROPERTY(bool gaussian READ get_gaussian WRITE set_gaussian RESET reset_gaussian STORED false)
153 - BR_PROPERTY(br::Distance*, distance, make("Dist(L2)"))  
154 - BR_PROPERTY(bool, gaussian, true) 153 + Q_PROPERTY(bool crossModality READ get_crossModality WRITE set_crossModality RESET reset_crossModality STORED false)
155 154
156 MP mp; 155 MP mp;
157 156
@@ -170,6 +169,7 @@ class MatchProbabilityDistance : public Distance @@ -170,6 +169,7 @@ class MatchProbabilityDistance : public Distance
170 for (int j=0; j<i; j++) { 169 for (int j=0; j<i; j++) {
171 const float score = matrixOutput.data()->data.at<float>(i, j); 170 const float score = matrixOutput.data()->data.at<float>(i, j);
172 if (score == -std::numeric_limits<float>::max()) continue; 171 if (score == -std::numeric_limits<float>::max()) continue;
  172 + if (crossModality) if(src[i].file.get<QString>("Modality") == src[j].file.get<QString>("Modality")) continue;
173 if (labels[i] == labels[j]) genuineScores.append(score); 173 if (labels[i] == labels[j]) genuineScores.append(score);
174 else impostorScores.append(score); 174 else impostorScores.append(score);
175 } 175 }
@@ -181,9 +181,8 @@ class MatchProbabilityDistance : public Distance @@ -181,9 +181,8 @@ class MatchProbabilityDistance : public Distance
181 float compare(const Template &target, const Template &query) const 181 float compare(const Template &target, const Template &query) const
182 { 182 {
183 float rawScore = distance->compare(target, query); 183 float rawScore = distance->compare(target, query);
184 - return -log(rawScore+1);  
185 - //if (rawScore == -std::numeric_limits<float>::max()) return rawScore;  
186 - //return mp(rawScore, gaussian); 184 + if (rawScore == -std::numeric_limits<float>::max()) return rawScore;
  185 + return mp(rawScore, gaussian);
187 } 186 }
188 187
189 void store(QDataStream &stream) const 188 void store(QDataStream &stream) const
@@ -197,12 +196,110 @@ class MatchProbabilityDistance : public Distance @@ -197,12 +196,110 @@ class MatchProbabilityDistance : public Distance
197 distance->load(stream); 196 distance->load(stream);
198 stream >> mp; 197 stream >> mp;
199 } 198 }
  199 +
  200 +protected:
  201 + BR_PROPERTY(br::Distance*, distance, make("Dist(L2)"))
  202 + BR_PROPERTY(bool, gaussian, true)
  203 + BR_PROPERTY(bool, crossModality, false)
200 }; 204 };
201 205
202 BR_REGISTER(Distance, MatchProbabilityDistance) 206 BR_REGISTER(Distance, MatchProbabilityDistance)
203 207
204 /*! 208 /*!
205 * \ingroup distances 209 * \ingroup distances
  210 + * \brief Match Probability modification for heat maps \cite klare12
  211 + * \author Scott Klum \cite sklum
  212 + */
  213 +class HeatMapDistance : public Distance
  214 +{
  215 + Q_OBJECT
  216 + Q_PROPERTY(br::Distance* distance READ get_distance WRITE set_distance RESET reset_distance STORED false)
  217 + Q_PROPERTY(bool gaussian READ get_gaussian WRITE set_gaussian RESET reset_gaussian STORED false)
  218 + Q_PROPERTY(bool crossModality READ get_crossModality WRITE set_crossModality RESET reset_crossModality STORED false)
  219 + Q_PROPERTY(int step READ get_step WRITE set_step RESET reset_step STORED false)
  220 + BR_PROPERTY(br::Distance*, distance, make("Dist(L2)"))
  221 + BR_PROPERTY(bool, gaussian, true)
  222 + BR_PROPERTY(bool, crossModality, false)
  223 + BR_PROPERTY(int, step, 1)
  224 +
  225 + QList<MP> mp;
  226 +
  227 + void train(const TemplateList &src)
  228 + {
  229 + distance->train(src);
  230 +
  231 + const QList<int> labels = src.indexProperty("Subject");
  232 +
  233 + QList<TemplateList> patches;
  234 +
  235 + // Split src into list of TemplateLists of corresponding patches across all Templates
  236 + for (int i=0; i<step; i++) {
  237 + TemplateList patchBuffer;
  238 + for (int j=i; j<src.size(); j+=step) {
  239 + patchBuffer.append(src[j]);
  240 + }
  241 + patches.append(patchBuffer);
  242 + patchBuffer.clear();
  243 + }
  244 +
  245 + QScopedPointer<MatrixOutput> matrixOutput(MatrixOutput::make(FileList(patches[0].size()), FileList(patches[0].size())));
  246 +
  247 + for (int i=0; i<step; i++) {
  248 + distance->compare(patches[i], patches[i], matrixOutput.data());
  249 + QList<float> genuineScores, impostorScores;
  250 + genuineScores.reserve(step);
  251 + impostorScores.reserve(step);
  252 + for (int j=0; j<matrixOutput.data()->data.rows; j++) {
  253 + for (int k=0; k<j; k++) {
  254 + const float score = matrixOutput.data()->data.at<float>(j, k);
  255 + if (score == -std::numeric_limits<float>::max()) continue;
  256 + if (crossModality) if(src[j*step].file.get<QString>("MODALITY") == src[k*step].file.get<QString>("MODALITY")) continue;
  257 + if (labels[j*step] == labels[k*step]) genuineScores.append(score);
  258 + else impostorScores.append(score);
  259 + }
  260 + }
  261 +
  262 + mp.append(MP(genuineScores, impostorScores));
  263 + }
  264 + }
  265 +
  266 + float compare(const Template &target, const Template &query) const
  267 + {
  268 + (void) target;
  269 + (void) query;
  270 + qFatal("You did this wrong");
  271 +
  272 + return 0;
  273 + }
  274 +
  275 + // Switch this to template list version, use compare(template, template) in
  276 + // heat map distance, and index into the proper match probability
  277 + void compare(const TemplateList &target, const TemplateList &query, Output *output) const
  278 + {
  279 + for (int i=0; i<step; i++) {
  280 + float rawScore = distance->compare(target[i],query[i]);
  281 + if (rawScore == -std::numeric_limits<float>::max()) output->setRelative(rawScore, i, 0);
  282 + else output->setRelative(mp[i](rawScore, gaussian), i, 0);
  283 + }
  284 + }
  285 +
  286 + void store(QDataStream &stream) const
  287 + {
  288 + distance->store(stream);
  289 + stream << mp;
  290 + }
  291 +
  292 + void load(QDataStream &stream)
  293 + {
  294 + distance->load(stream);
  295 + stream >> mp;
  296 + }
  297 +};
  298 +
  299 +BR_REGISTER(Distance, HeatMapDistance)
  300 +
  301 +/*!
  302 + * \ingroup distances
206 * \brief Linear normalizes of a distance so the mean impostor score is 0 and the mean genuine score is 1. 303 * \brief Linear normalizes of a distance so the mean impostor score is 0 and the mean genuine score is 1.
207 * \author Josh Klontz \cite jklontz 304 * \author Josh Klontz \cite jklontz
208 */ 305 */
share/openbr/Doxyfile.in
@@ -755,7 +755,7 @@ EXAMPLE_RECURSIVE = YES @@ -755,7 +755,7 @@ EXAMPLE_RECURSIVE = YES
755 # directories that contain image that are included in the documentation (see 755 # directories that contain image that are included in the documentation (see
756 # the \image command). 756 # the \image command).
757 757
758 -IMAGE_PATH = ${CMAKE_SOURCE_DIR} 758 +IMAGE_PATH = ${CMAKE_SOURCE_DIR}/share/openbr
759 759
760 # The INPUT_FILTER tag can be used to specify a program that doxygen should 760 # The INPUT_FILTER tag can be used to specify a program that doxygen should
761 # invoke to filter for each input file. Doxygen will invoke the filter program 761 # invoke to filter for each input file. Doxygen will invoke the filter program