Commit bd3fbd910f610420291fd4cbeece07f0a3bd37cc

Authored by Scott Klum
2 parents 8ccbcbe4 e0463ba6

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

CHANGELOG.md
1 0.3.0 - ??/??/?? 1 0.3.0 - ??/??/??
2 ================ 2 ================
3 * YouTubeFacesDBTransform implements Dr. Wolf's experimental protocol 3 * YouTubeFacesDBTransform implements Dr. Wolf's experimental protocol
  4 +* NEC3 refactored
4 5
5 0.2.0 - 2/23/13 6 0.2.0 - 2/23/13
6 =============== 7 ===============
sdk/openbr_plugin.cpp
@@ -452,6 +452,7 @@ TemplateList TemplateList::fromGallery(const br::File &gallery) @@ -452,6 +452,7 @@ TemplateList TemplateList::fromGallery(const br::File &gallery)
452 foreach (const br::File &file, gallery.split()) { 452 foreach (const br::File &file, gallery.split()) {
453 QScopedPointer<Gallery> i(Gallery::make(file)); 453 QScopedPointer<Gallery> i(Gallery::make(file));
454 TemplateList newTemplates = i->read(); 454 TemplateList newTemplates = i->read();
  455 + if (gallery.getBool("reduce")) newTemplates = newTemplates.reduced();
455 const int crossValidate = gallery.getInt("crossValidate"); 456 const int crossValidate = gallery.getInt("crossValidate");
456 if (crossValidate > 0) srand(0); 457 if (crossValidate > 0) srand(0);
457 458
@@ -1239,10 +1240,10 @@ Transform *Transform::make(QString str, QObject *parent) @@ -1239,10 +1240,10 @@ Transform *Transform::make(QString str, QObject *parent)
1239 if (Globals->abbreviations.contains(str)) 1240 if (Globals->abbreviations.contains(str))
1240 return make(Globals->abbreviations[str], parent); 1241 return make(Globals->abbreviations[str], parent);
1241 1242
1242 - { // Check for use of '!' as shorthand for Chain(...) 1243 + { // Check for use of '!' as shorthand for Expand(...)
1243 QStringList words = parse(str, '!'); 1244 QStringList words = parse(str, '!');
1244 if (words.size() > 1) 1245 if (words.size() > 1)
1245 - return make("Chain([" + words.join(",") + "])", parent); 1246 + return make("Expand([" + words.join(",") + "])", parent);
1246 } 1247 }
1247 1248
1248 { // Check for use of '+' as shorthand for Pipe(...) 1249 { // Check for use of '+' as shorthand for Pipe(...)
sdk/openbr_plugin.h
@@ -393,6 +393,17 @@ struct TemplateList : public QList&lt;Template&gt; @@ -393,6 +393,17 @@ struct TemplateList : public QList&lt;Template&gt;
393 labelCounts[file.label()]++; 393 labelCounts[file.label()]++;
394 return labelCounts; 394 return labelCounts;
395 } 395 }
  396 +
  397 + /*!
  398 + * \brief Merge all the templates together.
  399 + */
  400 + TemplateList reduced() const
  401 + {
  402 + Template reduced;
  403 + foreach (const Template &t, *this)
  404 + reduced.merge(t);
  405 + return TemplateList() << reduced;
  406 + }
