Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
- /*
- This example program shows how to find frontal human faces in an image and
- estimate their pose. The pose takes the form of 68 landmarks. These are
- points on the face such as the corners of the mouth, along the eyebrows, on
- the eyes, and so forth.
- This face detector is made using the classic Histogram of Oriented
- Gradients (HOG) feature combined with a linear classifier, an image pyramid,
- and sliding window detection scheme. The pose estimator was created by
- using dlib's implementation of the paper:
- One Millisecond Face Alignment with an Ensemble of Regression Trees by
- Vahid Kazemi and Josephine Sullivan, CVPR 2014
- and was trained on the iBUG 300-W face landmark dataset.
- Also, note that you can train your own models using dlib's machine learning
- tools. See train_shape_predictor_ex.cpp to see an example.
- Finally, note that the face detector is fastest when compiled with at least
- SSE2 instructions enabled. So if you are using a PC with an Intel or AMD
- chip then you should enable at least SSE2 instructions. If you are using
- cmake to compile this program you can enable them by using one of the
- following commands when you create the build project:
- cmake path_to_dlib_root/examples -DUSE_SSE2_INSTRUCTIONS=ON
- cmake path_to_dlib_root/examples -DUSE_SSE4_INSTRUCTIONS=ON
- cmake path_to_dlib_root/examples -DUSE_AVX_INSTRUCTIONS=ON
- This will set the appropriate compiler options for GCC, clang, Visual
- Studio, or the Intel compiler. If you are using another compiler then you
- need to consult your compiler's manual to determine how to enable these
- instructions. Note that AVX is the fastest but requires a CPU from at least
- 2011. SSE4 is the next fastest and is supported by most current machines.
- */
- #include "stdafx.h"
- #include <stdlib.h>
- #include <string>
- #include <boost/filesystem.hpp>
- #include <boost/foreach.hpp>
- #include <dlib/image_processing/frontal_face_detector.h>
- #include <dlib/image_processing/render_face_detections.h>
- #include <dlib/image_processing.h>
- #include <dlib/gui_widgets.h>
- #include <dlib/image_io.h>
- #include <dlib/svm_threaded.h>
- #include <iostream>
- #include <fstream>
- using namespace dlib;
- using namespace std;
- namespace fs = boost::filesystem;
- typedef matrix<double, 3, 1> sample_type;
- std::vector<double> mouthareas;
- std::vector<double> lefteyeareas;
- std::vector<double> righteyeareas;
- std::vector<string> labelpaths;
- void generate_data(std::vector<sample_type>& samples, std::vector<string>& labels);
- void classify();
- // ----------------------------------------------------------------------------------------
- int main(int argc, char** argv)
- {
- try
- {
- fs::path targetDirIm("facesemotion");
- fs::directory_iterator itim(targetDirIm), eodim;
- // This example takes in a shape model file and then a list of images to
- // process. We will take these filenames in as command line arguments.
- // Dlib comes with example images in the examples/faces folder so give
- // those as arguments to this program.
- /*if (argc == 1)
- {
- cout << "Call this program like this:" << endl;
- cout << "./face_landmark_detection_ex shape_predictor_68_face_landmarks.dat faces/*.jpg" << endl;
- cout << "\nYou can get the shape_predictor_68_face_landmarks.dat file from:\n";
- cout << "http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2" << endl;
- return 0;
- }
- */
- // We need a face detector. We will use this to get bounding boxes for
- // each face in an image.
- frontal_face_detector detector = get_frontal_face_detector();
- // And we also need a shape_predictor. This is the tool that will predict face
- // landmark positions given an image and face bounding box. Here we are just
- // loading the model from the shape_predictor_68_face_landmarks.dat file you gave
- // as a command line argument.
- shape_predictor sp;
- deserialize(argv[1]) >> sp;
- //image_window win, win_faces;
- string emotionname;
- string photofilename;
- // Loop over all the images provided in folder.
- BOOST_FOREACH(fs::path const &p, std::make_pair(itim, eodim))
- {
- if (fs::is_regular_file(p))
- {
- emotionname = p.string();
- emotionname = emotionname.substr(13, emotionname.size() - 17);
- emotionname = "labels/" + emotionname + "_emotion.txt";
- cout << emotionname << endl;
- if (fs::is_regular_file(emotionname)) {
- cout << "yes" << endl;
- /*
- //cout << p << endl;
- labelpaths.push_back(emotionname);
- string line;
- string labelname;
- std::vector<string> featurepoints;
- ifstream myfile(p.string());
- if (myfile.is_open())
- {
- while (getline(myfile, line))
- {
- featurepoints.push_back(line);
- }
- myfile.close();
- }
- else {
- cout << "Unable to open file";
- }
- */
- cout << "processing image " << p << endl;
- array2d<rgb_pixel> img;
- load_image(img, p.string());
- // Make the image larger so we can detect small faces.
- pyramid_up(img);
- // Now tell the face detector to give us a list of bounding boxes
- // around all the faces in the image.
- std::vector<rectangle> dets = detector(img);
- cout << "Number of faces detected: " << dets.size() << endl;
- // Now we will go ask the shape_predictor to tell us the pose of
- // each face we detected.
- for (unsigned long j = 0; j < dets.size(); ++j)
- {
- full_object_detection shape = sp(img, dets[j]);
- cout << "number of parts: " << shape.num_parts() << endl;
- cout << "pixel position of first part: " << shape.part(0) << endl;
- cout << "pixel position of second part: " << shape.part(1) << endl;
- string textface = emotionname.substr(7, emotionname.size() - 19);
- textface = "textfaces/" + textface + ".txt";
- ofstream myfile;
- myfile.open(textface);
- cout << textface;
- for (int i = 0; i < shape.num_parts(); i++) {
- myfile << shape.part(i) << "\n" ;
- }
- myfile.close();
- // myfile.close();
- //assign facial landmarks to part of face
- std::vector<point> mouthlist;
- std::vector<point >leftbrowlist;
- std::vector<point > rightbrowlist;
- std::vector<point > righteyelist;
- std::vector<point > lefteyelist;
- std::vector<point> noselist;
- std::vector<point > jawlist;
- for (int i = 0; i < shape.num_parts(); i++) {
- if (i <= 17) {
- jawlist.push_back(shape.part(i));
- }
- else if (i <= 22) {
- leftbrowlist.push_back(shape.part(i));
- }
- else if (i <= 27) {
- rightbrowlist.push_back(shape.part(i));
- }
- else if (i <= 36) {
- noselist.push_back(shape.part(i));
- }
- else if (i <= 42) {
- lefteyelist.push_back(shape.part(i));
- }
- else if (i <= 48) {
- righteyelist.push_back(shape.part(i));
- }
- else {
- mouthlist.push_back(shape.part(i));
- }
- }
- //compute geometrical features
- /*
- int mouthxmin = 20000;
- int mouthxmax = -1;
- int mouthymin = 20000;
- int mouthymax = -1;
- int lefteyexmin = 20000;
- int lefteyexmax = -1;
- int lefteyeymin = 20000;
- int lefteyeymax = -1;
- int righteyexmin = 20000;
- int righteyexmax = -1;
- int righteyeymin = 20000;
- int righteyeymax = -1;
- for (int ii = 0; ii < mouthlist.size(); ii++) {
- int xvalue = std::stoi(mouthlist.at(ii).substr(1, 3));
- int yvalue = std::stoi(mouthlist.at(ii).substr(6, 3));
- if (xvalue > mouthxmax) {
- mouthxmax = xvalue;
- }
- if (xvalue < mouthxmin) {
- mouthxmin = xvalue;
- }
- if (yvalue > mouthymax) {
- mouthymax = yvalue;
- }
- if (yvalue < mouthymin) {
- mouthymin = yvalue;
- }
- }
- int mouthwidth = mouthxmax - mouthxmin;
- int mouthlength = mouthymax - mouthymin;
- int mouthA = mouthwidth * mouthlength;
- int mouthP = 2 * (1 + mouthwidth);
- mouthareas.push_back(mouthA/1000);
- //cout << mouthareas.size() << endl;
- for (int ii = 0; ii < lefteyelist.size(); ii++) {
- int xvalue = std::stoi(lefteyelist.at(ii).substr(1, 3));
- int yvalue = std::stoi(lefteyelist.at(ii).substr(6, 3));
- if (xvalue> lefteyexmax) {
- lefteyexmax = xvalue;
- }
- if (xvalue < lefteyexmin) {
- lefteyexmin = xvalue;
- }
- if (yvalue > lefteyeymax) {
- lefteyeymax = yvalue;
- }
- if (yvalue < lefteyeymin) {
- lefteyeymin = yvalue;
- }
- }
- int lefteyewidth = lefteyexmax - lefteyexmin;
- int lefteyelength = lefteyeymax - lefteyeymin;
- int lefteyeA = lefteyewidth * lefteyelength;
- int lefteyeP = 2 * (1 + lefteyewidth);
- lefteyeareas.push_back(lefteyeA/1000);
- // cout << lefteyeareas.size() << endl;
- for (int ii = 0; ii < righteyelist.size(); ii++) {
- int xvalue = std::stoi(righteyelist.at(ii).substr(1, 3));
- int yvalue = std::stoi(righteyelist.at(ii).substr(6, 3));
- if (xvalue > righteyexmax) {
- righteyexmax = xvalue;
- }
- if (xvalue < righteyexmin) {
- righteyexmin = xvalue;
- }
- if (yvalue > righteyeymax) {
- righteyeymax = yvalue;
- }
- if (yvalue < righteyeymin) {
- righteyeymin = yvalue;
- }
- }
- int righteyewidth = righteyexmax - righteyexmin;
- int righteyelength = righteyeymax - righteyeymin;
- int righteyeA = righteyewidth * righteyelength;
- int righteyeP = 2 * (1 + righteyewidth);
- righteyeareas.push_back(righteyeA/1000);
- */
- }
- }
- }
- }
- classify();
- }
- catch (exception& e)
- {
- cout << "\nexception thrown!" << endl;
- cout << e.what() << endl;
- }
- }
- //svm classifier using cross-fold classification
- void classify()
- {
- //cout << "classifying" << endl;
- std::vector<sample_type> samples;
- std::vector<string> labels;
- generate_data(samples, labels);
- // cout << "generated data" << endl;
- typedef linear_kernel<sample_type> lin_kernel;
- typedef svm_multiclass_linear_trainer <lin_kernel, string> svm_mc_trainer;
- svm_mc_trainer trainer;
- multiclass_linear_decision_function<lin_kernel, string> df;
- deserialize("df.dat") >> df;
- randomize_samples(samples, labels);
- //cout << "randomized" << endl;
- cout << "cross validation: \n" << cross_validate_multiclass_trainer(trainer, samples, labels, 8) << endl;
- serialize("df.dat") << df;
- }
- void generate_data(std::vector<sample_type>& samples, std::vector<string>& labels)
- {
- //make data with all features + labels in order to train classifier
- //cout << "generating data" << endl;
- sample_type m;
- for (int i = 0; i < labelpaths.size(); i++) {
- string emotionname = labelpaths.at(i);
- m = { mouthareas.at(i), righteyeareas.at(i), lefteyeareas.at(i) };
- // cout << m << endl;
- samples.push_back(m);
- string line;
- string labelname;
- ifstream myfile(emotionname);
- if (myfile.is_open())
- {
- while (getline(myfile, line))
- {
- labelname = line;
- }
- myfile.close();
- }
- else {
- // cout << "Unable to open file";
- }
- labels.push_back(labelname);
- cout << labelname << endl;
- }
- }
- // ----------------------------------------------------------------------------------------
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement