Commit f93466715a757bab06f9e6ecbf6f19d74fb740a1

Authored by Josh Klontz
1 parent aadf59cd

Revert "removed dlib"

This reverts commit aeb25d8b264ca18b84a01e4736a9c77568ba7cee.
openbr/plugins/classification/dlib.cpp 0 โ†’ 100644
  1 +#include <opencv2/imgproc/imgproc.hpp>
  2 +#include <dlib/image_processing/frontal_face_detector.h>
  3 +#include <dlib/image_processing.h>
  4 +#include <dlib/opencv.h>
  5 +
  6 +#include "openbr/plugins/openbr_internal.h"
  7 +
  8 +#include <QTemporaryFile>
  9 +
  10 +using namespace std;
  11 +using namespace dlib;
  12 +
  13 +namespace br
  14 +{
  15 +
  16 +/*!
  17 + * \ingroup transforms
  18 + * \brief Wrapper to dlib's landmarker.
  19 + * \author Scott Klum \cite sklum
  20 + */
  21 +class DLibShapeResourceMaker : public ResourceMaker<shape_predictor>
  22 +{
  23 +
  24 +private:
  25 + shape_predictor *make() const
  26 + {
  27 + shape_predictor *sp = new shape_predictor();
  28 + dlib::deserialize(qPrintable(Globals->sdkPath + "/share/openbr/models/dlib/shape_predictor_68_face_landmarks.dat")) >> *sp;
  29 + return sp;
  30 + }
  31 +};
  32 +
  33 +class DLandmarkerTransform : public UntrainableTransform
  34 +{
  35 + Q_OBJECT
  36 +
  37 +private:
  38 + Resource<shape_predictor> shapeResource;
  39 +
  40 + void init()
  41 + {
  42 + shapeResource.setResourceMaker(new DLibShapeResourceMaker());
  43 + shapeResource.release(shapeResource.acquire()); // Pre-load one instance of the model
  44 + }
  45 +
  46 + QPointF averagePoints(const QList<QPointF> &points, int rangeBegin, int rangeEnd) const
  47 + {
  48 + QPointF point;
  49 + for (int i=rangeBegin; i<rangeEnd; i++)
  50 + point += points[i];
  51 + point /= (rangeEnd-rangeBegin);
  52 + return point;
  53 + }
  54 +
  55 + void setFacePoints(Template &dst) const
  56 + {
  57 + const QList<QPointF> points = dst.file.points();
  58 + dst.file.set("RightEye", averagePoints(points, 36, 42));
  59 + dst.file.set("LeftEye" , averagePoints(points, 42, 48));
  60 + dst.file.set("Chin", points[8]);
  61 + }
  62 +
  63 + void project(const Template &src, Template &dst) const
  64 + {
  65 + dst = src;
  66 +
  67 + shape_predictor *const sp = shapeResource.acquire();
  68 +
  69 + cv::Mat cvImage = src.m();
  70 + if (cvImage.channels() == 3)
  71 + cv::cvtColor(cvImage, cvImage, CV_BGR2GRAY);
  72 +
  73 + cv_image<unsigned char> cimg(cvImage);
  74 + array2d<unsigned char> image;
  75 + assign_image(image,cimg);
  76 +
  77 + rectangle r;
  78 + if (src.file.rects().isEmpty()) { // If the image has no rects assume the whole image is a face
  79 + r = rectangle(0, 0, cvImage.cols, cvImage.rows);
  80 + } else { // Crop the image on the first rect
  81 + const QRectF rect = src.file.rects().first();
  82 + r = rectangle(rect.left(), rect.top(), rect.right(), rect.bottom());
  83 + }
  84 +
  85 + full_object_detection shape = (*sp)(image, r);
  86 + QList<QPointF> points;
  87 + for (size_t i=0; i<shape.num_parts(); i++)
  88 + points.append(QPointF(shape.part(i)(0), shape.part(i)(1)));
  89 + dst.file.setPoints(points);
  90 + setFacePoints(dst);
  91 +
  92 + shapeResource.release(sp);
  93 + }
  94 +};
  95 +
  96 +BR_REGISTER(Transform, DLandmarkerTransform)
  97 +
  98 +/*!
  99 + * \ingroup transforms
  100 + * \brief Wrapper to dlib's trainable object detector.
  101 + * \author Scott Klum \cite sklum
  102 + */
  103 +class DObjectDetectorTransform : public Transform
  104 +{
  105 + Q_OBJECT
  106 +
  107 + Q_PROPERTY(int winSize READ get_winSize WRITE set_winSize RESET reset_winSize STORED true)
  108 + Q_PROPERTY(float C READ get_C WRITE set_C RESET reset_C STORED true)
  109 + Q_PROPERTY(float epsilon READ get_epsilon WRITE set_epsilon RESET reset_epsilon STORED true)
  110 + BR_PROPERTY(int, winSize, 80)
  111 + BR_PROPERTY(float, C, 1)
  112 + BR_PROPERTY(float, epsilon, .01)
  113 +
  114 +private:
  115 + typedef scan_fhog_pyramid<pyramid_down<6> > image_scanner_type;
  116 + mutable object_detector<image_scanner_type> detector;
  117 + mutable QMutex mutex;
  118 +
  119 + void train(const TemplateList &data)
  120 + {
  121 + dlib::array<array2d<unsigned char> > samples;
  122 + std::vector<std::vector<rectangle> > boxes;
  123 +
  124 + foreach (const Template &t, data) {
  125 + if (!t.file.rects().isEmpty()) {
  126 + cv_image<unsigned char> cimg(t.m());
  127 +
  128 + array2d<unsigned char> image;
  129 + assign_image(image,cimg);
  130 +
  131 + samples.push_back(image);
  132 +
  133 + std::vector<rectangle> b;
  134 + foreach (const QRectF &r, t.file.rects())
  135 + b.push_back(rectangle(r.left(),r.top(),r.right(),r.bottom()));
  136 +
  137 + boxes.push_back(b);
  138 + }
  139 + }
  140 +
  141 + if (samples.size() == 0)
  142 + qFatal("Training data has no bounding boxes.");
  143 +
  144 + image_scanner_type scanner;
  145 +
  146 + scanner.set_detection_window_size(winSize, winSize);
  147 + structural_object_detection_trainer<image_scanner_type> trainer(scanner);
  148 + trainer.set_num_threads(max(1,QThread::idealThreadCount()));
  149 + trainer.set_c(C);
  150 + trainer.set_epsilon(epsilon);
  151 +
  152 + if (Globals->verbose)
  153 + trainer.be_verbose();
  154 +
  155 + detector = trainer.train(samples, boxes);
  156 + }
  157 +
  158 + void project(const Template &src, Template &dst) const
  159 + {
  160 + dst = src;
  161 + cv_image<unsigned char> cimg(src.m());
  162 + array2d<unsigned char> image;
  163 + assign_image(image,cimg);
  164 +
  165 + QMutexLocker locker(&mutex);
  166 + std::vector<rectangle> dets = detector(image);
  167 + locker.unlock();
  168 +
  169 + for (size_t i=0; i<dets.size(); i++)
  170 + dst.file.appendRect(QRectF(QPointF(dets[i].left(),dets[i].top()),QPointF(dets[i].right(),dets[i].bottom())));
  171 + }
  172 +
  173 + void store(QDataStream &stream) const
  174 + {
  175 + // Create local file
  176 + QTemporaryFile tempFile;
  177 + tempFile.open();
  178 + tempFile.close();
  179 +
  180 + dlib::serialize(qPrintable(tempFile.fileName())) << detector;
  181 +
  182 + // Copy local file contents to stream
  183 + tempFile.open();
  184 + QByteArray data = tempFile.readAll();
  185 + tempFile.close();
  186 + stream << data;
  187 + }
  188 +
  189 + void load(QDataStream &stream)
  190 + {
  191 + // Copy local file contents from stream
  192 + QByteArray data;
  193 + stream >> data;
  194 +
  195 + // Create local file
  196 + QTemporaryFile tempFile(QDir::tempPath()+"/model");
  197 + tempFile.open();
  198 + tempFile.write(data);
  199 + tempFile.close();
  200 +
  201 + // Load MLP from local file
  202 + dlib::deserialize(qPrintable(tempFile.fileName())) >> detector;
  203 + }
  204 +};
  205 +
  206 +BR_REGISTER(Transform, DObjectDetectorTransform)
  207 +
  208 +} // namespace br
  209 +
  210 +#include "dlib.moc"
