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()