-
Notifications
You must be signed in to change notification settings - Fork 1
/
face_landmark_detection_to_file.cpp
166 lines (130 loc) · 6.39 KB
/
face_landmark_detection_to_file.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
// 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 <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 <iostream>
#include <dlib/opencv.h>
#include <cstdio>
#include <ctime>
#if CV_MAJOR_VERSION < 3
#include <opencv2/highgui/highgui.hpp> // If you are using OpenCV 2
#else
#include <opencv2/imgproc.hpp> // If you are using OpenCV 3
#endif
#include "render_face.hpp"
using namespace dlib;
using namespace std;
// ----------------------------------------------------------------------------------------
int main(int argc, char** argv)
{
try
{
// 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;
std::clock_t start = std::clock();
double duration = 0;
image_window win, win_faces;
// Loop over all the images provided on the command line.
for (int i = 2; i < argc; ++i)
{
std::string filename(argv[i]);
// cout << "processing image " << filename << endl;
//array2d<rgb_pixel> img;
//load_image(img, argv[i]);
cv::Mat imgMat = cv::imread(argv[i]);
cv_image<bgr_pixel> img(imgMat);
// 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.
size_t lastindex = filename.find_last_of(".");
string basename = filename.substr(0, lastindex);
std::vector<full_object_detection> shapes;
for (unsigned long j = 0; j < dets.size(); ++j)
{
full_object_detection shape = sp(img, dets[j]);
shapes.push_back(shape);
std::stringstream points_filename;
std::ofstream ofs;
if ( j == 0 )
{
points_filename << basename << ".txt";
}else
{
points_filename << basename << "_" << j << ".txt";
}
ofs.open(points_filename.str().c_str());
const full_object_detection& d = shapes[0];
for (unsigned long k = 0; k < shape.num_parts(); ++k)
{
ofs << shape.part(k).x() << " " << shape.part(k).y() << endl;
}
ofs.close();
render_face(imgMat, shape);
}
// dont want to display each image
//cv::imshow("image", imgMat);
//cv::waitKey(0);
//cout<<"duration of " << i << " is: " << duration << endl ;
}
duration = ((double)(std::clock() - start) / CLOCKS_PER_SEC) ;
std::cout << "total duration is: " << duration << endl << endl;
}
catch (exception& e)
{
cout << "\nexception thrown!" << endl;
cout << e.what() << endl;
}
}
// ----------------------------------------------------------------------------------------