Commit 367ec95d7498bbff9d7412d694e304db91a6069a

Authored by Josh Klontz
1 parent 14131484

removed ct8

openbr/plugins/ct8.cmake deleted
1   -set(BR_WITH_CT8 OFF CACHE BOOL "Build with Cognitec FaceVACS 8")
2   -
3   -if(${BR_WITH_CT8})
4   - find_package(CT8 REQUIRED)
5   - set(BR_THIRDPARTY_SRC ${BR_THIRDPARTY_SRC} plugins/ct8.cpp ${CT8_RESOURCES})
6   -
7   - set(CT8_LIBS optimized ${CT8_LIBRARY_RELEASE} debug ${CT8_LIBRARY_DEBUG})
8   - set(BR_THIRDPARTY_LIBS ${BR_THIRDPARTY_LIBS} ${CT8_LIBS})
9   -
10   -
11   - if(WIN32)
12   - install(FILES ${CT8_DIR_LIB}/libfrsdk-8.6.0.dll
13   - DESTINATION bin)
14   - install(DIRECTORY ${CT8_DIR}/etc DESTINATION models/ct8)
15   - add_definitions(-DCT8_DIR=\"${CT8_DIR}\")
16   - else()
17   - install(FILES ${CT8_DIR_LIB}/libfrsdk-8.5.0.so
18   - ${CT8_DIR_LIB}/../share/libhasp_linux_x86_64_67109.so
19   - ${CT8_DIR_LIB}/../share/libiomp5.so
20   - DESTINATION lib)
21   - endif()
22   -endif()
openbr/plugins/ct8.cpp deleted
1   -#include <QMap>
2   -#include <QVariant>
3   -#include <opencv2/core/core.hpp>
4   -#include <opencv2/imgproc/imgproc.hpp>
5   -#include <frsdk/config.h>
6   -#include <frsdk/cptr.h>
7   -#include <frsdk/enroll.h>
8   -#include <frsdk/face.h>
9   -#include <frsdk/image.h>
10   -#include <frsdk/match.h>
11   -#include <exception>
12   -#include <string>
13   -#include <vector>
14   -
15   -#include "openbr_internal.h"
16   -#include "openbr/core/resource.h"
17   -
18   -using namespace cv;
19   -using namespace br;
20   -
21   -#define CT8_CONFIG_PROP "ct8ConfigFile"
22   -
23   -namespace FRsdk {
24   - // Construct a FaceVACS sdk ImageBody from an opencv Mat
25   - struct OpenCVImageBody : public ImageBody
26   - {
27   - OpenCVImageBody(const Mat &m, const std::string& _name = "")
28   - : w(m.cols), h(m.rows), b(0), rgb(0), n(_name)
29   - {
30   - // The ImageBody only needs to construct a grayscale or rgb
31   - // representation (whichever is indicated by isColor()), not both.
32   - if (m.channels() == 1) {
33   - is_color = false;
34   - buildByteRepresentation(m);
35   - }
36   - else {
37   - buildRgbRepresentation(m);
38   - is_color = true;
39   - }
40   -
41   - }
42   -
43   - ~OpenCVImageBody()
44   - {
45   - delete[] rgb;
46   - delete[] b;
47   - }
48   -
49   - bool isColor() const { return is_color; }
50   - unsigned int height() const { return h; }
51   - unsigned int width() const { return w; }
52   - const Byte* grayScaleRepresentation() const { return b; }
53   - const Rgb* colorRepresentation() const { return rgb; }
54   - std::string name() const { return n;}
55   -
56   - void buildRgbRepresentation(const Mat &m)
57   - {
58   - // layout required by FRsdk::Images: [Blue Green Red NotUsed]; no padding
59   - rgb = new Rgb[w * h * sizeof(Rgb)];
60   - std::vector<Mat> mv;
61   - split(m, mv);
62   - for (unsigned int i = 0; i < h; i++) {
63   - for (unsigned int k = 0; k < w; k++) {
64   - rgb[i*w+k].b = mv[0 % mv.size()].at<uchar>(i, k);
65   - rgb[i*w+k].g = mv[1 % mv.size()].at<uchar>(i, k);
66   - rgb[i*w+k].r = mv[2 % mv.size()].at<uchar>(i, k);
67   - rgb[i*w+k].a = 0;
68   - }
69   - }
70   - }
71   -
72   - void buildByteRepresentation(const Mat & m)
73   - {
74   - b = new Byte[w*h];
75   - Byte* grayp = b;
76   - for( unsigned int i = 0; i < h; i++ ) {
77   - for( unsigned int k = 0; k < w; k++ ) {
78   - *grayp = (Byte) m.at<uchar>(i,k);
79   - grayp++;
80   - }
81   - }
82   - }
83   -
84   - private:
85   - bool is_color;
86   - unsigned int w;
87   - unsigned int h;
88   - Byte* b;
89   - Rgb* rgb;
90   - std::string n;
91   - };
92   -
93   -
94   - // Enrollment::FeedbackBody subclasses are used as a set of callbacks
95   - // during facevacs enrollment. This class keeps track of whether or not
96   - // enrollment has failed (checkable via firValid()), and the extracted fir
97   - // (getFir)
98   - struct EnrolOpenCVFeedback : public Enrollment::FeedbackBody
99   - {
100   - EnrolOpenCVFeedback(Mat *_m)
101   - : m(_m), firvalid(false)
102   - {}
103   -
104   - EnrolOpenCVFeedback() {}
105   -
106   - void start() { firvalid = false; }
107   -
108   - void processingImage(const FRsdk::Image& img) { (void) img; }
109   - void eyesFound( const FRsdk::Eyes::Location& eyeLoc) { (void) eyeLoc; }
110   - void eyesNotFound() { firvalid = false;}
111   - void sampleQualityTooLow() {}
112   - void sampleQuality(const float& f) { (void) f; }
113   -
114   - void success(const FRsdk::FIR& _fir)
115   - {
116   - fir = new FRsdk::FIR(_fir);
117   - m->create(1, fir->size(), CV_8UC1);
118   - fir->serialize((Byte*)m->data);
119   - firvalid = true;
120   - }
121   -
122   - void failure() { firvalid = false; }
123   - void end() {}
124   -
125   - const FRsdk::FIR& getFir() const
126   - {
127   - if (!firvalid) qFatal("FRsdk::EnrolOpenCVFeedback::getFIR no FIR.");
128   - return *fir;
129   - }
130   -
131   - bool firValid() const { return firvalid; }
132   -
133   - private:
134   - FRsdk::CountedPtr<FRsdk::FIR> fir;
135   - Mat *m;
136   - bool firvalid;
137   - };
138   -}
139   -
140   -/*!
141   - * \ingroup initializers
142   - * \brief Initialize ct8 plugin
143   - * \author Josh Klontz \cite jklontz
144   - * \author Charles Otto \cite caotto
145   - */
146   -struct CT8Initialize : public Initializer
147   -{
148   - static FRsdk::Configuration* CT8Configuration;
149   -public:
150   - // ct8 plugin initialization, load a FRsdk config file, and register
151   - // the shortcut for using FaceVACS feature extraction/comparison
152   - void initialize() const
153   - {
154   - try {
155   - QString store_string = QString((CT8_DIR + std::string("/etc/frsdk.cfg")).c_str());
156   - Globals->setProperty(CT8_CONFIG_PROP, store_string);
157   - CT8Configuration = NULL;
158   - Globals->abbreviations.insert("CT8","Open+CT8Detect!CT8Enroll:CT8Compare");
159   - } catch (std::exception &e) {
160   - qWarning("CT8Initialize Exception: %s", e.what());
161   - CT8Configuration = NULL;
162   - }
163   - }
164   -
165   - static FRsdk::Configuration * getCT8Configuration()
166   - {
167   - if (!CT8Configuration) {
168   - QVariant recovered_variant= Globals->property(CT8_CONFIG_PROP);
169   - QString recovered_string = recovered_variant.toString();
170   - try {
171   - CT8Configuration = new FRsdk::Configuration(qPrintable(recovered_string));
172   - } catch (std::exception &e) {
173   - qFatal("CT8Initialize Exception: %s", e.what());
174   - }
175   - }
176   - return CT8Configuration;
177   - }
178   -
179   -
180   - void finalize() const
181   - {
182   - delete CT8Configuration;
183   - CT8Configuration = NULL;
184   - }
185   -};
186   -
187   -FRsdk::Configuration* CT8Initialize::CT8Configuration = NULL;
188   -
189   -BR_REGISTER(Initializer, CT8Initialize)
190   -
191   -// Adaptor class adding a default constructor to FRsdk::Enrollment::Processor
192   -// so that it can be used with Resource
193   -class CT8EnrollmentProcessor : public FRsdk::Enrollment::Processor
194   -{
195   -public:
196   - CT8EnrollmentProcessor() : FRsdk::Enrollment::Processor(*CT8Initialize::getCT8Configuration())
197   - {
198   - //
199   - }
200   -};
201   -
202   -typedef Resource<CT8EnrollmentProcessor> CT8EnrollmentProcessorResource;
203   -
204   -/*!
205   - * \brief CT8 context
206   - * \author Josh Klontz \cite jklontz
207   - * \author Charles Otto \cite caotto
208   - */
209   -struct CT8Context
210   -{
211   - CT8Context()
212   - {
213   - try {
214   - faceFinder = new FRsdk::Face::Finder(*CT8Initialize::getCT8Configuration());
215   - eyesFinder = new FRsdk::Eyes::Finder(*CT8Initialize::getCT8Configuration());
216   - firBuilder = new FRsdk::FIRBuilder(*CT8Initialize::getCT8Configuration());
217   - facialMatchingEngine = new FRsdk::FacialMatchingEngine(*CT8Initialize::getCT8Configuration());
218   - } catch (std::exception &e) {
219   - qFatal("CT8Context Exception: %s", e.what());
220   - }
221   - }
222   -
223   - virtual ~CT8Context()
224   - {
225   - delete faceFinder;
226   - delete eyesFinder;
227   - delete firBuilder;
228   - delete facialMatchingEngine;
229   - }
230   -
231   - // Enroll an FRsdk::Sample (can be various types, generally an image that
232   - // maybe has some extra data like detected eye locations).
233   - bool enroll(const FRsdk::Sample &sample, Mat *m) const
234   - {
235   - try {
236   - FRsdk::SampleSet sampleSet;
237   - sampleSet.push_back(sample);
238   -
239   - FRsdk::EnrolOpenCVFeedback * feedback_body = new FRsdk::EnrolOpenCVFeedback(m);
240   - FRsdk::CountedPtr<FRsdk::Enrollment::FeedbackBody> feedback_ptr(feedback_body);
241   -
242   - FRsdk::Enrollment::Feedback enrollmentFeedback(feedback_ptr);
243   -
244   - CT8EnrollmentProcessor * enrollmentProcessor = enrollmentProcessors.acquire();
245   - enrollmentProcessor->process(sampleSet.begin(), sampleSet.end(), enrollmentFeedback);
246   - enrollmentProcessors.release(enrollmentProcessor);
247   - if (!feedback_body->firValid()) return false;
248   - } catch (std::exception &e) {
249   - qFatal("CT8Context Exception: %s", e.what());
250   - return false;
251   - }
252   - return true;
253   - }
254   -
255   -
256   - // Input: an image, and pre-detected eye locations, returns false if enrollment fails
257   - bool enroll(const FRsdk::Image &img, const FRsdk::Eyes::Location &eyes, Mat *m) const
258   - {
259   - try {
260   - FRsdk::Sample sample(FRsdk::AnnotatedImage(img, eyes));
261   - return enroll(sample, m);
262   - } catch (std::exception &e) {
263   - qFatal("CT8Context Exception: %s", e.what());
264   - return false;
265   - }
266   - return true;
267   - }
268   -
269   - // Input: an image, no eye locations (facevacs will do detection with
270   - // default parameters. Returns false if enrollment fails
271   - bool enroll(const FRsdk::Image &img, Mat *m) const
272   - {
273   - try {
274   - FRsdk::Sample sample(img);
275   - return enroll(sample, m);
276   - } catch (std::exception &e) {
277   - qFatal("CT8Context Exception: %s", e.what());
278   - return false;
279   - }
280   - return true;
281   - }
282   -
283   - static FRsdk::Position toPosition(const QPointF &point)
284   - {
285   - return FRsdk::Position(point.x(), point.y());
286   - }
287   -
288   -protected:
289   - FRsdk::Face::Finder *faceFinder;
290   - FRsdk::Eyes::Finder *eyesFinder;
291   - CT8EnrollmentProcessorResource enrollmentProcessors;
292   - FRsdk::FIRBuilder *firBuilder;
293   - FRsdk::FacialMatchingEngine *facialMatchingEngine;
294   -};
295   -
296   -/*!
297   - * \ingroup transforms
298   - * \brief Perform face and eye detection with the FaceVACS SDK.
299   - * \author Josh Klontz \cite jklontz
300   - * \author Charles Otto \cite caotto
301   - */
302   -class CT8DetectTransform : public UntrainableTransform
303   - , public CT8Context
304   -{
305   - Q_OBJECT
306   - Q_PROPERTY(float minRelEyeDistance READ get_minRelEyeDistance WRITE set_minRelEyeDistance RESET reset_minRelEyeDistance STORED false)
307   - Q_PROPERTY(float maxRelEyeDistance READ get_maxRelEyeDistance WRITE set_maxRelEyeDistance RESET reset_maxRelEyeDistance STORED false)
308   - BR_PROPERTY(float, minRelEyeDistance, 0.01f)
309   - BR_PROPERTY(float, maxRelEyeDistance, 0.4f)
310   -
311   - // Perform face, then eye detection using the facevacs SDK
312   - void project(const Template &src, Template &dst) const
313   - {
314   - try {
315   - // Build an FRsdk image from the input openCV mat
316   - FRsdk::CountedPtr<FRsdk::ImageBody> i(new FRsdk::OpenCVImageBody(src));
317   - FRsdk::Image img(i);
318   - FRsdk::Face::LocationSet faceLocations = faceFinder->find(img, minRelEyeDistance, maxRelEyeDistance);
319   -
320   - // Attempt to detect eyes in any face ROIs that were detected
321   - QList<QRectF> rects;
322   - QList<QPointF> points;
323   - FRsdk::Face::LocationSet::const_iterator faceLocationSetIterator = faceLocations.begin();
324   - while (faceLocationSetIterator != faceLocations.end()) {
325   - FRsdk::Face::Location faceLocation = *faceLocationSetIterator; faceLocationSetIterator++;
326   - FRsdk::Eyes::LocationSet currentEyesLocations = eyesFinder->find(img, faceLocation);
327   -
328   - if (currentEyesLocations.size() > 0) {
329   - rects.append(QRectF(faceLocation.pos.x(), faceLocation.pos.y(), faceLocation.width, faceLocation.width));
330   - points.append(QPointF(currentEyesLocations.front().first.x(), currentEyesLocations.front().first.y()));
331   - points.append(QPointF(currentEyesLocations.front().second.x(), currentEyesLocations.front().second.y()));
332   - dst += src.m();
333   - if (!Globals->enrollAll) break;
334   - }
335   - }
336   -
337   - // If eye detection failed, mark the output as a failure
338   - if (dst.isEmpty()) {
339   - dst.file.set("FTE", true);
340   - if (!Globals->enrollAll) dst += Mat();
341   - }
342   - dst.file.appendRects(rects);
343   - dst.file.appendPoints(points);
344   - } catch (std::exception &e) {
345   - qFatal("CT8Enroll Exception: %s", e.what());
346   - }
347   - }
348   -};
349   -
350   -BR_REGISTER(Transform, CT8DetectTransform)
351   -
352   -/*!
353   - * \ingroup transforms
354   - * \brief Enroll face images using the FaceVACS SDK
355   - * \author Josh Klontz \cite jklontz
356   - * \author Charles Otto \cite caotto
357   - */
358   -class CT8EnrollTransform : public UntrainableTransform
359   - , public CT8Context
360   -{
361   - Q_OBJECT
362   -
363   - // enroll an image using the facevacs sdk. Generates a facevacs "fir" which
364   - // is their face representation.
365   - void project(const Template &src, Template &dst) const
366   - {
367   - try {
368   - FRsdk::CountedPtr<FRsdk::ImageBody> i(new FRsdk::OpenCVImageBody(src));
369   - FRsdk::Image img(i);
370   -
371   - // If we already have eye locations, use them
372   - QList<QPointF> points = src.file.points();
373   - bool enrollSucceeded = false;
374   - if (points.size() == 2) {
375   - enrollSucceeded = enroll(img, FRsdk::Eyes::Location(toPosition(points[0]), toPosition(points[1])), &(dst.m()));
376   -
377   - // Transfer previously detectd eye and face locations to the output dst.
378   - dst.file.set("First_Eye", points[0]);
379   - dst.file.set("Second_Eye", points[1]);
380   -
381   - QList<QRectF> rects = src.file.rects();
382   - if (rects.size() == 1)
383   - dst.file.set("Face", rects.first());
384   - } else {
385   - // If we don't have eye locations already, calling enroll here
386   - // will cause facevacs to perform detection using default
387   - // parameters (and we will not receive the detected locations
388   - // as output).
389   - enrollSucceeded = enroll(img, &(dst.m()));
390   - }
391   -
392   - // If enrollment failed, mark this image as a failure. This will
393   - // typically only happen if we aren't using pre-detected eye
394   - // locations
395   - if (!enrollSucceeded) {
396   - dst.file.set("FTE", true);
397   - dst.m() = Mat();
398   - }
399   - } catch (std::exception &e) {
400   - qFatal("CT8Enroll Exception: %s", e.what());
401   - }
402   - }
403   -};
404   -
405   -BR_REGISTER(Transform, CT8EnrollTransform)
406   -
407   -/*!
408   - * \ingroup distances
409   - * \brief Compare FaceVACS templates
410   - * \author Josh Klontz \cite jklontz
411   - * \author Charles Otto \cite caotto
412   - */
413   -struct CT8Compare : public Distance,
414   - public CT8Context
415   -{
416   - Q_OBJECT
417   -
418   - // Compare pre-extracted facevacs templates
419   - float compare(const Template &srcA, const Template &srcB) const
420   - {
421   - float score = -std::numeric_limits<float>::max();
422   - if (!srcA.m().data || !srcB.m().data) return score;
423   -
424   - try {
425   - static QMutex mutex;
426   - QMutexLocker locker(&mutex);
427   -
428   - // Internally Cognitec keeps a total count of the allocated templates,
429   - // it seems that this reference count update is not thread safe
430   - FRsdk::FIR firA = firBuilder->build( (FRsdk::Byte *) srcA.m().data, srcA.m().cols);
431   - FRsdk::FIR firB = firBuilder->build( (FRsdk::Byte *) srcB.m().data, srcB.m().cols);
432   -
433   - score = (float)facialMatchingEngine->compare(firA, firB);
434   - } catch (std::exception &e) {
435   - qFatal("CT8Compare Exception: %s", e.what());
436   - }
437   -
438   - return score;
439   - }
440   -};
441   -
442   -BR_REGISTER(Distance, CT8Compare)
443   -
444   -#include "plugins/ct8.moc"
445   -