Commit 141314842cb64d2b497fb122e80459a55d8ab986
Merge pull request #55 from biometrics/pp5_rework
Changes to PP5Enroll, proposed fix to #54
Showing
1 changed file
with
59 additions
and
33 deletions
openbr/plugins/pp5.cpp
| @@ -73,7 +73,7 @@ struct PP5Context | @@ -73,7 +73,7 @@ struct PP5Context | ||
| 73 | 73 | ||
| 74 | default_settings.detection.adaptive_max_size = 1.f; | 74 | default_settings.detection.adaptive_max_size = 1.f; |
| 75 | default_settings.detection.adaptive_min_size = 0.01f; | 75 | default_settings.detection.adaptive_min_size = 0.01f; |
| 76 | - default_settings.detection.detect_best_face_only = true; | 76 | + default_settings.detection.detect_best_face_only = !Globals->enrollAll; |
| 77 | default_settings.detection.enable = 1; | 77 | default_settings.detection.enable = 1; |
| 78 | default_settings.detection.min_size = 4; | 78 | default_settings.detection.min_size = 4; |
| 79 | default_settings.detection.use_serial_face_detection = 1; | 79 | default_settings.detection.use_serial_face_detection = 1; |
| @@ -220,47 +220,73 @@ class PP5EnrollTransform : public UntrainableTransform | @@ -220,47 +220,73 @@ class PP5EnrollTransform : public UntrainableTransform | ||
| 220 | BR_PROPERTY(bool, detectOnly, false) | 220 | BR_PROPERTY(bool, detectOnly, false) |
| 221 | Resource<PP5Context> contexts; | 221 | Resource<PP5Context> contexts; |
| 222 | 222 | ||
| 223 | - void project(const Template &src, Template &dst) const | 223 | + void project(const Template & src, Template & dst) const |
| 224 | { | 224 | { |
| 225 | + if (Globals->enrollAll) | ||
| 226 | + qFatal("single template project doesn't support enrollAll"); | ||
| 227 | + | ||
| 228 | + TemplateList srcList; | ||
| 229 | + srcList.append(src); | ||
| 230 | + TemplateList dstList; | ||
| 231 | + project(srcList, dstList); | ||
| 232 | + dst = dstList.first(); | ||
| 233 | + } | ||
| 234 | + | ||
| 235 | + void project(const TemplateList &srcList, TemplateList & dstList) const | ||
| 236 | + { | ||
| 237 | + // Nothing to do here | ||
| 238 | + if (srcList.empty()) | ||
| 239 | + return; | ||
| 240 | + | ||
| 225 | PP5Context *context = contexts.acquire(); | 241 | PP5Context *context = contexts.acquire(); |
| 226 | 242 | ||
| 227 | - ppr_raw_image_type raw_image; | ||
| 228 | - PP5Context::createRawImage(src, raw_image); | ||
| 229 | - ppr_image_type image; | ||
| 230 | - TRY(ppr_create_image(raw_image, &image)) | ||
| 231 | - ppr_face_list_type face_list; | ||
| 232 | - TRY(ppr_detect_faces(context->context, image, &face_list)) | ||
| 233 | - | ||
| 234 | - for (int i=0; i<face_list.length; i++) { | ||
| 235 | - ppr_face_type face = face_list.faces[i]; | ||
| 236 | - int extractable; | ||
| 237 | - TRY(ppr_is_template_extractable(context->context, face, &extractable)) | ||
| 238 | - if (!extractable && !detectOnly) continue; | ||
| 239 | - | ||
| 240 | - cv::Mat m; | ||
| 241 | - if (detectOnly) { | ||
| 242 | - m = src; | ||
| 243 | - } else { | ||
| 244 | - TRY(ppr_extract_face_template(context->context, image, &face)) | ||
| 245 | - context->createMat(face, m); | ||
| 246 | - } | 243 | + foreach(const Template & src, srcList) { |
| 244 | + ppr_raw_image_type raw_image; | ||
| 245 | + PP5Context::createRawImage(src, raw_image); | ||
| 246 | + ppr_image_type image; | ||
| 247 | + TRY(ppr_create_image(raw_image, &image)) | ||
| 248 | + ppr_face_list_type face_list; | ||
| 249 | + TRY(ppr_detect_faces(context->context, image, &face_list)) | ||
| 250 | + | ||
| 251 | + for (int i=0; i<face_list.length; i++) { | ||
| 252 | + ppr_face_type face = face_list.faces[i]; | ||
| 253 | + int extractable; | ||
| 254 | + TRY(ppr_is_template_extractable(context->context, face, &extractable)) | ||
| 255 | + if (!extractable && !detectOnly) continue; | ||
| 256 | + | ||
| 257 | + cv::Mat m; | ||
| 258 | + if (detectOnly) { | ||
| 259 | + m = src; | ||
| 260 | + } else { | ||
| 261 | + TRY(ppr_extract_face_template(context->context, image, &face)) | ||
| 262 | + context->createMat(face, m); | ||
| 263 | + } | ||
| 264 | + Template dst; | ||
| 265 | + dst.file = src.file; | ||
| 266 | + | ||
| 267 | + dst.file.append(PP5Context::toMetadata(face)); | ||
| 268 | + dst += m; | ||
| 269 | + dstList.append(dst); | ||
| 247 | 270 | ||
| 248 | - dst.file.append(PP5Context::toMetadata(face)); | ||
| 249 | - dst += m; | 271 | + // Found a face, nothing else to do (if we aren't trying to find multiple faces). |
| 272 | + if (!Globals->enrollAll) | ||
| 273 | + break; | ||
| 274 | + } | ||
| 250 | 275 | ||
| 251 | - if (!src.file.getBool("enrollAll")) break; | 276 | + ppr_free_face_list(face_list); |
| 277 | + ppr_free_image(image); | ||
| 278 | + ppr_raw_image_free(raw_image); | ||
| 252 | } | 279 | } |
| 253 | 280 | ||
| 254 | - ppr_free_face_list(face_list); | ||
| 255 | - ppr_free_image(image); | ||
| 256 | - ppr_raw_image_free(raw_image); | 281 | + // No faces were detected, output something with FTE set. |
| 282 | + if (dstList.empty()) { | ||
| 283 | + dstList.append(srcList.first()); | ||
| 284 | + dstList.first().file.set("FTE",true); | ||
| 285 | + if (!detectOnly) | ||
| 286 | + dstList.first().m() = cv::Mat(); | ||
| 287 | + } | ||
| 257 | 288 | ||
| 258 | contexts.release(context); | 289 | contexts.release(context); |
| 259 | - | ||
| 260 | - if (!src.file.getBool("enrollAll") && dst.isEmpty()) { | ||
| 261 | - if (detectOnly) dst += src; | ||
| 262 | - else dst += cv::Mat(); | ||
| 263 | - } | ||
| 264 | } | 290 | } |
| 265 | }; | 291 | }; |
| 266 | 292 |