diff --git a/openbr/plugins/classification/dlib.cpp b/openbr/plugins/classification/dlib.cpp new file mode 100644 index 0000000..6dbbb88 --- /dev/null +++ b/openbr/plugins/classification/dlib.cpp @@ -0,0 +1,210 @@ +#include +#include +#include +#include + +#include "openbr/plugins/openbr_internal.h" + +#include + +using namespace std; +using namespace dlib; + +namespace br +{ + +/*! + * \ingroup transforms + * \brief Wrapper to dlib's landmarker. + * \author Scott Klum \cite sklum + */ +class DLibShapeResourceMaker : public ResourceMaker +{ + +private: + shape_predictor *make() const + { + shape_predictor *sp = new shape_predictor(); + dlib::deserialize(qPrintable(Globals->sdkPath + "/share/openbr/models/dlib/shape_predictor_68_face_landmarks.dat")) >> *sp; + return sp; + } +}; + +class DLandmarkerTransform : public UntrainableTransform +{ + Q_OBJECT + +private: + Resource shapeResource; + + void init() + { + shapeResource.setResourceMaker(new DLibShapeResourceMaker()); + shapeResource.release(shapeResource.acquire()); // Pre-load one instance of the model + } + + QPointF averagePoints(const QList &points, int rangeBegin, int rangeEnd) const + { + QPointF point; + for (int i=rangeBegin; i points = dst.file.points(); + dst.file.set("RightEye", averagePoints(points, 36, 42)); + dst.file.set("LeftEye" , averagePoints(points, 42, 48)); + dst.file.set("Chin", points[8]); + } + + void project(const Template &src, Template &dst) const + { + dst = src; + + shape_predictor *const sp = shapeResource.acquire(); + + cv::Mat cvImage = src.m(); + if (cvImage.channels() == 3) + cv::cvtColor(cvImage, cvImage, CV_BGR2GRAY); + + cv_image cimg(cvImage); + array2d image; + assign_image(image,cimg); + + rectangle r; + if (src.file.rects().isEmpty()) { // If the image has no rects assume the whole image is a face + r = rectangle(0, 0, cvImage.cols, cvImage.rows); + } else { // Crop the image on the first rect + const QRectF rect = src.file.rects().first(); + r = rectangle(rect.left(), rect.top(), rect.right(), rect.bottom()); + } + + full_object_detection shape = (*sp)(image, r); + QList points; + for (size_t i=0; i > image_scanner_type; + mutable object_detector detector; + mutable QMutex mutex; + + void train(const TemplateList &data) + { + dlib::array > samples; + std::vector > boxes; + + foreach (const Template &t, data) { + if (!t.file.rects().isEmpty()) { + cv_image cimg(t.m()); + + array2d image; + assign_image(image,cimg); + + samples.push_back(image); + + std::vector b; + foreach (const QRectF &r, t.file.rects()) + b.push_back(rectangle(r.left(),r.top(),r.right(),r.bottom())); + + boxes.push_back(b); + } + } + + if (samples.size() == 0) + qFatal("Training data has no bounding boxes."); + + image_scanner_type scanner; + + scanner.set_detection_window_size(winSize, winSize); + structural_object_detection_trainer trainer(scanner); + trainer.set_num_threads(max(1,QThread::idealThreadCount())); + trainer.set_c(C); + trainer.set_epsilon(epsilon); + + if (Globals->verbose) + trainer.be_verbose(); + + detector = trainer.train(samples, boxes); + } + + void project(const Template &src, Template &dst) const + { + dst = src; + cv_image cimg(src.m()); + array2d image; + assign_image(image,cimg); + + QMutexLocker locker(&mutex); + std::vector dets = detector(image); + locker.unlock(); + + for (size_t i=0; i> data; + + // Create local file + QTemporaryFile tempFile(QDir::tempPath()+"/model"); + tempFile.open(); + tempFile.write(data); + tempFile.close(); + + // Load MLP from local file + dlib::deserialize(qPrintable(tempFile.fileName())) >> detector; + } +}; + +BR_REGISTER(Transform, DObjectDetectorTransform) + +} // namespace br + +#include "dlib.moc" diff --git a/openbr/plugins/classification/dlib_source.cpp b/openbr/plugins/classification/dlib_source.cpp new file mode 100644 index 0000000..1b66308 --- /dev/null +++ b/openbr/plugins/classification/dlib_source.cpp @@ -0,0 +1,2 @@ +#define DLIB_NO_GUI_SUPPORT +#include diff --git a/openbr/plugins/cmake/dlib.cmake b/openbr/plugins/cmake/dlib.cmake new file mode 100644 index 0000000..f2735aa --- /dev/null +++ b/openbr/plugins/cmake/dlib.cmake @@ -0,0 +1,14 @@ +set(BR_WITH_DLIB OFF CACHE BOOL "Build with DLib") + +if(${BR_WITH_DLIB}) + ExternalProject_Add(dlib + URL http://downloads.sourceforge.net/project/dclib/dlib/v18.16/dlib-18.16.tar.bz2 + URL_MD5 e9e5449bc25370afce2d254327afac99 + SOURCE_DIR "${PROJECT_SOURCE_DIR}/3rdparty/dlib-18.16" + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "") + include_directories("${PROJECT_SOURCE_DIR}/3rdparty/dlib-18.16") +else() + set(BR_EXCLUDED_PLUGINS ${BR_EXCLUDED_PLUGINS} plugins/classification/dlib.cpp plugins/classification/dlib_source.cpp) +endif()