Commit 0e83f65baa805f4ac4a501ac0bcd64cc126195eb

Authored by Josh Klontz
2 parents e5056b7b ad160761

Merge pull request #382 from biometrics/remove_frvt

removed frvt2012 API
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