-
Notifications
You must be signed in to change notification settings - Fork 1
/
webcam.cpp
155 lines (126 loc) · 5.05 KB
/
webcam.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
// 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 example is essentially just a version of the face_landmark_detection_ex.cpp
example modified to use OpenCV's VideoCapture object to read from a camera instead
of files.
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/opencv.h>
#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_transforms.h>
#include <dlib/image_io.h>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace dlib;
using namespace std;
using namespace cv;
void render_exterior_landmarks(cv::Mat &img, const dlib::full_object_detection& d, const int start, const int end)
{
std::vector<cv::Point> points;
for (int i = start; i <= 16; ++i)
{
points.push_back(cv::Point(d.part(i).x(), d.part(i).y()));
}
for (int i = end; i > 16; --i)
{
points.push_back(cv::Point(d.part(i).x(), d.part(i).y()));
}
cv::polylines(img, points, true, cv::Scalar(255,0,0), 2, 16);
}
void render_turd_on_forehead(cv::Mat &img, cv::Mat &sprite, const dlib::full_object_detection& d){
cv::Point rightEyebrow(d.part(17).x(),d.part(17).y());
cv::Point leftEyebrow(d.part(22).x(),d.part(22).y());
int w= 1.5*abs(leftEyebrow.x-rightEyebrow.x);
int h=w/1.5;
cv::Mat small;
cv::Rect roi( cv::Point( rightEyebrow.x, rightEyebrow.y-h ), cv::Size( w, h ));
if(
roi.x>0 &&
roi.y>0 &&
roi.x + roi.width < img.cols &&
roi.x + roi.width < img.rows)
{
cv::resize(sprite,small,roi.size());
cv::Mat imageROI= img(Rect(rightEyebrow.x,rightEyebrow.y-h,w,h));
cv::addWeighted(imageROI,1.0,small,1.0,0.,imageROI);
//small.copyTo(imageROI);
}
}
int main(int argc, char *argv[])
{
try
{
cv::VideoCapture cap(0);
//image_window win;
namedWindow("w",1);
if(!cap.isOpened()) { // check if we succeeded
return -1;
}
// Load face detection and pose estimation models.
frontal_face_detector detector = get_frontal_face_detector();
shape_predictor pose_model;
std::string model("shape_predictor_68_face_landmarks.dat");
std::string turdFilename("turd.png");
if(argc > 2){
model=argv[1];
turdFilename = argv[2];
} else {
cout<<" Remember usage with custom files is: "<<endl;
cout<<" ./webcam [dlib_model] [image]"<<endl;
}
deserialize(model) >> pose_model;
cv::Mat turd;
turd= imread(turdFilename);
while(true)
{
// Grab a frame
cv::Mat tempBig, temp;
cap >> tempBig;
cv::resize(tempBig, temp, cv::Size(), 1.0/1.0, 1.0/1.0);
cv_image<bgr_pixel> cimg(temp);
// Detect faces
std::vector<dlib::rectangle> faces = detector(cimg);
if (faces.size()>0) {
full_object_detection shapes = pose_model(cimg, faces[0]);
render_exterior_landmarks(temp,shapes,0,26);
render_turd_on_forehead(temp,turd,shapes);
}
imshow("w",temp);
if(waitKey(30) >= 0) {
break;
}
}
}
catch(serialization_error& e)
{
cout << "You need dlib's default face landmarking model file to run this example." << endl;
cout << "You can get it from the following URL: " << endl;
cout << " http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2" << endl;
cout << endl << e.what() << endl;
}
catch(exception& e)
{
cout << e.what() << endl;
}
}