Commit 8efb2824c2ac475dfe98f73ddafa78825c313c88
1 parent
274b7ff1
updated CT8 to use new template metadata API, cleaned up some of the logic
Showing
1 changed file
with
37 additions
and
61 deletions
sdk/plugins/ct8.cpp
| ... | ... | @@ -236,7 +236,6 @@ struct CT8Context |
| 236 | 236 | FRsdk::SampleSet sampleSet; |
| 237 | 237 | sampleSet.push_back(sample); |
| 238 | 238 | |
| 239 | - | |
| 240 | 239 | FRsdk::EnrolOpenCVFeedback * feedback_body = new FRsdk::EnrolOpenCVFeedback(m); |
| 241 | 240 | FRsdk::CountedPtr<FRsdk::Enrollment::FeedbackBody> feedback_ptr(feedback_body); |
| 242 | 241 | |
| ... | ... | @@ -300,14 +299,14 @@ protected: |
| 300 | 299 | * \author Josh Klontz \cite jklontz |
| 301 | 300 | * \author Charles Otto \cite caotto |
| 302 | 301 | */ |
| 303 | -struct CT8Detect : public UntrainableTransform | |
| 304 | - , public CT8Context | |
| 302 | +class CT8DetectTransform : public UntrainableTransform | |
| 303 | + , public CT8Context | |
| 305 | 304 | { |
| 306 | -public: | |
| 307 | 305 | Q_OBJECT |
| 308 | - | |
| 309 | 306 | Q_PROPERTY(float minRelEyeDistance READ get_minRelEyeDistance WRITE set_minRelEyeDistance RESET reset_minRelEyeDistance STORED false) |
| 310 | 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) | |
| 311 | 310 | |
| 312 | 311 | // Perform face, then eye detection using the facevacs SDK |
| 313 | 312 | void project(const Template &src, Template &dst) const |
| ... | ... | @@ -316,57 +315,39 @@ public: |
| 316 | 315 | // Build an FRsdk image from the input openCV mat |
| 317 | 316 | FRsdk::CountedPtr<FRsdk::ImageBody> i(new FRsdk::OpenCVImageBody(src)); |
| 318 | 317 | FRsdk::Image img(i); |
| 319 | - | |
| 320 | 318 | FRsdk::Face::LocationSet faceLocations = faceFinder->find(img, minRelEyeDistance, maxRelEyeDistance); |
| 321 | - | |
| 322 | - // If the face finder doesn't find anything mark the output as a failure | |
| 323 | - if (faceLocations.empty() ) { | |
| 324 | - dst.file.setBool("FTE"); | |
| 325 | - return; | |
| 326 | - } | |
| 327 | - | |
| 328 | - QList<QRectF> ROIs; | |
| 329 | - QList<QPointF> landmarks; | |
| 330 | - FRsdk::Face::LocationSet::const_iterator faceLocationSetIterator = faceLocations.begin(); | |
| 331 | - bool any_eyes = false; | |
| 332 | 319 | |
| 333 | 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(); | |
| 334 | 324 | while (faceLocationSetIterator != faceLocations.end()) { |
| 335 | 325 | FRsdk::Face::Location faceLocation = *faceLocationSetIterator; faceLocationSetIterator++; |
| 336 | 326 | FRsdk::Eyes::LocationSet currentEyesLocations = eyesFinder->find(img, faceLocation); |
| 337 | 327 | |
| 338 | 328 | if (currentEyesLocations.size() > 0) { |
| 339 | - any_eyes = true; | |
| 340 | - ROIs.append(QRectF(faceLocation.pos.x(), faceLocation.pos.y(), faceLocation.width, faceLocation.width)); | |
| 341 | - landmarks.append(QPointF(currentEyesLocations.front().first.x(), currentEyesLocations.front().first.y())); | |
| 342 | - landmarks.append(QPointF(currentEyesLocations.front().second.x(), currentEyesLocations.front().second.y())); | |
| 343 | - | |
| 344 | - dst += src; | |
| 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; | |
| 345 | 334 | } |
| 346 | - | |
| 347 | - if (any_eyes && !Globals->enrollAll && !dst.isEmpty()) break; | |
| 348 | 335 | } |
| 349 | 336 | |
| 350 | 337 | // If eye detection failed, mark the output as a failure |
| 351 | - if (!any_eyes) { | |
| 352 | - dst.file.setBool("FTE"); | |
| 353 | - return; | |
| 338 | + if (dst.isEmpty()) { | |
| 339 | + dst.file.set("FTE", true); | |
| 340 | + if (!Globals->enrollAll) dst += Mat(); | |
| 354 | 341 | } |
| 355 | - | |
| 356 | - dst.file.setROIs(ROIs); | |
| 357 | - dst.file.setLandmarks(landmarks); | |
| 342 | + dst.file.appendRects(rects); | |
| 343 | + dst.file.appendPoints(points); | |
| 358 | 344 | } catch (std::exception &e) { |
| 359 | 345 | qFatal("CT8Enroll Exception: %s", e.what()); |
| 360 | 346 | } |
| 361 | - | |
| 362 | - if (!Globals->enrollAll && dst.isEmpty()) dst += Mat(); | |
| 363 | - } | |
| 364 | -private: | |
| 365 | - BR_PROPERTY(float, minRelEyeDistance, 0.01f) | |
| 366 | - BR_PROPERTY(float, maxRelEyeDistance, 0.4f) | |
| 347 | + } | |
| 367 | 348 | }; |
| 368 | 349 | |
| 369 | -BR_REGISTER(Transform, CT8Detect) | |
| 350 | +BR_REGISTER(Transform, CT8DetectTransform) | |
| 370 | 351 | |
| 371 | 352 | /*! |
| 372 | 353 | * \ingroup transforms |
| ... | ... | @@ -374,10 +355,11 @@ BR_REGISTER(Transform, CT8Detect) |
| 374 | 355 | * \author Josh Klontz \cite jklontz |
| 375 | 356 | * \author Charles Otto \cite caotto |
| 376 | 357 | */ |
| 377 | -struct CT8Enroll : public UntrainableTransform | |
| 378 | - , public CT8Context | |
| 358 | +class CT8EnrollTransform : public UntrainableTransform | |
| 359 | + , public CT8Context | |
| 379 | 360 | { |
| 380 | 361 | Q_OBJECT |
| 362 | + | |
| 381 | 363 | // enroll an image using the facevacs sdk. Generates a facevacs "fir" which |
| 382 | 364 | // is their face representation. |
| 383 | 365 | void project(const Template &src, Template &dst) const |
| ... | ... | @@ -387,37 +369,31 @@ struct CT8Enroll : public UntrainableTransform |
| 387 | 369 | FRsdk::Image img(i); |
| 388 | 370 | |
| 389 | 371 | // If we already have eye locations, use them |
| 390 | - QList<QPointF> landmarks = src.file.landmarks(); | |
| 391 | - bool enroll_succeeded = false; | |
| 392 | - if (landmarks.size() == 2) { | |
| 393 | - enroll_succeeded = enroll(img, FRsdk::Eyes::Location(toPosition(landmarks[0]), toPosition(landmarks[1])), &(dst.m())); | |
| 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())); | |
| 394 | 376 | |
| 395 | 377 | // Transfer previously detectd eye and face locations to the output dst. |
| 396 | - dst.file.insert("CT8_First_Eye_X", landmarks[0].x()); | |
| 397 | - dst.file.insert("CT8_First_Eye_Y", landmarks[0].y()); | |
| 398 | - dst.file.insert("CT8_Second_Eye_X", landmarks[1].x()); | |
| 399 | - dst.file.insert("CT8_Second_Eye_Y", landmarks[1].y()); | |
| 400 | - | |
| 401 | - QList<QRectF> ROIs = src.file.ROIs(); | |
| 402 | - if (ROIs.size() == 1) { | |
| 403 | - dst.file.insert("CT8_Face_X", ROIs.first().x()); | |
| 404 | - dst.file.insert("CT8_Face_Y", ROIs.first().y()); | |
| 405 | - dst.file.insert("CT8_Face_Width", ROIs.first().width()); | |
| 406 | - dst.file.insert("CT8_Face_Height", ROIs.first().height()); | |
| 407 | - } | |
| 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()); | |
| 408 | 384 | } else { |
| 409 | 385 | // If we don't have eye locations already, calling enroll here |
| 410 | 386 | // will cause facevacs to perform detection using default |
| 411 | 387 | // parameters (and we will not receive the detected locations |
| 412 | 388 | // as output). |
| 413 | - enroll_succeeded = enroll(img, &(dst.m())); | |
| 389 | + enrollSucceeded = enroll(img, &(dst.m())); | |
| 414 | 390 | } |
| 391 | + | |
| 415 | 392 | // If enrollment failed, mark this image as a failure. This will |
| 416 | 393 | // typically only happen if we aren't using pre-detected eye |
| 417 | 394 | // locations |
| 418 | - if (!enroll_succeeded) | |
| 419 | - { | |
| 420 | - dst.file.setBool("FTE"); | |
| 395 | + if (!enrollSucceeded) { | |
| 396 | + dst.file.set("FTE", true); | |
| 421 | 397 | dst.m() = Mat(); |
| 422 | 398 | } |
| 423 | 399 | } catch (std::exception &e) { |
| ... | ... | @@ -426,7 +402,7 @@ struct CT8Enroll : public UntrainableTransform |
| 426 | 402 | } |
| 427 | 403 | }; |
| 428 | 404 | |
| 429 | -BR_REGISTER(Transform, CT8Enroll) | |
| 405 | +BR_REGISTER(Transform, CT8EnrollTransform) | |
| 430 | 406 | |
| 431 | 407 | /*! |
| 432 | 408 | * \ingroup distances | ... | ... |