396 }; 407 };
397 408
398 /*! 409 /*!
sdk/plugins/format.cpp
@@ -509,6 +509,34 @@ BR_REGISTER(Format, matFormat) @@ -509,6 +509,34 @@ BR_REGISTER(Format, matFormat)
509 509
510 /*! 510 /*!
511 * \ingroup formats 511 * \ingroup formats
  512 + * \brief RAW format
  513 + *
  514 + * http://www.nist.gov/srd/nistsd27.cfm
  515 + * \author Josh Klontz \cite jklontz
  516 + */
  517 +class rawFormat : public Format
  518 +{
  519 + Q_OBJECT
  520 +
  521 + Template read() const
  522 + {
  523 + QByteArray data;
  524 + QtUtils::readFile(file, data);
  525 + if (data.size() != 768*800)
  526 + qFatal("Expected 768*800 bytes.");
  527 + return Template(file, Mat(768, 800, CV_8UC1, data.data()).clone());
  528 + }
  529 +
  530 + void write(const Template &t) const
  531 + {
  532 + QtUtils::writeFile(file, QByteArray().setRawData((const char*)t.m().data, t.m().total() * t.m().elemSize()));
  533 + }
  534 +};
  535 +
  536 +BR_REGISTER(Format, rawFormat)
  537 +
  538 +/*!
  539 + * \ingroup formats
512 * \brief Retrieves an image from a webcam. 540 * \brief Retrieves an image from a webcam.
513 * \author Josh Klontz \cite jklontz 541 * \author Josh Klontz \cite jklontz
514 */ 542 */
sdk/plugins/gallery.cpp
@@ -135,7 +135,7 @@ BR_REGISTER(Gallery, EmptyGallery) @@ -135,7 +135,7 @@ BR_REGISTER(Gallery, EmptyGallery)
135 135
136 /*! 136 /*!
137 * \ingroup galleries 137 * \ingroup galleries
138 - * \brief Treats the gallery as a single image. 138 + * \brief Treats the gallery as a br::Format.
139 * \author Josh Klontz \cite jklontz 139 * \author Josh Klontz \cite jklontz
140 */ 140 */
141 class DefaultGallery : public Gallery 141 class DefaultGallery : public Gallery
@@ -150,8 +150,8 @@ class DefaultGallery : public Gallery @@ -150,8 +150,8 @@ class DefaultGallery : public Gallery
150 150
151 void write(const Template &t) 151 void write(const Template &t)
152 { 152 {
153 - QtUtils::touchDir(QFileInfo(file.name));  
154 - OpenCVUtils::saveImage(t, file.name); 153 + QScopedPointer<Format> format(Factory<Format>::make(file));
  154 + format->write(t);
155 } 155 }
156 }; 156 };
157 BR_REGISTER(Gallery, DefaultGallery) 157 BR_REGISTER(Gallery, DefaultGallery)
sdk/plugins/meta.cpp
@@ -26,13 +26,13 @@ using namespace cv; @@ -26,13 +26,13 @@ using namespace cv;
26 namespace br 26 namespace br
27 { 27 {
28 28
29 -static TemplateList Simplified(const TemplateList &templates) 29 +static TemplateList Expanded(const TemplateList &templates)
30 { 30 {
31 - TemplateList simplified; 31 + TemplateList expanded;
32 foreach (const Template &t, templates) { 32 foreach (const Template &t, templates) {
33 if (t.isEmpty()) { 33 if (t.isEmpty()) {
34 if (!t.file.getBool("enrollAll")) 34 if (!t.file.getBool("enrollAll"))
35 - simplified.append(t); 35 + expanded.append(t);
36 continue; 36 continue;
37 } 37 }
38 38
@@ -46,13 +46,13 @@ static TemplateList Simplified(const TemplateList &amp;templates) @@ -46,13 +46,13 @@ static TemplateList Simplified(const TemplateList &amp;templates)
46 46
47 for (int i=0; i<t.size(); i++) { 47 for (int i=0; i<t.size(); i++) {
48 if (!fte || !t.file.getBool("enrollAll")) { 48 if (!fte || !t.file.getBool("enrollAll")) {
49 - simplified.append(Template(t.file, t[i]));  
50 - simplified.last().file.setROIs(ROIs.mid(i*ROIStep, ROIStep));  
51 - simplified.last().file.setLandmarks(landmarks.mid(i*landmarkStep, landmarkStep)); 49 + expanded.append(Template(t.file, t[i]));
  50 + expanded.last().file.setROIs(ROIs.mid(i*ROIStep, ROIStep));
  51 + expanded.last().file.setLandmarks(landmarks.mid(i*landmarkStep, landmarkStep));
52 } 52 }
53 } 53 }
54 } 54 }
55 - return simplified; 55 + return expanded;
56 } 56 }
57 57
58 static void _train(Transform *transform, const TemplateList *data) 58 static void _train(Transform *transform, const TemplateList *data)
@@ -92,7 +92,8 @@ static void incrementStep() @@ -92,7 +92,8 @@ static void incrementStep()
92 * 92 *
93 * The source br::Template is given to the first transform and the resulting br::Template is passed to the next transform, etc. 93 * The source br::Template is given to the first transform and the resulting br::Template is passed to the next transform, etc.
94 * 94 *
95 - * \see ChainTransform 95 + * \see ExpandTransform
  96 + * \see ForkTransform
96 */ 97 */
97 class PipeTransform : public MetaTransform 98 class PipeTransform : public MetaTransform
98 { 99 {
@@ -142,10 +143,9 @@ class PipeTransform : public MetaTransform @@ -142,10 +143,9 @@ class PipeTransform : public MetaTransform
142 void backProject(const Template &dst, Template &src) const 143 void backProject(const Template &dst, Template &src) const
143 { 144 {
144 src = dst; 145 src = dst;
145 - //reverse order in which transforms are processed 146 + // Reverse order in which transforms are processed
146 int length = transforms.length(); 147 int length = transforms.length();
147 - //foreach (const Transform *f, transforms) {  
148 - for (int i=length-1; i>=0; i--){ 148 + for (int i=length-1; i>=0; i--) {
149 Transform *f = transforms.at(i); 149 Transform *f = transforms.at(i);
150 try { 150 try {
151 src >> *f; 151 src >> *f;
@@ -156,22 +156,21 @@ class PipeTransform : public MetaTransform @@ -156,22 +156,21 @@ class PipeTransform : public MetaTransform
156 } 156 }
157 } 157 }
158 } 158 }
159 -  
160 }; 159 };
161 160
162 BR_REGISTER(Transform, PipeTransform) 161 BR_REGISTER(Transform, PipeTransform)
163 162
164 /*! 163 /*!
165 * \ingroup transforms 164 * \ingroup transforms
166 - * \brief Transforms in series. 165 + * \brief Transforms in series with expansion step.
167 * \author Josh Klontz \cite jklontz 166 * \author Josh Klontz \cite jklontz
168 * 167 *
169 * The source br::Template is given to the first transform and the resulting br::Template is passed to the next transform, etc. 168 * The source br::Template is given to the first transform and the resulting br::Template is passed to the next transform, etc.
170 - * Each matrix is reorganized into a new template before continuing. 169 + * Each matrix is expanded into its own template between steps.
171 * 170 *
172 * \see PipeTransform 171 * \see PipeTransform
173 */ 172 */
174 -class ChainTransform : public MetaTransform 173 +class ExpandTransform : public MetaTransform
175 { 174 {
176 Q_OBJECT 175 Q_OBJECT
177 Q_PROPERTY(QList<br::Transform*> transforms READ get_transforms WRITE set_transforms RESET reset_transforms) 176 Q_PROPERTY(QList<br::Transform*> transforms READ get_transforms WRITE set_transforms RESET reset_transforms)
@@ -185,7 +184,7 @@ class ChainTransform : public MetaTransform @@ -185,7 +184,7 @@ class ChainTransform : public MetaTransform
185 for (int i=0; i<transforms.size(); i++) { 184 for (int i=0; i<transforms.size(); i++) {
186 transforms[i]->train(copy); 185 transforms[i]->train(copy);
187 copy >> *transforms[i]; 186 copy >> *transforms[i];
188 - copy = Simplified(copy); 187 + copy = Expanded(copy);
189 incrementStep(); 188 incrementStep();
190 } 189 }
191 190
@@ -211,17 +210,16 @@ class ChainTransform : public MetaTransform @@ -211,17 +210,16 @@ class ChainTransform : public MetaTransform
211 dst = src; 210 dst = src;
212 for (int i=0; i<transforms.size(); i++) { 211 for (int i=0; i<transforms.size(); i++) {
213 dst >> *transforms[i]; 212 dst >> *transforms[i];
214 - dst = Simplified(dst); 213 + dst = Expanded(dst);
215 } 214 }
216 } 215 }
217 216
218 void backProject(const Template &dst, Template &src) const 217 void backProject(const Template &dst, Template &src) const
219 { 218 {
220 src = dst; 219 src = dst;
221 - //reverse order in which transforms are processed 220 + // Reverse order in which transforms are processed
222 int length = transforms.length(); 221 int length = transforms.length();
223 - //foreach (const Transform *f, transforms) {  
224 - for (int i=length-1; i>=0; i--){ 222 + for (int i=length-1; i>=0; i--) {
225 Transform *f = transforms.at(i); 223 Transform *f = transforms.at(i);
226 try { 224 try {
227 src >> *f; 225 src >> *f;
@@ -234,7 +232,7 @@ class ChainTransform : public MetaTransform @@ -234,7 +232,7 @@ class ChainTransform : public MetaTransform
234 } 232 }
235 }; 233 };
236 234
237 -BR_REGISTER(Transform, ChainTransform) 235 +BR_REGISTER(Transform, ExpandTransform)
238 236
239 /*! 237 /*!
240 * \ingroup transforms 238 * \ingroup transforms
@@ -242,6 +240,8 @@ BR_REGISTER(Transform, ChainTransform) @@ -242,6 +240,8 @@ BR_REGISTER(Transform, ChainTransform)
242 * \author Josh Klontz \cite jklontz 240 * \author Josh Klontz \cite jklontz
243 * 241 *
244 * The source br::Template is seperately given to each transform and the results are appended together. 242 * The source br::Template is seperately given to each transform and the results are appended together.
  243 + *
  244 + * \see PipeTransform
245 */ 245 */
246 class ForkTransform : public MetaTransform 246 class ForkTransform : public MetaTransform
247 { 247 {
sdk/plugins/misc.cpp
@@ -317,6 +317,26 @@ class RenameFirstTransform : public UntrainableMetaTransform @@ -317,6 +317,26 @@ class RenameFirstTransform : public UntrainableMetaTransform
317 317
318 BR_REGISTER(Transform, RenameFirstTransform) 318 BR_REGISTER(Transform, RenameFirstTransform)
319 319
  320 +/*!
  321 + * \ingroup transforms
  322 + * \brief Change the br::Template::file extension
  323 + * \author Josh Klontz \cite jklontz
  324 + */
  325 +class AsTransform : public UntrainableMetaTransform
  326 +{
  327 + Q_OBJECT
  328 + Q_PROPERTY(QString extension READ get_extension WRITE set_extension RESET reset_extension STORED false)
  329 + BR_PROPERTY(QString, extension, "")
  330 +
  331 + void project(const Template &src, Template &dst) const
  332 + {
  333 + dst = src;
  334 + dst.file.name = dst.file.name.left(dst.file.name.lastIndexOf('.')+1) + extension;
  335 + }
  336 +};
  337 +
  338 +BR_REGISTER(Transform, AsTransform)
  339 +
320 } 340 }
321 341
322 #include "misc.moc" 342 #include "misc.moc"
sdk/plugins/nec3.cpp
  1 +#ifdef WIN32
  2 +#include <windows.h>
  3 +#endif
  4 +
1 #include <NeoFacePro.h> 5 #include <NeoFacePro.h>
2 -#include <mm_plugin.h>  
3 6
4 -#include "common/resource.h" 7 +#include <openbr_plugin.h>
  8 +#include "core/resource.h"
5 9
6 -using namespace mm; 10 +using namespace br;
7 11
8 /*! 12 /*!
9 * \ingroup initializers 13 * \ingroup initializers
10 * \brief Initialize NEC3 14 * \brief Initialize NEC3
11 * \author Josh Klontz \cite jklontz 15 * \author Josh Klontz \cite jklontz
  16 + * \author Scott Klum \cite sklum
12 * \warning Needs a maintainer 17 * \warning Needs a maintainer
13 */ 18 */
14 class NEC3Initializer : public Initializer 19 class NEC3Initializer : public Initializer
@@ -19,7 +24,7 @@ class NEC3Initializer : public Initializer @@ -19,7 +24,7 @@ class NEC3Initializer : public Initializer
19 { 24 {
20 int result = NeoFacePro::Initialize(); 25 int result = NeoFacePro::Initialize();
21 if (result != NFP_SUCCESS) qWarning("NEC3 Initialize error [%d]", result); 26 if (result != NFP_SUCCESS) qWarning("NEC3 Initialize error [%d]", result);
22 - Globals->Abbreviations.insert("NEC3", "Open+NEC3Enroll:NEC3Compare"); 27 + Globals->abbreviations.insert("NEC3", "Open!NEC3Enroll:NEC3Compare");
23 } 28 }
24 29
25 void finalize() const 30 void finalize() const
@@ -29,40 +34,27 @@ class NEC3Initializer : public Initializer @@ -29,40 +34,27 @@ class NEC3Initializer : public Initializer
29 } 34 }
30 }; 35 };
31 36
32 -MM_REGISTER(Initializer, NEC3Initializer) 37 +BR_REGISTER(Initializer, NEC3Initializer)
33 38
34 /*! 39 /*!
35 - * \brief Helper class  
36 - * \author Josh Klontz \cite jklontz  
37 - * \warning Needs a maintainer 40 + * \brief NEC3 Context
  41 + * \author Scott Klum \cite sklum
38 */ 42 */
39 -class CFaceInfoResourceMaker : public ResourceMaker<NeoFacePro::CFaceInfo>  
40 -{  
41 - NeoFacePro::CFaceInfo *make() const  
42 - {  
43 - NeoFacePro::CFaceInfo *faceInfo = new NeoFacePro::CFaceInfo();  
44 - faceInfo->SetParamAlgorithm(NFP_ALGORITHM003);  
45 - faceInfo->SetParamEyesRoll(15);  
46 - faceInfo->SetParamEyesMaxWidth(1000);  
47 - faceInfo->SetParamEyesMinWidth(30);  
48 - faceInfo->SetParamMaxFace(5);  
49 - faceInfo->SetParamReliability(0);  
50 - return faceInfo;  
51 - }  
52 -};  
53 43
54 -/*!  
55 - * \brief Helper class  
56 - * \author Josh Klontz \cite jklontz  
57 - * \warning Needs a maintainer  
58 - */  
59 -class CFaceFeatureResourceMaker : public ResourceMaker<NeoFacePro::CFaceFeature> 44 +struct NEC3Context
60 { 45 {
61 - NeoFacePro::CFaceFeature *make() const  
62 - {  
63 - NeoFacePro::CFaceFeature *faceFeature = new NeoFacePro::CFaceFeature();  
64 - faceFeature->SetParamFeatureType(NFP_FEATURE_S14);  
65 - return faceFeature; 46 + NeoFacePro::CFaceInfo faceInfo;
  47 + NeoFacePro::CFaceFeature faceFeature;
  48 +
  49 + NEC3Context() {
  50 + faceInfo.SetParamAlgorithm(NFP_ALGORITHM003);
  51 + faceInfo.SetParamEyesRoll(15);
  52 + faceInfo.SetParamEyesMaxWidth(1000);
  53 + faceInfo.SetParamEyesMinWidth(30);
  54 + faceInfo.SetParamMaxFace(1);
  55 + faceInfo.SetParamReliability(0);
  56 +
  57 + faceFeature.SetParamFeatureType(NFP_FEATURE_S14);
66 } 58 }
67 }; 59 };
68 60
@@ -70,30 +62,22 @@ class CFaceFeatureResourceMaker : public ResourceMaker&lt;NeoFacePro::CFaceFeature&gt; @@ -70,30 +62,22 @@ class CFaceFeatureResourceMaker : public ResourceMaker&lt;NeoFacePro::CFaceFeature&gt;
70 * \ingroup transforms 62 * \ingroup transforms
71 * \brief Enroll a face image in NEC NeoFace 3 63 * \brief Enroll a face image in NEC NeoFace 3
72 * \author Josh Klontz \cite jklontz 64 * \author Josh Klontz \cite jklontz
  65 + * \author Scott Klum \cite sklum
