Commit 74d09154611152fcf768fa182fe03e1f0a41fcc6

Authored by Josh Klontz
1 parent c0232698

removed pp5 plugin

openbr/plugins/classification/pp5.cpp deleted
1   -#include <QDebug>
2   -#include <QFileInfo>
3   -#include <QMap>
4   -#include <QMutex>
5   -#include <QSharedPointer>
6   -#include <QString>
7   -#include <QStringList>
8   -#include <QThreadPool>
9   -#include <QVariant>
10   -#include <pittpatt_errors.h>
11   -#include <pittpatt_raw_image_io.h>
12   -#include <pittpatt_sdk.h>
13   -#include <pittpatt_license.h>
14   -#include "openbr/plugins/openbr_internal.h"
15   -#include "openbr/core/resource.h"
16   -
17   -#define TRY(CC) \
18   -{ \
19   - if ((CC) != PPR_SUCCESS) qFatal("%d error (%s, %d): %s.", CC, __FILE__, __LINE__, ppr_error_message(CC)); \
20   -}
21   -
22   -#define TRY_VIDEO(CC) \
23   -{ \
24   - if ((CC) != PPR_VIDEO_IO_SUCCESS) qFatal("%d error (%s, %d): %s.", CC, __FILE__, __LINE__, ppr_video_io_error_message(CC)); \
25   -}
26   -
27   -#define TRY_RAW_IMAGE(CC) \
28   -{ \
29   - if ((CC) != PPR_RAW_IMAGE_SUCCESS) qFatal("%d error (%s, %d): %s.", CC, __FILE__, __LINE__, ppr_raw_image_error_message(CC)); \
30   -}
31   -
32   -using namespace br;
33   -
34   -/*!
35   - * \ingroup initializers
36   - * \brief Initialize PP5
37   - * \author Josh Klontz \cite jklontz
38   - * \author E. Taborsky \cite mmtaborsky
39   - * \warning PittPatt 5.x.x is known to NOT work with MinGW-w64 due to a segfault in ppr_initialize_sdk.
40   - */
41   -class PP5Initializer : public Initializer
42   -{
43   - Q_OBJECT
44   -
45   - void initialize() const
46   - {
47   - TRY(ppr_initialize_sdk(qPrintable(Globals->sdkPath + "/share/openbr/models/pp5/"), my_license_id, my_license_key))
48   - Globals->abbreviations.insert("PP5","Open+Expand+PP5Enroll!PP5Gallery");
49   - Globals->abbreviations.insert("PP5Register", "PP5Enroll(true,true,0.02,5,Extended)+RenameFirst([eyeL,PP5_Landmark0_Right_Eye],Affine_0)+RenameFirst([eyeR,PP5_Landmark1_Left_Eye],Affine_1)");
50   - Globals->abbreviations.insert("PP5CropFace", "Open+PP5Enroll(true)+RenameFirst([eyeL,PP5_Landmark0_Right_Eye],Affine_0)+RenameFirst([eyeR,PP5_Landmark1_Left_Eye],Affine_1)+Affine(128,128,0.25,0.35)+Cvt(Gray)");
51   - }
52   -
53   - void finalize() const
54   - {
55   - ppr_finalize_sdk();
56   - }
57   -};
58   -
59   -BR_REGISTER(Initializer, PP5Initializer)
60   -
61   -/*!
62   - * \brief PP5 context
63   - * \author Josh Klontz \cite jklontz
64   - * \author E. Taborsky \cite mmtaborsky
65   - */
66   -struct PP5Context
67   -{
68   - ppr_context_type context;
69   -
70   - PP5Context(bool detectOnly = false, float adaptiveMinSize = 0.01f, int minSize = 4, ppr_landmark_range_type landmarkRange = PPR_LANDMARK_RANGE_COMPREHENSIVE, int searchPruningAggressiveness = 0)
71   - {
72   - ppr_settings_type default_settings = ppr_get_default_settings();
73   -
74   - default_settings.detection.adaptive_max_size = 1.f;
75   - default_settings.detection.adaptive_min_size = adaptiveMinSize;
76   - default_settings.detection.detect_best_face_only = !Globals->enrollAll;
77   - default_settings.detection.enable = 1;
78   - default_settings.detection.min_size = minSize;
79   - default_settings.detection.search_pruning_aggressiveness = searchPruningAggressiveness;
80   - default_settings.detection.use_serial_face_detection = 1;
81   -
82   - default_settings.landmarks.enable = 1;
83   - default_settings.landmarks.landmark_range = landmarkRange;
84   - default_settings.landmarks.manually_detect_landmarks = 0;
85   -
86   - default_settings.recognition.automatically_extract_templates = !detectOnly;
87   - default_settings.recognition.enable_comparison = !detectOnly;
88   - default_settings.recognition.enable_extraction = !detectOnly;
89   - default_settings.recognition.num_comparison_threads = 1;
90   - default_settings.recognition.recognizer = PPR_RECOGNIZER_MULTI_POSE;
91   - TRY(ppr_initialize_context(default_settings, &context))
92   - }
93   -
94   - ~PP5Context()
95   - {
96   - TRY(ppr_finalize_context(context))
97   - }
98   -
99   - static void createRawImage(const cv::Mat &src, ppr_raw_image_type &dst)
100   - {
101   - if (!src.isContinuous()) qFatal("PP5Context::createRawImage requires continuous data.");
102   - else if (src.channels() == 3) ppr_raw_image_create(&dst, src.cols, src.rows, PPR_RAW_IMAGE_BGR24);
103   - else if (src.channels() == 1) ppr_raw_image_create(&dst, src.cols, src.rows, PPR_RAW_IMAGE_GRAY8);
104   - else qFatal("PP5Context::createRawImage invalid channel count.");
105   - memcpy(dst.data, src.data, src.channels()*src.rows*src.cols);
106   - }
107   -
108   - void createMat(const ppr_face_type &src, cv::Mat &dst) const
109   - {
110   - ppr_flat_data_type flat_data;
111   - TRY(ppr_flatten_face(context,src,&flat_data))
112   - dst = cv::Mat(1, flat_data.length, CV_8UC1, flat_data.data).clone();
113   - ppr_free_flat_data(flat_data);
114   - }
115   -
116   - void createFace(const cv::Mat &src, ppr_face_type *dst) const
117   - {
118   - ppr_flat_data_type flat_data;
119   - flat_data.length = src.cols;
120   - flat_data.data = src.data;
121   - TRY(ppr_unflatten_face(context, flat_data, dst))
122   - }
123   -
124   - static QString toString(const ppr_landmark_category_type &category)
125   - {
126   - switch (category) {
127   - case PPR_LANDMARK_CATEGORY_LEFT_EYE:
128   - return "Left_Eye";
129   - case PPR_LANDMARK_CATEGORY_RIGHT_EYE:
130   - return "Right_Eye";
131   - case PPR_LANDMARK_CATEGORY_NOSE_BASE:
132   - return "Nose_Base";
133   - case PPR_LANDMARK_CATEGORY_NOSE_BRIDGE:
134   - return "Nose_Bridge";
135   - case PPR_LANDMARK_CATEGORY_EYE_NOSE:
136   - return "Eye_Nose";
137   - case PPR_LANDMARK_CATEGORY_LEFT_UPPER_CHEEK:
138   - return "Left_Upper_Cheek";
139   - case PPR_LANDMARK_CATEGORY_LEFT_LOWER_CHEEK:
140   - return "Left_Lower_Cheek";
141   - case PPR_LANDMARK_CATEGORY_RIGHT_UPPER_CHEEK:
142   - return "Right_Upper_Cheek";
143   - case PPR_LANDMARK_CATEGORY_RIGHT_LOWER_CHEEK:
144   - return "Right_Lower_Cheek";
145   - case PPR_NUM_LANDMARK_CATEGORIES:
146   - return "Num_Landmark_Categories";
147   - }
148   -
149   - return "Unknown";
150   - }
151   -
152   - static QMap<QString,QVariant> toMetadata(const ppr_face_type &face)
153   - {
154   - QMap<QString,QVariant> metadata;
155   -
156   - ppr_face_attributes_type face_attributes;
157   - ppr_get_face_attributes(face, &face_attributes);
158   - metadata.insert("FrontalFace", QRectF(face_attributes.position.x - face_attributes.dimensions.width/2,
159   - face_attributes.position.y - face_attributes.dimensions.height/2,
160   - face_attributes.dimensions.width,
161   - face_attributes.dimensions.height));
162   - metadata.insert("Confidence", face_attributes.confidence);
163   - metadata.insert("PP5_Face_Roll", face_attributes.rotation.roll);
164   - metadata.insert("PP5_Face_Pitch", face_attributes.rotation.pitch);
165   - metadata.insert("PP5_Face_Yaw", face_attributes.rotation.yaw);
166   - metadata.insert("PP5_Face_HasThumbnail", face_attributes.has_thumbnail);
167   - metadata.insert("PP5_Face_NumLandmarks", face_attributes.num_landmarks);
168   - metadata.insert("PP5_Face_Size", face_attributes.size);
169   - metadata.insert("PP5_TrackingInfo_ConfidenceLevel", face_attributes.tracking_info.confidence_level);
170   - metadata.insert("PP5_TrackingInfo_FrameNumber", face_attributes.tracking_info.frame_number);
171   - metadata.insert("PP5_TrackingInfo_TrackID", face_attributes.tracking_info.track_id);
172   -
173   - ppr_landmark_list_type landmark_list;
174   - TRY(ppr_get_face_landmarks(face, &landmark_list))
175   -
176   - QList<ppr_landmark_category_type> categories;
177   - categories << PPR_LANDMARK_CATEGORY_RIGHT_EYE
178   - << PPR_LANDMARK_CATEGORY_LEFT_EYE
179   - << PPR_LANDMARK_CATEGORY_NOSE_BASE
180   - << PPR_LANDMARK_CATEGORY_NOSE_BRIDGE
181   - << PPR_LANDMARK_CATEGORY_EYE_NOSE
182   - << PPR_LANDMARK_CATEGORY_LEFT_UPPER_CHEEK
183   - << PPR_LANDMARK_CATEGORY_LEFT_LOWER_CHEEK
184   - << PPR_LANDMARK_CATEGORY_RIGHT_UPPER_CHEEK
185   - << PPR_LANDMARK_CATEGORY_RIGHT_LOWER_CHEEK;
186   - for (int i=0; i<categories.size(); i++) {
187   - ppr_landmark_category_type category = categories[i];
188   - QString metadataString = QString("PP5_Landmark%1_%2").arg(QString::number(i), toString(category));
189   -
190   - bool found = false;
191   - for (int j=0; j<landmark_list.length; j++) {
192   - ppr_landmark_type &landmark = landmark_list.landmarks[j];
193   - if (landmark.category != category) continue;
194   -
195   - metadata.insert(metadataString, QPointF(landmark.position.x, landmark.position.y));
196   - found = true;
197   - break;
198   - }
199   -
200   - if (!found) {
201   - metadata.insert(metadataString, QPointF(std::numeric_limits<float>::quiet_NaN(), std::numeric_limits<float>::quiet_NaN()));
202   - }
203   - }
204   -
205   - ppr_free_landmark_list(landmark_list);
206   -
207   - return metadata;
208   - }
209   -
210   - void compareNative(ppr_gallery_type target, const QList<int> &targetIDs, ppr_gallery_type query, const QList<int> &queryIDs, Output *output) const
211   - {
212   - ppr_similarity_matrix_type simmat;
213   - TRY(ppr_compare_galleries(context, query, target, &simmat))
214   - for (int i=0; i<queryIDs.size(); i++) {
215   - int query_subject_id = queryIDs[i];
216   - for (int j=0; j<targetIDs.size(); j++) {
217   - int target_subject_id = targetIDs[j];
218   - float score = -std::numeric_limits<float>::max();
219   - if ((query_subject_id != -1) && (target_subject_id != -1)) {
220   - TRY(ppr_get_subject_similarity_score(context, simmat, query_subject_id, target_subject_id, &score))
221   - }
222   - output->setRelative(score, i, j);
223   - }
224   - }
225   - ppr_free_similarity_matrix(simmat);
226   - }
227   -
228   - void enroll(const TemplateList &templates, ppr_gallery_type *gallery, QList<int> &subject_ids) const
229   - {
230   - int subject_id = 0, face_id = 0;
231   - foreach (const Template &src, templates) {
232   - if (!src.empty() && src.m().data) {
233   - foreach (const cv::Mat &m, src) {
234   - ppr_face_type face;
235   - createFace(m, &face);
236   - TRY(ppr_add_face(context, gallery, face, subject_id, face_id))
237   - face_id++;
238   - ppr_free_face(face);
239   - }
240   - subject_ids.append(subject_id);
241   - subject_id++;
242   - } else {
243   - subject_ids.append(-1);
244   - }
245   - }
246   - }
247   -
248   -};
249   -
250   -/*!
251   - * \ingroup transforms
252   - * \brief Enroll faces in PP5
253   - * \author Josh Klontz \cite jklontz
254   - * \author E. Taborsky \cite mmtaborsky
255   - * \br_property bool detectOnly If true, enroll all detected faces. Otherwise, only enroll faces suitable for recognition. Default is false.
256   - * \br_property bool requireLandmarks If true, require the right eye, left eye, and nose base to be detectable by PP5. If this does not happen FTE is set to true for that template. Default is false.
257   - * \br_property float adaptiveMinSize The minimum face size as a percentage of total image width. 0.1 corresponds to a minimum face size of 10% the total image width. Default is 0.01.
258   - * \br_property int minSize The absolute minimum face size to search for. This is not a pixel value. Please see PittPatt documentation for the relationship between minSize and pixel IPD. Default is 4.
259   - * \br_property enum landmarkRange Range of landmarks to search for. Options are Frontal, Extended, Full, and Comprehensive. Default is Comprehensive.
260   - * \br_property int searchPruningAggressiveness The amount of aggressiveness involved in search for faces in images. 0 means all scales and locations are searched. 1 means fewer detectors are used in the early stages but all scales are still searched. 2-4 means that the largest faces are found first and then fewer scales are searched. Default is 0.
261   - */
262   -class PP5EnrollTransform : public UntrainableMetaTransform
263   -{
264   - Q_OBJECT
265   - Q_PROPERTY(bool detectOnly READ get_detectOnly WRITE set_detectOnly RESET reset_detectOnly STORED false)
266   - Q_PROPERTY(bool requireLandmarks READ get_requireLandmarks WRITE set_requireLandmarks RESET reset_requireLandmarks STORED false)
267   - Q_PROPERTY(float adaptiveMinSize READ get_adaptiveMinSize WRITE set_adaptiveMinSize RESET reset_adaptiveMinSize STORED false)
268   - Q_PROPERTY(int minSize READ get_minSize WRITE set_minSize RESET reset_minSize STORED false)
269   - Q_PROPERTY(LandmarkRange landmarkRange READ get_landmarkRange WRITE set_landmarkRange RESET reset_landmarkRange STORED false)
270   - Q_PROPERTY(int searchPruningAggressiveness READ get_searchPruningAggressiveness WRITE set_searchPruningAggressiveness RESET reset_searchPruningAggressiveness STORED false)
271   -
272   -public:
273   - enum LandmarkRange
274   - {
275   - Frontal = PPR_LANDMARK_RANGE_FRONTAL,
276   - Extended = PPR_LANDMARK_RANGE_EXTENDED,
277   - Full = PPR_LANDMARK_RANGE_FULL,
278   - Comprehensive = PPR_LANDMARK_RANGE_COMPREHENSIVE
279   - };
280   - Q_ENUMS(LandmarkRange)
281   -
282   -private:
283   - BR_PROPERTY(bool, detectOnly, false)
284   - BR_PROPERTY(bool, requireLandmarks, false)
285   - BR_PROPERTY(float, adaptiveMinSize, 0.01f)
286   - BR_PROPERTY(int, minSize, 4)
287   - BR_PROPERTY(LandmarkRange, landmarkRange, Comprehensive)
288   - BR_PROPERTY(int, searchPruningAggressiveness, 0)
289   -
290   - Resource<PP5Context> contexts;
291   -
292   - struct PP5ContextMaker : public ResourceMaker<PP5Context>
293   - {
294   - PP5ContextMaker(PP5EnrollTransform *pp5EnrollTransform)
295   - : pp5EnrollTransform(pp5EnrollTransform) {}
296   -
297   - private:
298   - PP5EnrollTransform *pp5EnrollTransform;
299   -
300   - PP5Context *make() const
301   - {
302   - return new PP5Context(pp5EnrollTransform->detectOnly,
303   - pp5EnrollTransform->adaptiveMinSize,
304   - pp5EnrollTransform->minSize,
305   - (ppr_landmark_range_type) pp5EnrollTransform->landmarkRange,
306   - pp5EnrollTransform->searchPruningAggressiveness);
307   - }
308   - };
309   -
310   - void init()
311   - {
312   - contexts.setResourceMaker(new PP5ContextMaker(this));
313   - }
314   -
315   - void project(const Template &src, Template &dst) const
316   - {
317   - if (Globals->enrollAll)
318   - qFatal("single template project doesn't support enrollAll");
319   -
320   - TemplateList srcList;
321   - srcList.append(src);
322   - TemplateList dstList;
323   - project(srcList, dstList);
324   - dst = dstList.first();
325   - }
326   -
327   - void project(const TemplateList &srcList, TemplateList &dstList) const
328   - {
329   - // Nothing to do here
330   - if (srcList.empty())
331   - return;
332   -
333   - PP5Context *context = contexts.acquire();
334   -
335   - foreach (const Template &src, srcList) {
336   - bool foundFace = false;
337   - if (!src.isEmpty()) {
338   - ppr_raw_image_type raw_image;
339   - PP5Context::createRawImage(src, raw_image);
340   - ppr_image_type image;
341   - TRY(ppr_create_image(raw_image, &image))
342   - ppr_face_list_type face_list;
343   - TRY(ppr_detect_faces(context->context, image, &face_list))
344   -
345   - for (int i=0; i<face_list.length; i++) {
346   - ppr_face_type face = face_list.faces[i];
347   - if (!detectOnly) {
348   - int extractable;
349   - TRY(ppr_is_template_extractable(context->context, face, &extractable))
350   - if (!extractable)
351   - continue;
352   - }
353   - foundFace = true;
354   -
355   - cv::Mat m;
356   - if (detectOnly) {
357   - m = src;
358   - } else {
359   - TRY(ppr_extract_face_template(context->context, image, &face))
360   - context->createMat(face, m);
361   - }
362   - Template dst;
363   - dst.file = src.file;
364   -
365   - dst.file.append(PP5Context::toMetadata(face));
366   - if (requireLandmarks) {
367   - QPointF right = dst.file.get<QPointF>("PP5_Landmark0_Right_Eye");
368   - QPointF left = dst.file.get<QPointF>("PP5_Landmark1_Left_Eye");
369   - QPointF nose = dst.file.get<QPointF>("PP5_Landmark2_Nose_Base");
370   - // a number not equaling itself means it's NaN
371   - // there should be no NaNs for the 3 special landmarks
372   - if (dst.file.get<int>("PP5_Face_NumLandmarks") < 3 ||
373   - right.x() != right.x() || right.y() != right.y() ||
374   - left.x() != left.x() || left.y() != left.y() ||
375   - nose.x() != nose.x() || nose.y() != nose.y())
376   - {
377   - dst.file.fte = true;
378   - }
379   - }
380   - dst += m;
381   - dstList.append(dst);
382   -
383   - // Found a face, nothing else to do (if we aren't trying to find multiple faces).
384   - if (!Globals->enrollAll)
385   - break;
386   - }
387   -
388   - ppr_free_face_list(face_list);
389   - ppr_free_image(image);
390   - ppr_raw_image_free(raw_image);
391   - }
392   -
393   - // No faces were detected when we were expecting one, output something with FTE set.
394   - if (!foundFace && !Globals->enrollAll) {
395   - dstList.append(Template(src.file, detectOnly ? src.m() : cv::Mat()));
396   - dstList.last().file.fte = true;
397   - }
398   - }
399   -
400   - contexts.release(context);
401   - }
402   -};
403   -
404   -BR_REGISTER(Transform, PP5EnrollTransform)
405   -
406   -
407   -/*!
408   - * \ingroup distances
409   - * \brief Compare templates with PP5. PP5 distance is known to be asymmetric
410   - * \author Josh Klontz \cite jklontz
411   - * \author E. Taborsky \cite mmtaborsky
412   - */
413   -class PP5CompareDistance : public UntrainableDistance
414   - , public PP5Context
415   -{
416   - Q_OBJECT
417   -
418   - struct NativeGallery
419   - {
420   - FileList files;
421   - QList<int> subjectIDs;
422   - ppr_gallery_type gallery;
423   - };
424   -
425   - mutable QMap<QString, NativeGallery> cache;
426   - mutable QMutex cacheLock;
427   -
428   - ~PP5CompareDistance()
429   - {
430   - foreach (const NativeGallery &gallery, cache.values())
431   - ppr_free_gallery(gallery.gallery);
432   - }
433   -
434   - float compare(const cv::Mat &target, const cv::Mat &query) const
435   - {
436   - return compare(Template(target), Template(query));
437   - }
438   -
439   - float compare(const Template &target, const Template &query) const
440   - {
441   - TemplateList targetList;
442   - targetList.append(target);
443   - TemplateList queryList;
444   - queryList.append(query);
445   - MatrixOutput *score = MatrixOutput::make(targetList.files(), queryList.files());
446   - compare(targetList, queryList, score);
447   - return score->data.at<float>(0);
448   - }
449   -
450   - void compare(const TemplateList &target, const TemplateList &query, Output *output) const
451   - {
452   - ppr_gallery_type target_gallery, query_gallery;
453   - ppr_create_gallery(context, &target_gallery);
454   - ppr_create_gallery(context, &query_gallery);
455   - QList<int> target_subject_ids, query_subject_ids;
456   - enroll(target, &target_gallery, target_subject_ids);
457   - enroll(query, &query_gallery, query_subject_ids);
458   - compareNative(target_gallery, target_subject_ids, query_gallery, query_subject_ids, output);
459   - ppr_free_gallery(target_gallery);
460   - ppr_free_gallery(query_gallery);
461   - }
462   -
463   - NativeGallery cacheRetain(const File &gallery) const
464   - {
465   - QMutexLocker locker(&cacheLock);
466   - NativeGallery nativeGallery;
467   - if (cache.contains(gallery.name)) {
468   - nativeGallery = cache[gallery.name];
469   - } else {
470   - ppr_create_gallery(context, &nativeGallery.gallery);
471   - TemplateList templates = TemplateList::fromGallery(gallery);
472   - enroll(templates, &nativeGallery.gallery, nativeGallery.subjectIDs);
473   - nativeGallery.files = templates.files();
474   - if (gallery.get<bool>("retain"))
475   - cache.insert(gallery.name, nativeGallery);
476   - }
477   - return nativeGallery;
478   - }
479   -
480   - void cacheRelease(const File &gallery, const NativeGallery &nativeGallery) const
481   - {
482   - QMutexLocker locker(&cacheLock);
483   - if (cache.contains(gallery.name)) {
484   - if (gallery.get<bool>("release")) {
485   - cache.remove(gallery.name);
486   - ppr_free_gallery(nativeGallery.gallery);
487   - }
488   - } else {
489   - ppr_free_gallery(nativeGallery.gallery);
490   - }
491   - }
492   -
493   - bool compare(const File &targetGallery, const File &queryGallery, const File &output) const
494   - {
495   - if (!targetGallery.get<bool>("native") || !queryGallery.get<bool>("native"))
496   - return false;
497   -
498   - NativeGallery nativeTarget = cacheRetain(targetGallery);
499   - NativeGallery nativeQuery = cacheRetain(queryGallery);
500   -
501   - QScopedPointer<Output> o(Output::make(output, nativeTarget.files, nativeQuery.files));
502   - o->setBlock(0, 0);
503   - compareNative(nativeTarget.gallery, nativeTarget.subjectIDs, nativeQuery.gallery, nativeQuery.subjectIDs, o.data());
504   -
505   - cacheRelease(targetGallery, nativeTarget);
506   - cacheRelease(queryGallery, nativeQuery);
507   - return true;
508   - }
509   -};
510   -
511   -BR_REGISTER(Distance, PP5CompareDistance)
512   -
513   -/*!
514   - * \brief DOCUMENT ME
515   - * \author Unknown \cite unknown
516   - */
517   -class PP5GalleryTransform: public UntrainableMetaTransform
518   - , public PP5Context
519   -{
520   - Q_OBJECT
521   - Q_PROPERTY(QString galleryName READ get_galleryName WRITE set_galleryName RESET reset_galleryName STORED false)
522   - BR_PROPERTY(QString, galleryName, "")
523   -
524   - ppr_gallery_type target;
525   - QList<int> targetIDs;
526   - TemplateList gallery;
527   -
528   - void project(const Template &src, Template &dst) const
529   - {
530   - TemplateList temp, output;
531   - temp.append(src);
532   - project(temp, output);
533   - if (!output.empty())
534   - dst = output[0];
535   - }
536   -
537   - void project(const TemplateList &src, TemplateList &dst) const
538   - {
539   - dst.clear();
540   - QList<int> queryIDs;
541   -
542   - ppr_gallery_type query;
543   - ppr_create_gallery(context, &query);
544   - enroll(src,&query, queryIDs);
545   -
546   - ppr_similarity_matrix_type simmat;
547   -
548   - TRY(ppr_compare_galleries(context, query, target, &simmat))
549   -
550   - for (int i=0; i<queryIDs.size(); i++) {
551   - dst.append(Template());
552   - dst[i].file = src[i].file;
553   - dst[i].m() = cv::Mat(1,targetIDs.size(), CV_32FC1);
554   -
555   - int query_subject_id = queryIDs[i];
556   - for (int j=0; j<targetIDs.size(); j++) {
557   - int target_subject_id = targetIDs[j];
558   - float score = -std::numeric_limits<float>::max();
559   - if ((query_subject_id != -1) && (target_subject_id != -1)) {
560   - TRY(ppr_get_subject_similarity_score(context, simmat, query_subject_id, target_subject_id, &score))
561   - }
562   - dst[i].m().at<float>(0,j) = score;
563   - }
564   - }
565   -
566   - ppr_free_similarity_matrix(simmat);
567   - ppr_free_gallery(query);
568   - }
569   -
570   - void init()
571   - {
572   - if (!galleryName.isEmpty() || !gallery.isEmpty()) {
573   - // set up the gallery
574   - ppr_create_gallery(context, &target);
575   - if (gallery.isEmpty() )
576   - gallery = TemplateList::fromGallery(galleryName);
577   - enroll(gallery, &target, targetIDs);
578   - }
579   - }
580   -
581   - void train(const TemplateList &data)
582   - {
583   - gallery = data;
584   - }
585   -
586   - void store(QDataStream &stream) const
587   - {
588   - br::Object::store(stream);
589   - stream << gallery;
590   - }
591   -
592   - void load(QDataStream &stream)
593   - {
594   - br::Object::load(stream);
595   - stream >> gallery;
596   - init();
597   - }
598   -
599   -};
600   -
601   -BR_REGISTER(Transform, PP5GalleryTransform)
602   -
603   -#include "classification/pp5.moc"
openbr/plugins/cmake/pp5.cmake deleted
1   -set(BR_WITH_PP5 OFF CACHE BOOL "Build with PittPatt 5")
2   -
3   -if(${BR_WITH_PP5})
4   - find_package(PP5 REQUIRED)
5   - set(BR_THIRDPARTY_LIBS ${BR_THIRDPARTY_LIBS} ${PP5_LIBS})
6   -
7   - if(WIN32)
8   - install(DIRECTORY ${PP5_DIR}/lib/ DESTINATION bin)
9   - else()
10   - install(DIRECTORY ${PP5_DIR}/lib/ DESTINATION lib)
11   - endif()
12   -
13   - install(DIRECTORY ${PP5_DIR}/models/ DESTINATION share/openbr/models/pp5)
14   -else()
15   - set(BR_EXCLUDED_PLUGINS ${BR_EXCLUDED_PLUGINS} plugins/classification/pp5.cpp)
16   -endif()