【opencv人脸识别】从视频中检测人脸
1.从视频中识别人脸和人的眼睛
2. 从视频中检测人脸、眼睛、鼻子、嘴巴
上一节,讲了如何从图片中检测人脸,这一节讲如何从视频中检测人脸。 在opencv自带的说明中便有从视频中检测人脸的例子,在..opencv3_4opencvsourcessamplescpptutorial_codeobjectDetection文件夹下有objectDetection.cpp,将此例子稍作修改,就可以为我们所用。
1.从视频中识别人脸和人的眼睛
关于视频的操作,主要如下:
定义摄像头->打开摄像头->读取视频帧->转而为对图片的操作(一帧就相当于一幅图片)
1
2
3
4
5
6
7
8
9VideoCapture capture; //定义摄像头捕捉 变量 Mat frame; capture.open(0); //打开摄像头 while (capture.read(frame)) //读取帧 { //进行人脸检测 //显示 }
视频人脸检测的代码:
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
166
167
168
169
170
171//face_detect_from_video.cpp 定义控制台应用程序的入口点。 //从视频中识别人脸和人的眼睛 #include "stdafx.h" #include "opencv2/objdetect.hpp" #include "opencv2/highgui.hpp" #include "opencv2/imgproc.hpp" #include <stdio.h> using namespace std; using namespace cv; /** Function Headers */ void detectAndDisplay(Mat frame); /** Global variables */ String face_cascade_name, eyes_cascade_name; CascadeClassifier face_cascade; CascadeClassifier eyes_cascade; String window_name = "Capture - Face detection"; /** @function main */ int main(int argc, const char** argv) { face_cascade_name = "./xml/haarcascade_frontalface_alt.xml"; eyes_cascade_name = "./xml/haarcascade_eye.xml"; VideoCapture capture; Mat frame; //-- 1. Load the cascades if (!face_cascade.load(face_cascade_name)) { printf("--(!)Error loading face cascaden"); return -1; }; if (!eyes_cascade.load(eyes_cascade_name)) { printf("--(!)Error loading eyes cascaden"); return -1; }; //-- 2. Read the video stream capture.open(0); //打开摄像头 if (!capture.isOpened()) { printf("--(!)Error opening video capturen"); return -1; } while (capture.read(frame)) //读取帧 { if (frame.empty()) { printf(" --(!) No captured frame -- Break!"); break; } //-- 3. Apply the classifier to the frame detectAndDisplay(frame); if (waitKey(10) == 'k') { break; } // escape } return 0; } /** @function detectAndDisplay */ void detectAndDisplay(Mat frame) { std::vector<Rect> faces; Mat frame_gray; cvtColor(frame, frame_gray, COLOR_BGR2GRAY); //BGR 转化为灰度图 equalizeHist(frame_gray, frame_gray); //直方图均衡化 //-- Detect faces face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(60, 60)); for (size_t i = 0; i < faces.size(); i++) { Point center(faces[i].x + faces[i].width / 2, faces[i].y + faces[i].height / 2); // 人脸中心坐标 ellipse(frame, center, Size(faces[i].width / 2, faces[i].height / 2), 0, 0, 360, Scalar(255, 0, 255), 4, 8, 0); // 椭圆 Mat faceROI = frame_gray(faces[i]); std::vector<Rect> eyes; //-- In each face, detect eyes eyes_cascade.detectMultiScale(faceROI, eyes, 1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30)); for (size_t j = 0; j < eyes.size(); j++) { Point eye_center(faces[i].x + eyes[j].x + eyes[j].width / 2, faces[i].y + eyes[j].y + eyes[j].height / 2); //眼睛的中心 int radius = cvRound((eyes[j].width + eyes[j].height)*0.25); //取整 circle(frame, eye_center, radius, Scalar(255, 0, 0), 4, 8, 0); } } //-- Show what you got imshow(window_name, frame); }
从视频中识别人脸和人的眼睛 #include "stdafx.h" #include "opencv2/objdetect.hpp" #include "opencv2/highgui.hpp" #include "opencv2/imgproc.hpp" #include <stdio.h> using namespace std; using namespace cv; /** Function Headers */ void detectAndDisplay(Mat frame); /** Global variables */ String face_cascade_name, eyes_cascade_name; CascadeClassifier face_cascade; CascadeClassifier eyes_cascade; String window_name = "Capture - Face detection"; /** @function main */ int main(int argc, const char** argv) { face_cascade_name = "./xml/haarcascade_frontalface_alt.xml"; eyes_cascade_name = "./xml/haarcascade_eye.xml"; VideoCapture capture; Mat frame; //-- 1. Load the cascades if (!face_cascade.load(face_cascade_name)) { printf("--(!)Error loading face cascaden"); return -1; }; if (!eyes_cascade.load(eyes_cascade_name)) { printf("--(!)Error loading eyes cascaden"); return -1; }; //-- 2. Read the video stream capture.open(0); //打开摄像头 if (!capture.isOpened()) { printf("--(!)Error opening video capturen"); return -1; } while (capture.read(frame)) //读取帧 { if (frame.empty()) { printf(" --(!) No captured frame -- Break!"); break; } //-- 3. Apply the classifier to the frame detectAndDisplay(frame); if (waitKey(10) == 'k') { break; } // escape } return 0; } /** @function detectAndDisplay */ void detectAndDisplay(Mat frame) { std::vector<Rect> faces; Mat frame_gray; cvtColor(frame, frame_gray, COLOR_BGR2GRAY); //BGR 转化为灰度图 equalizeHist(frame_gray, frame_gray); //直方图均衡化 //-- Detect faces face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(60, 60)); for (size_t i = 0; i < faces.size(); i++) { Point center(faces[i].x + faces[i].width / 2, faces[i].y + faces[i].height / 2); // 人脸中心坐标 ellipse(frame, center, Size(faces[i].width / 2, faces[i].height / 2), 0, 0, 360, Scalar(255, 0, 255), 4, 8, 0); // 椭圆 Mat faceROI = frame_gray(faces[i]); std::vector<Rect> eyes; //-- In each face, detect eyes eyes_cascade.detectMultiScale(faceROI, eyes, 1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30)); for (size_t j = 0; j < eyes.size(); j++) { Point eye_center(faces[i].x + eyes[j].x + eyes[j].width / 2, faces[i].y + eyes[j].y + eyes[j].height / 2); //眼睛的中心 int radius = cvRound((eyes[j].width + eyes[j].height)*0.25); //取整 circle(frame, eye_center, radius, Scalar(255, 0, 0), 4, 8, 0); } } //-- Show what you got imshow(window_name, frame); }
运行结果:
2. 从视频中检测人脸、眼睛、鼻子、嘴巴
此部分结合了之前讲的识别人脸特征:运行opencv3.4中的demo--facial_features.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//face_recog_from_video.cpp 定义控制台应用程序的入口点。 #include "stdafx.h" #include "opencv2/objdetect.hpp" #include "opencv2/highgui.hpp" #include "opencv2/imgproc.hpp" #include <stdio.h> #include<iostream> using namespace std; using namespace cv; /** Function Headers */ void detectAndDisplay(Mat frame); /** Global variables */ String face_cascade_name, eyes_cascade_name, nose_cascade_name , mouth_cascade_name; CascadeClassifier face_cascade; CascadeClassifier eyes_cascade; CascadeClassifier nose_cascade; CascadeClassifier mouth_cascade; String window_name = "Capture - Face detection"; /** @function main */ int main(int argc, const char** argv) { face_cascade_name = "./xml/haarcascade_frontalface_alt.xml"; eyes_cascade_name = "./xml/haarcascade_eye.xml"; nose_cascade_name = "./xml/haarcascade_mcs_nose.xml"; mouth_cascade_name = "./xml/haarcascade_mcs_mouth.xml"; VideoCapture capture; Mat frame; //-- 1. Load the cascades if (!face_cascade.load(face_cascade_name)) { printf("--(!)Error loading face cascaden"); return -1; }; if (!eyes_cascade.load(eyes_cascade_name)) { printf("--(!)Error loading eyes cascaden"); return -1; }; if (!nose_cascade.load(nose_cascade_name)) { printf("--(!)Error loading nose cascaden"); return -1; }; if (!mouth_cascade.load(mouth_cascade_name)) { printf("--(!)Error loading mouth cascaden"); return -1; }; //-- 2. Read the video stream capture.open(0); //打开摄像头 if (!capture.isOpened()) { printf("--(!)Error opening video capturen"); return -1; } while (capture.read(frame)) //读取帧 { if (frame.empty()) { printf(" --(!) No captured frame -- Break!"); break; } //-- 3. Apply the classifier to the frame detectAndDisplay(frame); if (waitKey(10) == 'k') { break; } // escape } return 0; } /** @function detectAndDisplay */ void detectAndDisplay(Mat frame) { std::vector<Rect> faces; Mat frame_gray; cvtColor(frame, frame_gray, COLOR_BGR2GRAY); //BGR 转化为灰度图 equalizeHist(frame_gray, frame_gray); //直方图均衡化 //-- Detect faces face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(60, 60)); for (size_t i = 0; i < faces.size(); i++) { Point center(faces[i].x + faces[i].width / 2, faces[i].y + faces[i].height / 2); // 人脸中心坐标 ellipse(frame, center, Size(faces[i].width / 2, faces[i].height / 2), 0, 0, 360, Scalar(255, 0, 255), 4, 8, 0); // 椭圆 Mat faceROI = frame_gray(faces[i]); std::vector<Rect> eyes; std::vector<Rect> noses; std::vector<Rect> mouths; //-- In each face, detect eyes、nose、mouth eyes_cascade.detectMultiScale(faceROI, eyes, 1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30)); nose_cascade.detectMultiScale(faceROI, noses, 1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30)); mouth_cascade.detectMultiScale(faceROI, mouths, 1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30)); // eyes Point eye_center; for (size_t j = 0; j < eyes.size(); j++) { eye_center = Point(faces[i].x + eyes[j].x + eyes[j].width / 2, faces[i].y + eyes[j].y + eyes[j].height / 2); //眼睛的中心 if (eye_center.x>faces[i].x && eye_center.y > faces[i].y) // 确保眼睛在脸上,其实前边检测时,已经保证了这一点 { int radius = cvRound((eyes[j].width + eyes[j].height)*0.25); //取整 circle(frame, eye_center, radius, Scalar(255, 0, 0), 4, 8, 0); } } // nose Point nose_center; if (noses.size() > 0) { nose_center = Point(faces[i].x + noses[0].x + noses[0].width / 2, faces[i].y + noses[0].y + noses[0].height / 2); //鼻子的中心 if (nose_center.y > eye_center.y) //确保鼻子在眼睛下边 { rectangle(frame, Point(faces[i].x + noses[0].x, faces[i].y+ noses[0].y), Point(faces[i].x + noses[0].x + noses[0].width, faces[i].y + noses[0].y + noses[0].height), Scalar(0, 255, 0), 3, 8, 0); //Point(noses[0].x, noses[0].y), Point(noses[0].x + noses[0].width, noses[0].y + noses[0].height) //int radius = cvRound((noses[0].width + noses[0].height)*0.25); //取整 //circle(frame, nose_center, radius, Scalar(0, 255,0), 4, 8, 0); std::cout << "nose!n"; } } // mouth if (mouths.size() > 0) { Point mouth_center(faces[i].x + mouths[0].x + mouths[0].width / 2, faces[i].y + mouths[0].y + mouths[0].height / 2); //嘴巴的中心 if (mouth_center.y > nose_center.y) // 确保嘴巴在鼻子下边 { int radius = cvRound((mouths[0].width + mouths[0].height)*0.25); //取整 circle(frame, mouth_center, radius, Scalar(0, 0, 255), 4, 8, 0); std::cout << "mouth!n"; } } } //-- Show what you got imshow(window_name, frame); }
运行结果:
由结果可看出,较好的检测出来人脸及人脸特征,其中,粉色区域为face、蓝色为eye、绿色为nose、红色为mouth。
但多次试验会发现,误判的概率很高,所以模型与程序尚有较大改进空间。
注意:要对眼睛嘴巴鼻子的位置进行限定,可一定程度上减少误判。
------------------------------------------- END -------------------------------------
CSDN:大姨妈V
微信公众号:happyZhou
版权声明:本文为博主原创文章,转载请附上博文链接!
最后
以上就是受伤山水最近收集整理的关于【opencv人脸识别2】从视频中检测人脸的全部内容,更多相关【opencv人脸识别2】从视频中检测人脸内容请搜索靠谱客的其他文章。
发表评论 取消回复