Commit d1a5ec8cabab179886118835c6daa39261990142

Authored by Scott Klum
2 parents 0c56c80e 5d075f94

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

.gitmodules
1 1 [submodule "share/openbr/models"]
2 2 path = share/openbr/models
3 3 url = https://github.com/biometrics/openbr-models.git
4   -[submodule "share/openbr/doc"]
5   - path = share/openbr/doc
6   - url = https://github.com/biometrics/openbr-doc.git
7 4 [submodule "openbr/janus"]
8 5 path = openbr/janus
9 6 url = https://github.com/biometrics/janus.git
... ...
CHANGELOG.md deleted
1   -0.5.0 - ??/??/??
2   -================
3   -
4   -0.4.0 - 9/17/13
5   -===============
6   -* Added simple GUI frontend
7   -* Added -evalLandmarking and -plotLandmarking for evaluating and plotting landmarking accuracy (#9)
8   -* Added -evalDetection and -plotDetection for evaluating and plotting object detection accuracy (#9)
9   -* Deprecated Transform::backProject
10   -
11   -0.3.0 - 5/22/13
12   -===============
13   -* Added wrapper to NEC Latent SDK
14   -* Enrolling files/folders are now sorted naturally instead of alpha numerically
15   -* YouTubeFacesDBTransform implements Dr. Wolf's experimental protocol
16   -* NEC3 refactored
17   -* Updated transform API to add support for time-varying transforms per issue (#23)
18   -* Refactored File class to improve point and rect storage (#22)
19   -* Added algorithm to show face detection results (#25)
20   -* Reorganized GUI code and include paths (#31)
21   -* 'br -daemon' to listen for commands on stdin
22   -* Generalized 'br -convert', now requires three parameters
23   -* Official icon, thanks @sklum!
24   -
25   -0.2.0 - 2/23/13
26   -===============
27   -* FaceRecognition new distance metric
28   - - 0 to 1 range indicating match probability
29   -* Qt 4.8 -> Qt 5.0
30   -* Cleaner plots generated with 'br -plot'
31   -* Stasm and FLandmark wrappers
32   -* Improved demographic filtering speed
33   - - br::Context::demographicFilters -> br::Context::filters
34   - - MetadataDistance -> FilterDistance
35   -* PipeDistance
36   -* ImpostorUniquenessMeasureTransform
37   -* MatchProbabilityDistance
38   -* CrossValidation framework
39   - - br::Context::crossValidate
40   - - CrossValidationTransform
41   - - CrossValidationDistance
42   -
43   -0.1.0 - 1/27/13
44   -===============
45   -First official release!
CMakeLists.txt
... ... @@ -176,7 +176,7 @@ foreach(DIR ${BR_THIRDPARTY_APPS_DIR})
176 176 endforeach()
177 177  
178 178 # Install
179   -install(FILES CHANGELOG.md LICENSE.txt README.md DESTINATION share/openbr)
  179 +install(FILES LICENSE.txt README.md DESTINATION share/openbr)
180 180 install(DIRECTORY share DESTINATION .)
181 181 install(DIRECTORY ${BR_THIRDPARTY_SHARE} DESTINATION share)
182 182  
... ...
CTestConfig.cmake deleted
1   -set(CTEST_PROJECT_NAME ${CPACK_PACKAGE_NAME})
2   -set(CTEST_NIGHTLY_START_TIME "00:00:00 EST")
3   -
4   -if(NOT DEFINED CTEST_DROP_METHOD)
5   - set(CTEST_DROP_METHOD "http")
6   -endif()
7   -
8   -if(CTEST_DROP_METHOD STREQUAL "http")
9   - set(CTEST_DROP_SITE "my.cdash.org")
10   - set(CTEST_DROP_LOCATION "/submit.php?project=OpenBR")
11   - set(CTEST_DROP_SITE_CDASH TRUE)
12   -endif(CTEST_DROP_METHOD STREQUAL "http")
openbr/frvt2012.cpp deleted
1   -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2   - * Copyright 2012 The MITRE Corporation *
3   - * *
4   - * Licensed under the Apache License, Version 2.0 (the "License"); *
5   - * you may not use this file except in compliance with the License. *
6   - * You may obtain a copy of the License at *
7   - * *
8   - * http://www.apache.org/licenses/LICENSE-2.0 *
9   - * *
10   - * Unless required by applicable law or agreed to in writing, software *
11   - * distributed under the License is distributed on an "AS IS" BASIS, *
12   - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
13   - * See the License for the specific language governing permissions and *
14   - * limitations under the License. *
15   - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
16   -
17   -#include <openbr/openbr_plugin.h>
18   -#include <openbr/plugins/openbr_internal.h>
19   -
20   -#include "frvt2012.h"
21   -#include "core/distance_sse.h"
22   -
23   -using namespace br;
24   -using namespace std;
25   -
26   -static QSharedPointer<Transform> frvt2012_transform;
27   -static QSharedPointer<Transform> frvt2012_age_transform;
28   -static QSharedPointer<Transform> frvt2012_gender_transform;
29   -static const int frvt2012_template_size = 768;
30   -
31   -static void initialize(const string &configuration_location)
32   -{
33   - // Fake the command line arguments
34   - int argc = 1;
35   - char arg1[1]; arg1[0]='\0';
36   - char *argv[] = { arg1 };
37   -
38   - if (Globals == NULL) Context::initialize(argc, argv, QString::fromStdString(configuration_location));
39   - Globals->quiet = true;
40   - Globals->parallelism = 0;
41   -}
42   -
43   -static Template templateFromONEFACE(const ONEFACE &oneface)
44   -{
45   - return Template(QString::fromStdString(oneface.description),
46   - cv::Mat(oneface.image_height, oneface.image_width, oneface.image_depth == 8 ? CV_8UC1 : CV_8UC3, oneface.data));
47   -}
48   -
49   -int32_t get_pid(string &sdk_identifier, string &email_address)
50   -{
51   - sdk_identifier = "1338";
52   - email_address = "jklontz@mitre.org";
53   - return 0;
54   -}
55   -
56   -int32_t get_max_template_sizes(uint32_t &max_enrollment_template_size, uint32_t &max_recognition_template_size)
57   -{
58   - max_enrollment_template_size = frvt2012_template_size;
59   - max_recognition_template_size = frvt2012_template_size;
60   - return 0;
61   -}
62   -
63   -int32_t initialize_verification(string &configuration_location, vector<string> &descriptions)
64   -{
65   - (void) descriptions;
66   - initialize(configuration_location);
67   - frvt2012_transform = QSharedPointer<Transform>(Transform::make("Cvt(RGBGray)+Cascade(FrontalFace)!<FaceRecognitionRegistration>!<FaceRecognitionExtraction>+<FaceRecognitionEmbedding>+<FaceRecognitionQuantization>", NULL));
68   - return 0;
69   -}
70   -
71   -int32_t convert_multiface_to_enrollment_template(const MULTIFACE &input_faces, uint32_t &template_size, uint8_t *proprietary_template)
72   -{
73   - uint8_t quality;
74   - return convert_multiface_to_verification_template(input_faces, template_size, proprietary_template, quality);
75   -}
76   -
77   -int32_t convert_multiface_to_verification_template(const MULTIFACE &input_faces, uint32_t &template_size, uint8_t* proprietary_template, uint8_t &quality)
78   -{
79   - // Enroll templates
80   - TemplateList templates; templates.reserve(input_faces.size());
81   - foreach (const ONEFACE &oneface, input_faces)
82   - templates.append(templateFromONEFACE(oneface));
83   - templates >> *frvt2012_transform.data();
84   -
85   - // Compute template size
86   - template_size = templates.size() * frvt2012_template_size;
87   -
88   - // Create proprietary template
89   - for (int i=0; i<templates.size(); i++)
90   - memcpy(&proprietary_template[i*frvt2012_template_size], templates[i].m().data, frvt2012_template_size);
91   -
92   - quality = 100;
93   - return 0;
94   -}
95   -
96   -int32_t match_templates(const uint8_t* verification_template, const uint32_t verification_template_size, const uint8_t* enrollment_template, const uint32_t enrollment_template_size, double &similarity)
97   -{
98   - const int num_verification = verification_template_size / frvt2012_template_size;
99   - const int num_enrollment = enrollment_template_size / frvt2012_template_size;
100   -
101   - // Return early for failed templates
102   - if ((num_verification == 0) || (num_enrollment == 0)) {
103   - similarity = -1;
104   - return 2;
105   - }
106   -
107   - similarity = 0;
108   - for (int i=0; i<num_verification; i++)
109   - for (int j=0; j<num_enrollment; j++)
110   - similarity += l1(&verification_template[i*frvt2012_template_size], &enrollment_template[j*frvt2012_template_size], frvt2012_template_size);
111   - similarity /= num_verification * num_enrollment;
112   - similarity = std::max(0.0, -0.00112956 * (similarity - 6389.75)); // Yes this is a hard coded hack taken from FaceRecognition score normalization
113   - return 0;
114   -}
115   -
116   -int32_t SdkEstimator::initialize_age_estimation(const string &configuration_location)
117   -{
118   - initialize(configuration_location);
119   - frvt2012_age_transform = QSharedPointer<Transform>(Transform::make("Cvt(RGBGray)+Cascade(FrontalFace)!<FaceClassificationRegistration>!<FaceClassificationExtraction>+<AgeRegressor>+Discard", NULL));
120   - return 0;
121   -}
122   -
123   -int32_t SdkEstimator::initialize_gender_estimation(const string &configuration_location)
124   -{
125   - initialize(configuration_location);
126   - frvt2012_gender_transform = QSharedPointer<Transform>(Transform::make("Cvt(RGBGray)+Cascade(FrontalFace)!<FaceClassificationRegistration>!<FaceClassificationExtraction>+<GenderClassifier>+Discard", NULL));
127   - return 0;
128   -}
129   -
130   -int32_t SdkEstimator::estimate_age(const ONEFACE &input_face, int32_t &age)
131   -{
132   - TemplateList templates;
133   - templates.append(templateFromONEFACE(input_face));
134   - templates >> *frvt2012_age_transform.data();
135   - age = templates.first().file.get<float>("Age");
136   - return templates.first().file.fte ? 4 : 0;
137   -}
138   -
139   -int32_t SdkEstimator::estimate_gender(const ONEFACE &input_face, int8_t &gender, double &mf)
140   -{
141   - TemplateList templates;
142   - templates.append(templateFromONEFACE(input_face));
143   - templates >> *frvt2012_gender_transform.data();
144   - mf = gender = templates.first().file.get<QString>("Gender") == "Male" ? 0 : 1;
145   - return templates.first().file.fte ? 4 : 0;
146   -}
openbr/frvt2012.h deleted
1   -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2   - * Copyright 2012 The MITRE Corporation *
3   - * *
4   - * Licensed under the Apache License, Version 2.0 (the "License"); *
5   - * you may not use this file except in compliance with the License. *
6   - * You may obtain a copy of the License at *
7   - * *
8   - * http://www.apache.org/licenses/LICENSE-2.0 *
9   - * *
10   - * Unless required by applicable law or agreed to in writing, software *
11   - * distributed under the License is distributed on an "AS IS" BASIS, *
12   - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
13   - * See the License for the specific language governing permissions and *
14   - * limitations under the License. *
15   - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
16   -
17   -#ifndef FRVT2012_H
18   -#define FRVT2012_H
19   -
20   -#include <string>
21   -#include <vector>
22   -#include <stdint.h>
23   -#include <openbr/openbr_export.h>
24   -
25   -/*!
26   - * \defgroup frvt2012 FRVT 2012
27   - * \brief NIST <a href="http://www.nist.gov/itl/iad/ig/frvt-2012.cfm">Face Recognition Vendor Test 2012</a> API
28   - */
29   -
30   - /*!
31   - * \addtogroup frvt2012
32   - * \{
33   - */
34   -
35   -/*!
36   - * \brief Data structure representing a single face.
37   - */
38   -typedef struct sface {
39   - uint16_t image_width; /*!< \brief Number of pixels horizontally. */
40   - uint16_t image_height; /*!< \brief Number of pixels vertically. */
41   - uint16_t image_depth; /*!< \brief Number of bits per pixel. Legal values are 8 and 24. */
42   - uint8_t format; /*!< \brief Flag indicating native format of the image as supplied to NIST:
43   - - 0x01 = JPEG (i.e. compressed data)
44   - - 0x02 = PNG (i.e. never compressed data) */
45   - uint8_t* data; /*!< \brief Pointer to raster scanned data. Either RGB color or intensity.
46   - - If image_depth == 24 this points to 3WH bytes RGBRGBRGB...
47   - - If image_depth == 8 this points to WH bytes IIIIIII */
48   - std::string description; /*!< \brief Single description of the image. */
49   -} ONEFACE;
50   -
51   -/*!
52   - * \brief Data structure representing a set of images from a single person
53   - *
54   - * The set of face objects used to pass the image(s) and attribute(s) to
55   - * the template extraction process.
56   - */
57   -typedef std::vector<ONEFACE> MULTIFACE;
58   -
59   -/*!
60   - * \brief Return the identifier and contact email address for the software under test.
61   - *
62   - * All implementations shall support the self-identification function below.
63   - * This function is required to support internal NIST book-keeping.
64   - * The version numbers should be distinct between any versions which offer
65   - * different algorithmic functionality.
66   - *
67   - * \param[out] sdk_identifier
68   - * Version ID code as hexadecimal integer printed to null terminated ASCII
69   - * string. NIST will allocate exactly 5 bytes for this. This will be used to
70   - * identify the SDK in the results reports. This value should be changed every
71   - * time an SDK is submitted to NIST. The value is vendor assigned - format is
72   - * not regulated by NIST. EXAMPLE: "011A"
73   - *
74   - * \param[out] email_address
75   - * Point of contact email address as null terminated ASCII string.
76   - * NIST will allocate at least 64 bytes for this. SDK shall not allocate.
77   - *
78   - * \return
79   - * 0 Success
80   - * Other Vendor-defined failure
81   - */
82   -BR_EXPORT int32_t get_pid(std::string &sdk_identifier,
83   - std::string &email_address);
84   -
85   -/*!
86   - * \brief Return the maximum template sizes needed during feature extraction.
87   - *
88   - * All implementations shall report the maximum expected template sizes.
89   - * These values will be used by the NIST test harnesses to pre-allocate template
90   - * data. The values should apply to a single image. For a MULTIFACE containing
91   - * K images, NIST will allocate K times the value returned.
92   - *
93   - * \param[out] max_enrollment_template_size
94   - * The maximum possible size, in bytes, of the memory needed to store feature
95   - * data from a single enrollment image.
96   - *
97   - * \param[out] max_recognition_template_size
98   - * The maximum possible size, in bytes, of the memory needed to store feature
99   - * data from a single verification or identification image.
100   - *
101   - * \return
102   - * 0 Success
103   - * Other Vendor-defined failure
104   - */
105   -BR_EXPORT int32_t get_max_template_sizes(uint32_t &max_enrollment_template_size,
106   - uint32_t &max_recognition_template_size);
107   -
108   -/*!
109   - * \brief This function initializes the SDK under test.
110   - *
111   - * It will be called by the NIST application before any call to the functions
112   - * convert_multiface_to_enrollment_template or
113   - * convert_multiface_to_verification_template.
114   - * The SDK under test should set all parameters. Before any template generation
115   - * or matching calls are made, the NIST test harness will make a call to the
116   - * initialization of the function.
117   - *
118   - * \param[in] configuration_location
119   - * A read-only directory containing any vendor-supplied configuration parameters
120   - * or run-time data files. The name of this directory is assigned by NIST.
121   - * It is not hardwired by the provider. The names of the files in this directory
122   - * are hardwired in the SDK and are unrestricted.
123   - *
124   - * \param[in] descriptions
125   - * A lexicon of labels one of which will be assigned to each image.
126   - * EXAMPLE: The descriptions could be {"mugshot", "visa", "unknown"}.
127   - * These labels are provided to the SDK so that it knows to expect images of
128   - * these kinds.
129   - *
130   - * \return
131   - * 0 Success
132   - * 2 Vendor provided configuration files are not readable in the
133   - * indicated location
134   - * 8 The descriptions are unexpected or unusable
135   - * Other Vendor-defined failure
136   - */
137   -BR_EXPORT int32_t initialize_verification(std::string &configuration_location,
138   - std::vector<std::string> &descriptions);
139   -
140   -/*!
141   - * \brief This function takes a MULTIFACE, and outputs a proprietary template for enrollment.
142   - *
143   - * The memory for the output template is allocated by the NIST test harness
144   - * before the call i.e. the implementation shall not allocate memory for the result.
145   - * In all cases, even when unable to extract features, the output shall be a
146   - * template record that may be passed to the match_templates function without
147   - * error. That is, this routine must internally encode "template creation
148   - * failed" and the matcher must transparently handle this.
149   - *
150   - * \param[in] input_faces
151   - * An instance of a MULTIFACE structure. Implementations must alter their
152   - * behavior according to the number of images contained in the structure.
153   - *
154   - * \param[in] template_size
155   - * The size, in bytes, of the output template
156   - *
157   - * \param[out] proprietary_template
158   - * The output template. The format is entirely unregulated. NIST will allocate
159   - * a KT byte buffer for this template: The value K is the number of images in
160   - * the MULTIFACE; the value T is output by get_max_template_sizes.
161   - *
162   - * \return
163   - * 0 Success
164   - * 2 Elective refusal to process this kind of MULTIFACE
165   - * 4 Involuntary failure to extract features (e.g. could not find face in the
166   - * input-image)
167   - * 6 Elective refusal to produce a template (e.g. insufficient pixes between
168   - * the eyes)
169   - * 8 Cannot parse input data (i.e. assertion that input record is
170   - * non-conformant)
171   - * Other Vendor-defined failure. Failure codes must be documented and
172   - * communicated to NIST with the submission of the implementation under test.
173   - */
174   -BR_EXPORT int32_t convert_multiface_to_enrollment_template(const MULTIFACE &input_faces,
175   - uint32_t &template_size,
176   - uint8_t* proprietary_template);
177   -
178   -/*!
179   - * \brief This function takes a MULTIFACE, and outputs a proprietary template for
180   - * verification.
181   - *
182   - * The memory for the output template is allocated by the NIST test harness
183   - * before the call i.e. the implementation shall not allocate memory for the
184   - * result. In all cases, even when unable to extract features, the output shall
185   - * be a template record that may be passed to the match_templates function
186   - * without error. That is, this routine must internally encode "template
187   - * creation failed" and the matcher must transparently handle this.
188   - *
189   - * \param[in] input_faces
190   - * An instance of a MULTIFACE structure. Implementations must alter their
191   - * behavior according to the number of images contained in the structure.
192   - *
193   - * \param[in] template_size
194   - * The size, in bytes, of the output template
195   - *
196   - * \param[out] proprietary_template
197   - * The output template. The format is entirely unregulated. NIST will allocate
198   - * a KT byte buffer for this template: The value K is the number of images in
199   - * the MULTIFACE; the value T is output by get_max_template_sizes.
200   - *
201   - * \param[out] quality
202   - * An assessment of image quality. This is optional. The legal values are
203   - * - [0,100] - The value should have a monotonic decreasing relationship with
204   - * false non-match rate anticipated for this sample if it was compared with a
205   - * pristine image of the same person. So, a low value indicates high expected
206   - * FNMR.
207   - * - 255 - This value indicates a failed attempt to calculate a quality score.
208   - * - 254 - This values indicates the value was not assigned.
209   - *
210   - * \return
211   - * 0 Success
212   - * 2 Elective refusal to process this kind of MULTIFACE
213   - * 4 Involuntary failure to extract features (e.g. could not find face in the
214   - * input-image)
215   - * 6 Elective refusal to produce a template (e.g. insufficient pixes between
216   - * the eyes)
217   - * 8 Cannot parse input data (i.e. assertion that input record is
218   - * non-conformant)
219   - * Other Vendor-defined failure. Failure codes must be documented and
220   - * communicated to NIST with the submission of the implementation under test.
221   - */
222   -BR_EXPORT int32_t convert_multiface_to_verification_template(const MULTIFACE &input_faces,
223   - uint32_t &template_size,
224   - uint8_t* proprietary_template,
225   - uint8_t &quality);
226   -
227   -/*!
228   - * \brief
229   - * This function compares two opaque proprietary templates and outputs a
230   - * similarity score which need not satisfy the metric properties.
231   - *
232   - * NIST will allocate memory for this parameter before the call. When either
233   - * or both of the input templates are the result of a failed template
234   - * generation, the similarity score shall be -1 and the function return value
235   - * shall be 2.
236   - *
237   - * \param[in] verification_template
238   - * A template from convert_multiface_to_verification_template().
239   - *
240   - * \param[in] verification_template_size
241   - * The size, in bytes, of the input verification template 0 <= N <= 2^32 - 1
242   - *
243   - * \param[in] enrollment_template
244   - * A template from convert_multiface_to_enrollment_template().
245   - *
246   - * \param[in] enrollment_template_size
247   - * The size, in bytes, of the input enrollment template 0 <= N <= 2^32 - 1
248   - *
249   - * \param[out] similarity
250   - * A similarity score resulting from comparison of the templates, on the
251   - * range [0,DBL_MAX].
252   - *
253   - * \return
254   - * 0 Success
255   - * 2 Either or both of the input templates were result of failed feature
256   - * extraction
257   - * Other Vendor-defined failure.
258   - */
259   -BR_EXPORT int32_t match_templates(const uint8_t* verification_template,
260   - const uint32_t verification_template_size,
261   - const uint8_t* enrollment_template,
262   - const uint32_t enrollment_template_size,
263   - double &similarity);
264   -
265   -/*!
266   - * \brief Class D estimator abstraction.
267   - */
268   -struct BR_EXPORT Estimator {
269   - /*!< */
270   - static const int NOTIMPLEMENTED = -1;
271   - virtual ~Estimator() {}
272   -
273   - /*!
274   - * Intialization functions
275   - *
276   - * \param[in] configuration_location
277   - * A read-only directory containing any vendor-supplied configuration
278   - * parameters or run-time data files.
279   - *
280   - * \return
281   - * 0 Success
282   - * 2 Elective refusal to process this kind of MULTIFACE
283   - * 4 Involuntary failure to extract features (e.g. could not find face in
284   - * the input-image)
285   - * 8 Cannot parse input data (i.e. assertion that input record is
286   - * non-conformant)
287   - * Other Vendor-defined failure. Failure codes must be documented and
288   - * communicated to NIST with the submission of the implementation under
289   - * test.
290   - */
291   - /*!\{*/
292   - virtual int32_t initialize_frontal_pose_estimation(const std::string &configuration_location) { (void) configuration_location; return NOTIMPLEMENTED; }
293   - virtual int32_t initialize_age_estimation(const std::string &configuration_location) { (void) configuration_location; return NOTIMPLEMENTED; }
294   - virtual int32_t initialize_gender_estimation(const std::string &configuration_location) { (void) configuration_location; return NOTIMPLEMENTED; }
295   - virtual int32_t initialize_expression_estimation(const std::string &configuration_location) { (void) configuration_location; return NOTIMPLEMENTED; }
296   - /*!\}*/
297   -
298   - /*!
299   - * Frontal Pose estimation function
300   - *
301   - * \param[in] input_face
302   - * An instance of a ONEFACE structure.
303   - *
304   - * \param[out] non_frontality
305   - * Indication of how far from frontal the head pose is.
306   - * The value should be on the range [0,1].
307   - *
308   - * \return
309   - * 0 Success
310   - * 2 Elective refusal to process this kind of MULTIFACE
311   - * 4 Involuntary failure to extract features (e.g. could not find face in
312   - * the input-image)
313   - * 8 Cannot parse input data (i.e. assertion that input record is
314   - * non-conformant)
315   - * Other Vendor-defined failure. Failure codes must be documented and
316   - * communicated to NIST with the submission of the implementation under
317   - * test.
318   - */
319   - virtual int32_t estimate_frontal_pose_conformance(const ONEFACE &input_face, double &non_frontality) { (void) input_face; (void) non_frontality; return NOTIMPLEMENTED; }
320   -
321   - /*!
322   - * Age Estimation function
323   - *
324   - * \param[in] input_face
325   - * An instance of a ONEFACE structure.
326   - *
327   - * \param[out] age
328   - * Indication of the age (in years) of the person.
329   - * The value should be on the range [0,100].
330   - *
331   - * \return
332   - * 0 Success
333   - * 2 Elective refusal to process this kind of MULTIFACE
334   - * 4 Involuntary failure to extract features (e.g. could not find face in
335   - * the input-image)
336   - * 8 Cannot parse input data (i.e. assertion that input record is
337   - * non-conformant)
338   - * Other Vendor-defined failure. Failure codes must be documented and
339   - * communicated to NIST with the submission of the implementation under
340   - * test.
341   - */
342   - virtual int32_t estimate_age(const ONEFACE &input_face, int32_t &age) { (void) input_face; (void) age; return NOTIMPLEMENTED; }
343   -
344   - /*!
345   - * Gender Estimation function
346   - *
347   - * \param[in] input_face
348   - * An instance of a ONEFACE structure.
349   - *
350   - * \param[out] gender
351   - * Indication of the gender of the person. Valid values are
352   - * 0: Male
353   - * 1: Female
354   - * -1: Unknown
355   - *
356   - * \param[out] mf
357   - * A real-valued measure of maleness-femaleness value on [0,1].
358   - * A value of 0 indicates certainty that the subject is a male,
359   - * and a value of 1 indicates certainty that the subject is a female.
360   - *
361   - * \return
362   - * 0 Success
363   - * 2 Elective refusal to process this kind of MULTIFACE
364   - * 4 Involuntary failure to extract features (e.g. could not find face
365   - * in the input-image)
366   - * 8 Cannot parse input data (i.e. assertion that input record is
367   - * non-conformant)
368   - * Other Vendor-defined failure. Failure codes must be documented and
369   - * communicated to NIST with the submission of the implementation under test.
370   - */
371   - virtual int32_t estimate_gender(const ONEFACE &input_face, int8_t &gender, double &mf) { (void) input_face; (void) gender; (void) mf; return NOTIMPLEMENTED; }
372   -
373   - /*!
374   - * Expression neutrality function
375   - *
376   - * \param[in] input_face
377   - * An instance of a ONEFACE structure.
378   - *
379   - * \param[out] expression_neutrality
380   - * A real-valued measure of expression neutrality on [0,1] with 0
381   - * denoting large deviation from neutral and 1 indicating a fully
382   - * neutral expression.
383   - *
384   - * \return
385   - * 0 Success
386   - * 2 Elective refusal to process this kind of MULTIFACE
387   - * 4 Involuntary failure to extract features (e.g. could not find face in
388   - * the input-image)
389   - * 8 Cannot parse input data (i.e. assertion that input record is
390   - * non-conformant)
391   - * Other Vendor-defined failure. Failure codes must be documented and
392   - * communicated to NIST with the submission of the implementation under
393   - * test.
394   - */
395   - virtual int32_t estimate_expression_neutrality(const ONEFACE &input_face, double &expression_neutrality) { (void) input_face; (void) expression_neutrality; return NOTIMPLEMENTED; }
396   -};
397   -
398   -/*!
399   - * \brief Class D estimator implementation.
400   - */
401   -struct BR_EXPORT SdkEstimator : public Estimator
402   -{
403   - /*!
404   - * \brief Implemented estimators
405   - */
406   - /*!\{*/
407   - int32_t initialize_age_estimation(const std::string &configuration_location);
408   - int32_t initialize_gender_estimation(const std::string &configuration_location);
409   - int32_t estimate_age(const ONEFACE &input_face, int32_t &age);
410   - int32_t estimate_gender(const ONEFACE &input_face, int8_t &gender, double &mf);
411   - /*!\}*/
412   -};
413   -
414   -/*! @}*/
415   -
416   -#endif // FRVT2012_H
openbr/openbr_export.cpp deleted
openbr/openbr_plugin.cpp
... ... @@ -426,7 +426,7 @@ br_utemplate Template::toUniversalTemplate(const Template &amp;t)
426 426 return br_new_utemplate(algorithmID, x, y, width, height, confidence, metadata.data(), (const char*) m.data, m.rows * m.cols * m.elemSize());
427 427 }
428 428  
429   -Template Template::fromUniversalTemplate(const br_utemplate &ut)
  429 +Template Template::fromUniversalTemplate(br_const_utemplate ut)
430 430 {
431 431 QVariantMap map = QJsonDocument::fromJson(QByteArray((const char*) ut->data)).object().toVariantMap();
432 432 map.insert("AlgorithmID", ut->algorithmID);
... ... @@ -435,10 +435,27 @@ Template Template::fromUniversalTemplate(const br_utemplate &amp;ut)
435 435 map.insert("Width" , ut->width );
436 436 map.insert("Height" , ut->height );
437 437 map.insert("Confidence" , ut->confidence );
438   - const Mat m = Mat(1, ut->fvSize, CV_8UC1, ut->data + ut->mdSize).clone();
  438 + const Mat m = Mat(1, ut->fvSize, CV_8UC1, (void*)(ut->data + ut->mdSize)).clone();
439 439 return Template(File(map), m);
440 440 }
441 441  
  442 +br_utemplate Template::readUniversalTemplate(QFile &file)
  443 +{
  444 + const size_t headerSize = sizeof(br_universal_template);
  445 + br_universal_template *t = (br_universal_template*) malloc(headerSize);
  446 + file.read((char*) t, headerSize);
  447 +
  448 + const size_t dataSize = t->mdSize + t->fvSize;
  449 + t = (br_universal_template*) realloc(t, headerSize + dataSize);
  450 + file.read((char*) &t->data, dataSize);
  451 + return t;
  452 +}
  453 +
  454 +void Template::freeUniversalTemplate(br_const_utemplate t)
  455 +{
  456 + free((void*) t);
  457 +}
  458 +
442 459 QDataStream &br::operator<<(QDataStream &stream, const Template &t)
443 460 {
444 461 return stream << static_cast<const QList<cv::Mat>&>(t) << t.file;
... ...
openbr/openbr_plugin.h
... ... @@ -295,7 +295,9 @@ struct Template : public QList&lt;cv::Mat&gt;
295 295 }
296 296  
297 297 static br_utemplate toUniversalTemplate(const Template &t);
298   - static Template fromUniversalTemplate(const br_utemplate &ut);
  298 + static Template fromUniversalTemplate(br_const_utemplate ut);
  299 + static br_utemplate readUniversalTemplate(QFile &file);
  300 + static void freeUniversalTemplate(br_const_utemplate t);
299 301 };
300 302  
301 303 BR_EXPORT QDataStream &operator<<(QDataStream &stream, const Template &t);
... ...
openbr/plugins/classification/lda.cpp
... ... @@ -478,6 +478,8 @@ class LDATransform : public Transform
478 478 if (normalize)
479 479 stdDev = sqrt(results.array().square().sum() / trainingSet.size());
480 480 }
  481 +
  482 + qDebug() << "LDA projection dimensions:" << projection.rows() << "->" << projection.cols();
481 483 }
482 484  
483 485 void project(const Template &src, Template &dst) const
... ...
openbr/plugins/gallery/binary.cpp
... ... @@ -204,154 +204,27 @@ BR_REGISTER(Gallery, galGallery)
204 204 * \brief A contiguous array of br_universal_template.
205 205 * \author Josh Klontz \cite jklontz
206 206 */
207   -class utGallery : public BinaryGallery
  207 +class tGallery : public BinaryGallery
208 208 {
209 209 Q_OBJECT
210 210  
211 211 Template readTemplate()
212 212 {
213   - Template t;
214   - br_universal_template ut;
215   - if (gallery.read((char*)&ut, sizeof(br_universal_template)) == sizeof(br_universal_template)) {
216   - QByteArray data(ut.mdSize + ut.fvSize, Qt::Uninitialized);
217   - char *dst = data.data();
218   - qint64 bytesNeeded = ut.mdSize + ut.fvSize;
219   - while (bytesNeeded > 0) {
220   - qint64 bytesRead = gallery.read(dst, bytesNeeded);
221   - if (bytesRead <= 0) {
222   - qDebug() << gallery.errorString();
223   - qFatal("Unexepected EOF while reading universal template data, needed: %d more of: %d bytes.", int(bytesNeeded), int(ut.mdSize + ut.fvSize));
224   - }
225   - bytesNeeded -= bytesRead;
226   - dst += bytesRead;
227   - }
228   -
229   - t.file.set("AlgorithmID", ut.algorithmID);
230   - t.file.set("Metadata", QString(data.data()));
231   - char *dataStart = data.data() + ut.mdSize;
232   - uint32_t dataSize = ut.fvSize;
233   - if ((ut.algorithmID <= -1) && (ut.algorithmID >= -3)) {
234   - t.file.set("FrontalFace", QRectF(ut.x, ut.y, ut.width, ut.height));
235   - uint32_t *rightEyeX = reinterpret_cast<uint32_t*>(dataStart);
236   - dataStart += sizeof(uint32_t);
237   - uint32_t *rightEyeY = reinterpret_cast<uint32_t*>(dataStart);
238   - dataStart += sizeof(uint32_t);
239   - uint32_t *leftEyeX = reinterpret_cast<uint32_t*>(dataStart);
240   - dataStart += sizeof(uint32_t);
241   - uint32_t *leftEyeY = reinterpret_cast<uint32_t*>(dataStart);
242   - dataStart += sizeof(uint32_t);
243   - dataSize -= sizeof(uint32_t)*4;
244   - t.file.set("First_Eye", QPointF(*rightEyeX, *rightEyeY));
245   - t.file.set("Second_Eye", QPointF(*leftEyeX, *leftEyeY));
246   - } else if (ut.algorithmID == 7) {
247   - // binary data consisting of a single channel matrix, of a supported type.
248   - // 4 element header:
249   - // uint16 datatype (single channel opencv datatype code)
250   - // uint32 matrix rows
251   - // uint32 matrix cols
252   - // uint16 matrix depth (max 512)
253   - // Followed by serialized data, in row-major order (in r/c), with depth values
254   - // for each layer listed in order (i.e. rgb, rgb etc.)
255   - // #### NOTE! matlab's default order is col-major, so some work should
256   - // be done on the matlab side to make sure that the initial serialization is correct.
257   - uint16_t dataType = *reinterpret_cast<uint32_t*>(dataStart);
258   - dataStart += sizeof(uint16_t);
259   -
260   - uint32_t matrixRows = *reinterpret_cast<uint32_t*>(dataStart);
261   - dataStart += sizeof(uint32_t);
262   -
263   - uint32_t matrixCols = *reinterpret_cast<uint32_t*>(dataStart);
264   - dataStart += sizeof(uint32_t);
265   -
266   - uint16_t matrixDepth= *reinterpret_cast<uint16_t*>(dataStart);
267   - dataStart += sizeof(uint16_t);
268   -
269   - // Set metadata
270   - t.file.set("X", ut.x);
271   - t.file.set("Y", ut.y);
272   - t.file.set("Width", ut.width);
273   - t.file.set("Height", ut.height);
274   - t.file.set("Confidence", ut.confidence);
275   -
276   - t.append(cv::Mat(matrixRows, matrixCols, CV_MAKETYPE(dataType, matrixDepth), dataStart).clone() /* We don't want a shallow copy! */);
277   - return t;
278   - } else {
279   - t.file.set("X", ut.x);
280   - t.file.set("Y", ut.y);
281   - t.file.set("Width", ut.width);
282   - t.file.set("Height", ut.height);
283   - t.file.set("Confidence", ut.confidence);
284   - }
285   - t.append(cv::Mat(1, dataSize, CV_8UC1, dataStart).clone() /* We don't want a shallow copy! */);
286   - } else {
287   - if (!gallery.atEnd())
288   - qWarning("Failed to read universal template header!");
289   - gallery.close();
290   - }
  213 + const br_const_utemplate ut = Template::readUniversalTemplate(gallery);
  214 + const Template t = Template::fromUniversalTemplate(ut);
  215 + Template::freeUniversalTemplate(ut);
291 216 return t;
292 217 }
293 218  
294 219 void writeTemplate(const Template &t)
295 220 {
296   - const int32_t algorithmID = (t.isEmpty() || t.file.fte) ? 0 : t.file.get<int32_t>("AlgorithmID");
297   -
298   - // QUrl::fromUserInput provides some nice functionality in terms of completing URLs
299   - // e.g. C:/test.jpg -> file://C:/test.jpg and google.com/image.jpg -> http://google.com/image.jpg
300   - const QByteArray metadata = QUrl::fromUserInput(t.file.get<QString>("URL", t.file.name)).toEncoded();
301   -
302   - int32_t x = 0, y = 0;
303   - uint32_t width = 0, height = 0;
304   - float confidence = 0;
305   - QByteArray header;
306   - if ((algorithmID <= -1) && (algorithmID >= -3)) {
307   - const QRectF frontalFace = t.file.get<QRectF>("FrontalFace");
308   - x = frontalFace.x();
309   - y = frontalFace.y();
310   - width = frontalFace.width();
311   - height = frontalFace.height();
312   -
313   - const QPointF firstEye = t.file.get<QPointF>("First_Eye");
314   - const QPointF secondEye = t.file.get<QPointF>("Second_Eye");
315   - const uint32_t rightEyeX = firstEye.x();
316   - const uint32_t rightEyeY = firstEye.y();
317   - const uint32_t leftEyeX = secondEye.x();
318   - const uint32_t leftEyeY = secondEye.y();
319   -
320   - header.append((const char*)&rightEyeX, sizeof(uint32_t));
321   - header.append((const char*)&rightEyeY, sizeof(uint32_t));
322   - header.append((const char*)&leftEyeX , sizeof(uint32_t));
323   - header.append((const char*)&leftEyeY , sizeof(uint32_t));
324   - } else {
325   - x = t.file.get<int32_t>("X", 0);
326   - y = t.file.get<int32_t>("Y", 0);
327   - width = t.file.get<uint32_t>("Width", 0);
328   - height = t.file.get<uint32_t>("Height", 0);
329   - confidence = t.file.get<uint32_t>("Confidence", 0);
330   - }
331   -
332   - gallery.write((const char*) &algorithmID, sizeof(int32_t));
333   - gallery.write((const char*) &x , sizeof(int32_t));
334   - gallery.write((const char*) &y , sizeof(int32_t));
335   - gallery.write((const char*) &width , sizeof(uint32_t));
336   - gallery.write((const char*) &height , sizeof(uint32_t));
337   - gallery.write((const char*) &confidence , sizeof(float));
338   -
339   - const uint32_t mdSize = metadata.size() + 1;
340   - gallery.write((const char*) &mdSize, sizeof(uint32_t));
341   -
342   - const uint32_t signatureSize = (algorithmID == 0) ? 0 : t.m().rows * t.m().cols * t.m().elemSize();
343   - const uint32_t fvSize = header.size() + signatureSize;
344   - gallery.write((const char*) &fvSize, sizeof(uint32_t));
345   -
346   - gallery.write((const char*) metadata.data(), mdSize);
347   - if (algorithmID != 0) {
348   - gallery.write(header);
349   - gallery.write((const char*) t.m().data, signatureSize);
350   - }
  221 + const br_utemplate ut = Template::toUniversalTemplate(t);
  222 + gallery.write((const char*) ut, sizeof(br_universal_template) + ut->mdSize + ut->fvSize);
  223 + Template::freeUniversalTemplate(ut);
351 224 }
352 225 };
353 226  
354   -BR_REGISTER(Gallery, utGallery)
  227 +BR_REGISTER(Gallery, tGallery)
355 228  
356 229 /*!
357 230 * \ingroup galleries
... ...
openbr/plugins/gallery/xml.cpp
... ... @@ -31,7 +31,9 @@ class xmlGallery : public FileGallery
31 31 {
32 32 Q_OBJECT
33 33 Q_PROPERTY(bool ignoreMetadata READ get_ignoreMetadata WRITE set_ignoreMetadata RESET reset_ignoreMetadata STORED false)
  34 + Q_PROPERTY(bool skipMissing READ get_skipMissing WRITE set_skipMissing RESET reset_skipMissing STORED false)
34 35 BR_PROPERTY(bool, ignoreMetadata, false)
  36 + BR_PROPERTY(bool, skipMissing, false)
35 37 FileList files;
36 38  
37 39 QXmlStreamReader reader;
... ... @@ -116,6 +118,12 @@ class xmlGallery : public FileGallery
116 118  
117 119 // we read another complete template
118 120 count++;
  121 +
  122 + // optionally remove templates whose files don't exist or are empty
  123 + if (skipMissing && !QFileInfo(templates.last().file.resolved()).size()) {
  124 + templates.removeLast();
  125 + count--;
  126 + }
119 127 }
120 128 }
121 129 }
... ...
openbr/plugins/imgproc/quantize.cpp
... ... @@ -41,6 +41,7 @@ class QuantizeTransform : public Transform
41 41 minMaxLoc(OpenCVUtils::toMat(data.data()), &minVal, &maxVal);
42 42 a = 255.0/(maxVal-minVal);
43 43 b = -a*minVal;
  44 + qDebug() << "Quantized dimensions =" << data.first().m().rows * data.first().m().cols;
44 45 }
45 46  
46 47 void project(const Template &src, Template &dst) const
... ...
openbr/plugins/imgproc/synthesizekeypoints.cpp
... ... @@ -155,10 +155,10 @@ class SynthesizePointsTransform : public MetadataTransform
155 155 // Because not all triangulations are the same, we have to decide on a canonical set of triangles at training time.
156 156 QHash<TriangleIndicies, int> counts;
157 157 foreach (const Template &datum, data) {
158   -
159 158 const QList<QPointF> points = datum.file.points();
160   - if (points.size() == 0)
161   - continue;
  159 + if (points.size() <= 4)
  160 + continue;
  161 +
162 162 const QList< QList<int> > triangulation = getTriangulation(points, getBounds(points, 10));
163 163 if (triangulation.empty())
164 164 continue;
... ... @@ -167,6 +167,9 @@ class SynthesizePointsTransform : public MetadataTransform
167 167 counts[TriangleIndicies(indicies)]++;
168 168 }
169 169  
  170 + if (counts.empty())
  171 + return;
  172 +
170 173 triangles.clear();
171 174 QHash<TriangleIndicies, int>::const_iterator i = counts.constBegin();
172 175 while (i != counts.constEnd()) {
... ...
openbr/plugins/metadata/selectpoints.cpp
... ... @@ -29,8 +29,20 @@ class SelectPointsTransform : public UntrainableMetadataTransform
29 29 Q_OBJECT
30 30 Q_PROPERTY(QList<int> indices READ get_indices WRITE set_indices RESET reset_indices STORED false)
31 31 Q_PROPERTY(bool invert READ get_invert WRITE set_invert RESET reset_invert STORED false) // keep the points _not_ in the list
  32 + Q_PROPERTY(int rangeStart READ get_rangeStart WRITE set_rangeStart RESET reset_rangeStart STORED false)
  33 + Q_PROPERTY(int rangeEnd READ get_rangeEnd WRITE set_rangeEnd RESET reset_rangeEnd STORED false)
32 34 BR_PROPERTY(QList<int>, indices, QList<int>())
33 35 BR_PROPERTY(bool, invert, false)
  36 + BR_PROPERTY(int, rangeStart, -1)
  37 + BR_PROPERTY(int, rangeEnd, -1)
  38 +
  39 + void init()
  40 + {
  41 + if ((rangeStart != -1) && (rangeEnd != -1))
  42 + for (int i=rangeStart; i<=rangeEnd; i++)
  43 + if (!indices.contains(i))
  44 + indices.append(i);
  45 + }
34 46  
35 47 void projectMetadata(const File &src, File &dst) const
36 48 {
... ...
share/openbr/doc deleted
1   -Subproject commit 7236a155867a161b9bf6c801e1d158250e36ebf3