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 -