Commit cfe862fc73cfe3dc761b01b402bec8295bede9c2

Authored by Scott Klum
1 parent e8c73a7d

No idea how these files were deleted

3rdparty/stasm4.0.0/stasm/src/facedet.cpp 0 → 100755
  1 +// facedet.cpp: find faces in images (frontal model version)
  2 +//
  3 +// Copyright (C) 2005-2013, Stephen Milborrow
  4 +
  5 +#include "facedet.h"
  6 +#include "stasm_lib.h"
  7 +
  8 +namespace stasm
  9 +{
  10 +typedef vector<DetPar> vec_DetPar;
  11 +
  12 +//static cv::CascadeClassifier facedet_g; // the face detector
  13 +
  14 +static double BORDER_FRAC = 0.1; // fraction of image width or height
  15 + // use 0.0 for no border
  16 +
  17 +//-----------------------------------------------------------------------------
  18 +
  19 +void FaceDet::OpenFaceDetector_( // called by stasm_init, init face det from XML file
  20 + const char* datadir, // in: directory of face detector files
  21 + void*) // in: unused (func signature compatibility)
  22 +{
  23 + (void) datadir;
  24 + //OpenDetector(facedet_g, "haarcascade_frontalface_alt2.xml", datadir);
  25 +}
  26 +
  27 +// If a face is near the edge of the image, the OpenCV detectors tend to
  28 +// return a too-small face rectangle. By adding a border around the edge
  29 +// of the image we mitigate this problem.
  30 +
  31 +static Image EnborderImg( // return the image with a border
  32 + int& leftborder, // out: border size in pixels
  33 + int& topborder, // out: border size in pixels
  34 + const Image& img) // io
  35 +{
  36 + Image bordered_img(img);
  37 + leftborder = cvRound(BORDER_FRAC * bordered_img.cols);
  38 + topborder = cvRound(BORDER_FRAC * bordered_img.rows);
  39 + copyMakeBorder(bordered_img, bordered_img,
  40 + topborder, topborder, leftborder, leftborder,
  41 + cv::BORDER_REPLICATE);
  42 + return bordered_img;
  43 +}
  44 +
  45 +void DetectFaces( // all face rects into detpars
  46 + vec_DetPar& detpars, // out
  47 + const Image& img, // in
  48 + int minwidth,
  49 + cv::CascadeClassifier cascade) // in: as percent of img width
  50 +{
  51 + int leftborder = 0, topborder = 0; // border size in pixels
  52 + Image bordered_img(BORDER_FRAC == 0?
  53 + img: EnborderImg(leftborder, topborder, img));
  54 +
  55 + // Detection results are very slightly better with equalization
  56 + // (tested on the MUCT images, which are not pre-equalized), and
  57 + // it's quick enough to equalize (roughly 10ms on a 1.6 GHz laptop).
  58 +
  59 + Image equalized_img; cv::equalizeHist(bordered_img, equalized_img);
  60 +
  61 + CV_Assert(minwidth >= 1 && minwidth <= 100);
  62 +
  63 + int minpix = MAX(100, cvRound(img.cols * minwidth / 100.));
  64 +
  65 + // the params below are accurate but slow
  66 + static const double SCALE_FACTOR = 1.1;
  67 + static const int MIN_NEIGHBORS = 3;
  68 + static const int DETECTOR_FLAGS = 0;
  69 +
  70 + vec_Rect facerects = // all face rects in image
  71 + Detect(equalized_img, &cascade, NULL,
  72 + SCALE_FACTOR, MIN_NEIGHBORS, DETECTOR_FLAGS, minpix);
  73 +
  74 + // copy face rects into the detpars vector
  75 +
  76 + detpars.resize(NSIZE(facerects));
  77 + for (int i = 0; i < NSIZE(facerects); i++)
  78 + {
  79 + Rect* facerect = &facerects[i];
  80 + DetPar detpar; // detpar constructor sets all fields INVALID
  81 + // detpar.x and detpar.y is the center of the face rectangle
  82 + detpar.x = facerect->x + facerect->width / 2.;
  83 + detpar.y = facerect->y + facerect->height / 2.;
  84 + detpar.x -= leftborder; // discount the border we added earlier
  85 + detpar.y -= topborder;
  86 + detpar.width = double(facerect->width);
  87 + detpar.height = double(facerect->height);
  88 + detpar.yaw = 0; // assume face has no yaw in this version of Stasm
  89 + detpar.eyaw = EYAW00;
  90 + detpars[i] = detpar;
  91 + }
  92 +}
  93 +
  94 +// order by increasing distance from left marg, and dist from top marg within that
  95 +
  96 +static bool IncreasingLeftMargin( // compare predicate for std::sort
  97 + const DetPar& detpar1, // in
  98 + const DetPar& detpar2) // in
  99 +{
  100 + return 1e5 * detpar2.x + detpar2.y >
  101 + 1e5 * detpar1.x + detpar1.y;
  102 +}
  103 +
  104 +// order by decreasing width, and dist from the left margin within that
  105 +
  106 +static bool DecreasingWidth( // compare predicate for std::sort
  107 + const DetPar& detpar1, // in
  108 + const DetPar& detpar2) // in
  109 +{
  110 + return 1e5 * detpar2.width - detpar2.x <
  111 + 1e5 * detpar1.width - detpar1.x;
  112 +
  113 +}
  114 +
  115 +// Discard too big or small faces (this helps reduce the number of false positives)
  116 +
  117 +static void DiscardMissizedFaces(
  118 + vec_DetPar& detpars) // io
  119 +{
  120 + // constants (TODO These have not yet been rigorously empirically adjusted.)
  121 + const double MIN_WIDTH = 1.33; // as fraction of median width
  122 + const double MAX_WIDTH = 1.33; // as fraction of median width
  123 +
  124 + if (NSIZE(detpars) >= 3) // need at least 3 faces
  125 + {
  126 + // sort the faces on their width (smallest first) so can get median width
  127 + sort(detpars.begin(), detpars.end(), DecreasingWidth);
  128 + const int median = cvRound(detpars[NSIZE(detpars) / 2].width);
  129 + const int minallowed = cvRound(median / MIN_WIDTH);
  130 + const int maxallowed = cvRound(MAX_WIDTH * median);
  131 + // keep only faces that are not too big or small
  132 + vec_DetPar all_detpars(detpars);
  133 + detpars.resize(0);
  134 + for (int iface = 0; iface < NSIZE(all_detpars); iface++)
  135 + {
  136 + DetPar* face = &all_detpars[iface];
  137 + if (face->width >= minallowed && face->width <= maxallowed)
  138 + detpars.push_back(*face);
  139 + else if (trace_g || TRACE_IMAGES)
  140 + lprintf("[discard %d of %d]", iface, NSIZE(all_detpars));
  141 + }
  142 + }
  143 +}
  144 +
  145 +static void TraceFaces( // write image showing detected face rects
  146 + const vec_DetPar& detpars, // in
  147 + const Image& img, // in
  148 + const char* filename) // in
  149 +{
  150 + (void) detpars;
  151 + (void) img;
  152 + (void) filename;
  153 +
  154 +#if TRACE_IMAGES // will be 0 unless debugging (defined in stasm.h)
  155 +
  156 + CImage cimg; cvtColor(img, cimg, CV_GRAY2BGR); // color image
  157 + for (int iface = 0; iface < NSIZE(detpars); iface++)
  158 + {
  159 + const DetPar &detpar = detpars[iface];
  160 +
  161 + rectangle(cimg,
  162 + cv::Point(cvRound(detpar.x - detpar.width/2),
  163 + cvRound(detpar.y - detpar.height/2)),
  164 + cv::Point(cvRound(detpar.x + detpar.width/2),
  165 + cvRound(detpar.y + detpar.height/2)),
  166 + CV_RGB(255,255,0), 2);
  167 +
  168 + ImgPrintf(cimg, // 10 * iface to minimize overplotting
  169 + detpar.x + 10 * iface, detpar.y, 0xffff00, 1, ssprintf("%d", iface));
  170 + }
  171 + cv::imwrite(filename, cimg);
  172 +
  173 +#endif
  174 +}
  175 +
  176 +void FaceDet::DetectFaces_( // call once per image to find all the faces
  177 + const Image& img, // in: the image (grayscale)
  178 + const char*, // in: unused (match virt func signature)
  179 + bool multiface, // in: if false, want only the best face
  180 + int minwidth, // in: min face width as percentage of img width
  181 + void* user, // in: unused (match virt func signature)
  182 + cv::CascadeClassifier cascade)
  183 +{
  184 + CV_Assert(user == NULL);
  185 + //CV_Assert(!facedet_g.empty()); // check that OpenFaceDetector_ was called
  186 +
  187 + DetectFaces(detpars_, img, minwidth, cascade);
  188 + TraceFaces(detpars_, img, "facedet_BeforeDiscardMissizedFaces.bmp");
  189 + DiscardMissizedFaces(detpars_);
  190 + TraceFaces(detpars_, img, "facedet_AfterDiscardMissizedFaces.bmp");
  191 + if (multiface) // order faces on increasing distance from left margin
  192 + {
  193 + sort(detpars_.begin(), detpars_.end(), IncreasingLeftMargin);
  194 + TraceFaces(detpars_, img, "facedet.bmp");
  195 + }
  196 + else
  197 + {
  198 + // order faces on decreasing width, keep only the first (the largest face)
  199 + sort(detpars_.begin(), detpars_.end(), DecreasingWidth);
  200 + TraceFaces(detpars_, img, "facedet.bmp");
  201 + if (NSIZE(detpars_))
  202 + detpars_.resize(1);
  203 + }
  204 + iface_ = 0; // next invocation of NextFace_ must get first face
  205 +}
  206 +
  207 +// Get the (next) face from the image.
  208 +// If no face available, return detpar.x INVALID.
  209 +// Eyes, mouth, and rot in detpar always returned INVALID.
  210 +
  211 +const DetPar FaceDet::NextFace_(void)
  212 +{
  213 + DetPar detpar; // detpar constructor sets all fields INVALID
  214 +
  215 + if (iface_ < NSIZE(detpars_))
  216 + detpar = detpars_[iface_++];
  217 +
  218 + return detpar;
  219 +}
  220 +
  221 +} // namespace stasm