73 * \warning Needs a maintainer 66 * \warning Needs a maintainer
74 */ 67 */
75 -class NEC3Enroll : public UntrainableFeature 68 +class NEC3Enroll : public UntrainableTransform
76 { 69 {
77 Q_OBJECT 70 Q_OBJECT
78 - Q_PROPERTY(bool detectOnly READ get_detectOnly WRITE set_detectOnly)  
79 - MM_MEMBER(bool, detectOnly) 71 + Q_PROPERTY(bool detectOnly READ get_detectOnly WRITE set_detectOnly RESET reset_detectOnly STORED false)
  72 + BR_PROPERTY(bool, detectOnly, false)
80 73
81 - Resource<NeoFacePro::CFaceInfo> faceInfoResource;  
82 - Resource<NeoFacePro::CFaceFeature> faceFeatureResource;  
83 - QSharedPointer<Feature> flip;  
84 -  
85 - QString parameters() const  
86 - {  
87 - return "bool detectOnly = 0";  
88 - } 74 + Resource<NEC3Context> contexts;
  75 + QSharedPointer<Transform> flip;
89 76
90 void init() 77 void init()
91 { 78 {
92 - faceInfoResource.setResourceMaker(new CFaceInfoResourceMaker());  
93 - faceFeatureResource.setResourceMaker(new CFaceFeatureResourceMaker());  
94 - faceInfoResource.setMaxResources(1); // Only works in serial  
95 - faceFeatureResource.setMaxResources(1); // Only works in serial  
96 - flip = QSharedPointer<Feature>(Feature::make("Flip(X)")); 79 + contexts.setMaxResources(1);
  80 + flip = QSharedPointer<Transform>(Transform::make("Flip(X)"));
97 } 81 }
98 82
99 void project(const Template &src, Template &dst) const 83 void project(const Template &src, Template &dst) const
@@ -112,29 +96,29 @@ class NEC3Enroll : public UntrainableFeature @@ -112,29 +96,29 @@ class NEC3Enroll : public UntrainableFeature
112 binfo.bmiHeader.biHeight = input.rows; 96 binfo.bmiHeader.biHeight = input.rows;
113 binfo.bmiHeader.biBitCount = 24; 97 binfo.bmiHeader.biBitCount = 24;
114 98
115 - NeoFacePro::CFaceInfo *faceInfo = faceInfoResource.acquire();  
116 - int result = faceInfo->FindFace(binfo, input.data);  
117 - faceInfo->LocateEyes(); 99 + NEC3Context *context = contexts.acquire();
  100 + int result = context->faceInfo.FindFace(binfo, input.data);
  101 + context->faceInfo.LocateEyes();
  102 +
118 if (result == NFP_CANNOT_FIND_FACE) { 103 if (result == NFP_CANNOT_FIND_FACE) {
119 if (Globals->verbose) qDebug("NEC3Enroll face not found for file %s", qPrintable(src.file.flat())); 104 if (Globals->verbose) qDebug("NEC3Enroll face not found for file %s", qPrintable(src.file.flat()));
120 } else if (result != NFP_SUCCESS) { 105 } else if (result != NFP_SUCCESS) {
121 qWarning("NEC3Enroll FindFace error %d for file %s", result, qPrintable(src.file.flat())); 106 qWarning("NEC3Enroll FindFace error %d for file %s", result, qPrintable(src.file.flat()));
122 } 107 }
123 108
124 - NeoFacePro::CFaceFeature *faceFeature = faceFeatureResource.acquire();  
125 - QList<cv::Point2f> landmarks;  
126 - for (int i=0; i<faceInfo->GetFaceMax(); i++) {  
127 - if (faceInfo->SetFaceIndex(i) != NFP_SUCCESS) 109 + QList<QPointF> landmarks;
  110 + for (int i=0; i<context->faceInfo.GetFaceMax(); i++) {
  111 + if (context->faceInfo.SetFaceIndex(i) != NFP_SUCCESS)
128 continue; 112 continue;
129 - POINT right = faceInfo->GetRightEye();  
130 - POINT left = faceInfo->GetLeftEye();  
131 - landmarks.append(cv::Point2f(right.x, right.y));  
132 - landmarks.append(cv::Point2f(left.x, left.y)); 113 + POINT right = context->faceInfo.GetRightEye();
  114 + POINT left = context->faceInfo.GetLeftEye();
  115 + landmarks.append(QPointF(right.x, right.y));
  116 + landmarks.append(QPointF(left.x, left.y));
133 117
134 if (detectOnly) { 118 if (detectOnly) {
135 dst += src.m(); 119 dst += src.m();
136 } else { 120 } else {
137 - result = faceFeature->SetFeature(faceInfo); 121 + result = context->faceFeature.SetFeature(&context->faceInfo);
138 if (result != NFP_SUCCESS) { 122 if (result != NFP_SUCCESS) {
139 qWarning("NEC3Enroll SetFeature error %d for file %s", result, qPrintable(src.file.flat())); 123 qWarning("NEC3Enroll SetFeature error %d for file %s", result, qPrintable(src.file.flat()));
140 continue; 124 continue;
@@ -142,7 +126,7 @@ class NEC3Enroll : public UntrainableFeature @@ -142,7 +126,7 @@ class NEC3Enroll : public UntrainableFeature
142 126
143 void *data; 127 void *data;
144 long size; 128 long size;
145 - result = faceFeature->Serialize(&data, &size); 129 + result = context->faceFeature.Serialize(&data, &size);
146 if (result != NFP_SUCCESS) { 130 if (result != NFP_SUCCESS) {
147 qWarning("NEC3Enroll Serialize error %d for file %s", result, qPrintable(src.file.flat())); 131 qWarning("NEC3Enroll Serialize error %d for file %s", result, qPrintable(src.file.flat()));
148 continue; 132 continue;
@@ -156,22 +140,22 @@ class NEC3Enroll : public UntrainableFeature @@ -156,22 +140,22 @@ class NEC3Enroll : public UntrainableFeature
156 } 140 }
157 dst.file.appendLandmarks(landmarks); 141 dst.file.appendLandmarks(landmarks);
158 142
159 - faceInfoResource.release(faceInfo);  
160 - faceFeatureResource.release(faceFeature); 143 + contexts.release(context);
161 144
162 - if (src.file.getBool("ForceEnrollment") && dst.isEmpty()) dst += cv::Mat(); 145 + if (!src.file.getBool("enrollAll") && dst.isEmpty()) dst += cv::Mat();
163 } 146 }
164 }; 147 };
165 148
166 -MM_REGISTER(Feature, NEC3Enroll) 149 +BR_REGISTER(Transform, NEC3Enroll)
167 150
168 /*! 151 /*!
169 * \ingroup distances 152 * \ingroup distances
170 * \brief Compare faces with NEC NeoFace 3 SDK 153 * \brief Compare faces with NEC NeoFace 3 SDK
171 * \author Josh Klontz \cite jklontz 154 * \author Josh Klontz \cite jklontz
  155 + * \author Scott Klum \cite sklum
172 * \warning Needs a maintainer 156 * \warning Needs a maintainer
173 */ 157 */
174 -class NEC3Compare : public BasicComparer 158 +class NEC3Compare : public Distance
175 { 159 {
176 Q_OBJECT 160 Q_OBJECT
177 161
@@ -190,6 +174,6 @@ class NEC3Compare : public BasicComparer @@ -190,6 +174,6 @@ class NEC3Compare : public BasicComparer
190 } 174 }
191 }; 175 };
192 176
193 -MM_REGISTER(Comparer, NEC3Compare) 177 +BR_REGISTER(Distance, NEC3Compare)
194 178
195 #include "nec3.moc" 179 #include "nec3.moc"
sdk/plugins/reduce.cpp
@@ -79,6 +79,67 @@ class AndTransform : public UntrainableMetaTransform @@ -79,6 +79,67 @@ class AndTransform : public UntrainableMetaTransform
79 79
80 BR_REGISTER(Transform, AndTransform) 80 BR_REGISTER(Transform, AndTransform)
81 81
  82 +/*!
  83 + * \ingroup transforms
  84 + * \brief Statistics
  85 + * \author Josh Klontz \cite jklontz
  86 + */
  87 +class StatTransform : public UntrainableTransform
  88 +{
  89 + Q_OBJECT
  90 + Q_ENUMS(Statistic)
  91 + Q_PROPERTY(Statistic statistic READ get_statistic WRITE set_statistic RESET reset_statistic STORED false)
  92 +
  93 +public:
  94 + /*!
  95 + * \brief Available statistics
  96 + */
  97 + enum Statistic { Min, Max, Mean, StdDev };
  98 +
  99 +private:
  100 + BR_PROPERTY(Statistic, statistic, Mean)
  101 +
  102 + void project(const Template &src, Template &dst) const
  103 + {
  104 + if (src.m().channels() != 1)
  105 + qFatal("Expected 1 channel matrix.");
  106 + Mat m(1, 1, CV_32FC1);
  107 + if ((statistic == Min) || (statistic == Max)) {
  108 + double min, max;
  109 + minMaxLoc(src, &min, &max);
  110 + m.at<float>(1, 1) = (statistic == Min ? min : max);
  111 + } else {
  112 + Scalar mean, stddev;
  113 + meanStdDev(src, mean, stddev);
  114 + m.at<float>(1,1) = (statistic == Mean ? mean[0] : stddev[0]);
  115 + }
  116 + dst = m;
  117 + }
  118 +};
  119 +
  120 +BR_REGISTER(Transform, StatTransform)
  121 +
  122 +/*!
  123 + * \ingroup transforms
  124 + * \brief Downsample the rows and columns of a matrix.
  125 + */
  126 +class DownsampleTransform : public UntrainableTransform
  127 +{
  128 + Q_OBJECT
  129 + Q_PROPERTY(int k READ get_k WRITE set_k RESET reset_k STORED false)
  130 + BR_PROPERTY(int, k, 1)
  131 +
  132 + void project(const Template &src, Template &dst) const
  133 + {
  134 + Mat input = src.m();
  135 + Mat output;
  136 + (void) input; // TODO: write me!
  137 + dst.m() = output;
  138 + }
  139 +};
  140 +
  141 +BR_REGISTER(Transform, DownsampleTransform)
  142 +
82 } // namespace br 143 } // namespace br
83 144
84 #include "reduce.moc" 145 #include "reduce.moc"
share/openbr/cmake/FindNEC3.cmake 0 → 100644
  1 +find_path(NEC3_DIR Include/NeoFacePro.h ${CMAKE_SOURCE_DIR}/3rdparty/*)
  2 +
  3 +include_directories(${NEC3_DIR}/Include)
  4 +link_directories(${NEC3_DIR}/Lib)
  5 +
  6 +set(NEC3_LIBS NeoFacePro)