... ...
openbr/plugins/classification/dlib_source.cpp 0 โ†’ 100644
  1 +#define DLIB_NO_GUI_SUPPORT
  2 +#include <dlib/all/source.cpp>
... ...
openbr/plugins/cmake/dlib.cmake 0 โ†’ 100644
  1 +set(BR_WITH_DLIB OFF CACHE BOOL "Build with DLib")
  2 +
  3 +if(${BR_WITH_DLIB})
  4 + ExternalProject_Add(dlib
  5 + URL http://downloads.sourceforge.net/project/dclib/dlib/v18.16/dlib-18.16.tar.bz2
  6 + URL_MD5 e9e5449bc25370afce2d254327afac99
  7 + SOURCE_DIR "${PROJECT_SOURCE_DIR}/3rdparty/dlib-18.16"
  8 + CONFIGURE_COMMAND ""
  9 + BUILD_COMMAND ""
  10 + INSTALL_COMMAND "")
  11 + include_directories("${PROJECT_SOURCE_DIR}/3rdparty/dlib-18.16")
  12 +else()
  13 + set(BR_EXCLUDED_PLUGINS ${BR_EXCLUDED_PLUGINS} plugins/classification/dlib.cpp plugins/classification/dlib_source.cpp)
  14 +endif()
... ...