0 222 \ No newline at end of file
... ...
3rdparty/stasm4.0.0/stasm/src/initasm.cpp 0 → 100755
  1 +// initasm.cpp: initialize the ASM model
  2 +//
  3 +// Copyright (C) 2005-2013, Stephen Milborrow
  4 +
  5 +#include "initasm.h"
  6 +#include "yaw00.h"
  7 +
  8 +namespace stasm
  9 +{
  10 +void InitMods( // initialize ASM model
  11 + vec_Mod& mods, // out: ASM model (only one model in this version of Stasm)
  12 + const char* datadir) // in: directory of face detector files
  13 +{
  14 + if (mods.empty()) // models not yet initialized?
  15 + {
  16 + mods.resize(1); // 1 model
  17 +
  18 + static const Mod mod_yaw00(
  19 + EYAW00,
  20 + ESTART_EYES, // ignore detected mouth for best startshape on frontal faces
  21 + datadir,
  22 + yaw00_meanshape,
  23 + yaw00_eigvals,
  24 + yaw00_eigvecs,
  25 + 20, // neigs (value from empirical testing)
  26 + 1.5, // bmax (value from empirical testing)
  27 + SHAPEHACKS_DEFAULT | SHAPEHACKS_SHIFT_TEMPLE_OUT,
  28 + YAW00_DESCMODS, // defined in yaw00.h
  29 + NELEMS(YAW00_DESCMODS));
  30 +
  31 + mods[0] = &mod_yaw00;
  32 + }
  33 +}
  34 +
  35 +} // namespace stasm
0 36 \ No newline at end of file
... ...