diff --git a/CHANGELOG.md b/CHANGELOG.md index 828766e..5259d0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ 0.3.0 - ??/??/?? ================ * YouTubeFacesDBTransform implements Dr. Wolf's experimental protocol +* NEC3 refactored 0.2.0 - 2/23/13 =============== diff --git a/sdk/plugins/nec3.cpp b/sdk/plugins/nec3.cpp index 1c01f1b..c134016 100644 --- a/sdk/plugins/nec3.cpp +++ b/sdk/plugins/nec3.cpp @@ -1,14 +1,19 @@ +#ifdef WIN32 +#include +#endif + #include -#include -#include "common/resource.h" +#include +#include "core/resource.h" -using namespace mm; +using namespace br; /*! * \ingroup initializers * \brief Initialize NEC3 * \author Josh Klontz \cite jklontz + * \author Scott Klum \cite sklum * \warning Needs a maintainer */ class NEC3Initializer : public Initializer @@ -19,7 +24,7 @@ class NEC3Initializer : public Initializer { int result = NeoFacePro::Initialize(); if (result != NFP_SUCCESS) qWarning("NEC3 Initialize error [%d]", result); - Globals->Abbreviations.insert("NEC3", "Open+NEC3Enroll:NEC3Compare"); + Globals->abbreviations.insert("NEC3", "Open!NEC3Enroll:NEC3Compare"); } void finalize() const @@ -29,40 +34,27 @@ class NEC3Initializer : public Initializer } }; -MM_REGISTER(Initializer, NEC3Initializer) +BR_REGISTER(Initializer, NEC3Initializer) /*! - * \brief Helper class - * \author Josh Klontz \cite jklontz - * \warning Needs a maintainer + * \brief NEC3 Context + * \author Scott Klum \cite sklum */ -class CFaceInfoResourceMaker : public ResourceMaker -{ - NeoFacePro::CFaceInfo *make() const - { - NeoFacePro::CFaceInfo *faceInfo = new NeoFacePro::CFaceInfo(); - faceInfo->SetParamAlgorithm(NFP_ALGORITHM003); - faceInfo->SetParamEyesRoll(15); - faceInfo->SetParamEyesMaxWidth(1000); - faceInfo->SetParamEyesMinWidth(30); - faceInfo->SetParamMaxFace(5); - faceInfo->SetParamReliability(0); - return faceInfo; - } -}; -/*! - * \brief Helper class - * \author Josh Klontz \cite jklontz - * \warning Needs a maintainer - */ -class CFaceFeatureResourceMaker : public ResourceMaker +struct NEC3Context { - NeoFacePro::CFaceFeature *make() const - { - NeoFacePro::CFaceFeature *faceFeature = new NeoFacePro::CFaceFeature(); - faceFeature->SetParamFeatureType(NFP_FEATURE_S14); - return faceFeature; + NeoFacePro::CFaceInfo faceInfo; + NeoFacePro::CFaceFeature faceFeature; + + NEC3Context() { + faceInfo.SetParamAlgorithm(NFP_ALGORITHM003); + faceInfo.SetParamEyesRoll(15); + faceInfo.SetParamEyesMaxWidth(1000); + faceInfo.SetParamEyesMinWidth(30); + faceInfo.SetParamMaxFace(1); + faceInfo.SetParamReliability(0); + + faceFeature.SetParamFeatureType(NFP_FEATURE_S14); } }; @@ -70,30 +62,22 @@ class CFaceFeatureResourceMaker : public ResourceMaker * \ingroup transforms * \brief Enroll a face image in NEC NeoFace 3 * \author Josh Klontz \cite jklontz + * \author Scott Klum \cite sklum * \warning Needs a maintainer */ -class NEC3Enroll : public UntrainableFeature +class NEC3Enroll : public UntrainableTransform { Q_OBJECT - Q_PROPERTY(bool detectOnly READ get_detectOnly WRITE set_detectOnly) - MM_MEMBER(bool, detectOnly) + Q_PROPERTY(bool detectOnly READ get_detectOnly WRITE set_detectOnly RESET reset_detectOnly STORED false) + BR_PROPERTY(bool, detectOnly, false) - Resource faceInfoResource; - Resource faceFeatureResource; - QSharedPointer flip; - - QString parameters() const - { - return "bool detectOnly = 0"; - } + Resource contexts; + QSharedPointer flip; void init() { - faceInfoResource.setResourceMaker(new CFaceInfoResourceMaker()); - faceFeatureResource.setResourceMaker(new CFaceFeatureResourceMaker()); - faceInfoResource.setMaxResources(1); // Only works in serial - faceFeatureResource.setMaxResources(1); // Only works in serial - flip = QSharedPointer(Feature::make("Flip(X)")); + contexts.setMaxResources(1); + flip = QSharedPointer(Transform::make("Flip(X)")); } void project(const Template &src, Template &dst) const @@ -112,29 +96,29 @@ class NEC3Enroll : public UntrainableFeature binfo.bmiHeader.biHeight = input.rows; binfo.bmiHeader.biBitCount = 24; - NeoFacePro::CFaceInfo *faceInfo = faceInfoResource.acquire(); - int result = faceInfo->FindFace(binfo, input.data); - faceInfo->LocateEyes(); + NEC3Context *context = contexts.acquire(); + int result = context->faceInfo.FindFace(binfo, input.data); + context->faceInfo.LocateEyes(); + if (result == NFP_CANNOT_FIND_FACE) { if (Globals->verbose) qDebug("NEC3Enroll face not found for file %s", qPrintable(src.file.flat())); } else if (result != NFP_SUCCESS) { qWarning("NEC3Enroll FindFace error %d for file %s", result, qPrintable(src.file.flat())); } - NeoFacePro::CFaceFeature *faceFeature = faceFeatureResource.acquire(); - QList landmarks; - for (int i=0; iGetFaceMax(); i++) { - if (faceInfo->SetFaceIndex(i) != NFP_SUCCESS) + QList landmarks; + for (int i=0; ifaceInfo.GetFaceMax(); i++) { + if (context->faceInfo.SetFaceIndex(i) != NFP_SUCCESS) continue; - POINT right = faceInfo->GetRightEye(); - POINT left = faceInfo->GetLeftEye(); - landmarks.append(cv::Point2f(right.x, right.y)); - landmarks.append(cv::Point2f(left.x, left.y)); + POINT right = context->faceInfo.GetRightEye(); + POINT left = context->faceInfo.GetLeftEye(); + landmarks.append(QPointF(right.x, right.y)); + landmarks.append(QPointF(left.x, left.y)); if (detectOnly) { dst += src.m(); } else { - result = faceFeature->SetFeature(faceInfo); + result = context->faceFeature.SetFeature(&context->faceInfo); if (result != NFP_SUCCESS) { qWarning("NEC3Enroll SetFeature error %d for file %s", result, qPrintable(src.file.flat())); continue; @@ -142,7 +126,7 @@ class NEC3Enroll : public UntrainableFeature void *data; long size; - result = faceFeature->Serialize(&data, &size); + result = context->faceFeature.Serialize(&data, &size); if (result != NFP_SUCCESS) { qWarning("NEC3Enroll Serialize error %d for file %s", result, qPrintable(src.file.flat())); continue; @@ -156,22 +140,22 @@ class NEC3Enroll : public UntrainableFeature } dst.file.appendLandmarks(landmarks); - faceInfoResource.release(faceInfo); - faceFeatureResource.release(faceFeature); + contexts.release(context); - if (src.file.getBool("ForceEnrollment") && dst.isEmpty()) dst += cv::Mat(); + if (!src.file.getBool("enrollAll") && dst.isEmpty()) dst += cv::Mat(); } }; -MM_REGISTER(Feature, NEC3Enroll) +BR_REGISTER(Transform, NEC3Enroll) /*! * \ingroup distances * \brief Compare faces with NEC NeoFace 3 SDK * \author Josh Klontz \cite jklontz + * \author Scott Klum \cite sklum * \warning Needs a maintainer */ -class NEC3Compare : public BasicComparer +class NEC3Compare : public Distance { Q_OBJECT @@ -190,6 +174,6 @@ class NEC3Compare : public BasicComparer } }; -MM_REGISTER(Comparer, NEC3Compare) +BR_REGISTER(Distance, NEC3Compare) #include "nec3.moc" diff --git a/share/openbr/cmake/FindNEC3.cmake b/share/openbr/cmake/FindNEC3.cmake new file mode 100644 index 0000000..118a202 --- /dev/null +++ b/share/openbr/cmake/FindNEC3.cmake @@ -0,0 +1,6 @@ +find_path(NEC3_DIR Include/NeoFacePro.h ${CMAKE_SOURCE_DIR}/3rdparty/*) + +include_directories(${NEC3_DIR}/Include) +link_directories(${NEC3_DIR}/Lib) + +set(NEC3_LIBS NeoFacePro)