参考文章:http://f.dataguru.cn/thread-927564-1-1.html
代码是另一个博主的,从浏览记录找不到是谁了,如有侵权请联系本人。在源代码基础上加上了嘴巴张闭检测
把原本低速的dlib人脸检测换成了高速的haar检测,提速明显,但是精度下降
#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/opencv.h>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#include <vector>
#include <ctime>
//using namespace dlib;
using namespace std;
//using namespace cv;
double getDistance(CvPoint pointO, CvPoint pointA);
int main(int argc, char *argv[])
{
time_t start_t, end_t;
//Mat转化为dlib的matrix
dlib::array2d<dlib::bgr_pixel> dimg;
//加载训练好的级联分类器,利用haar级联分类器快速找出人脸区域,然后交给dlib检测人脸部位
cv::CascadeClassifier faceDetector("haarcascade_frontalface_alt2.xml");
if (faceDetector.empty())
{
std::cout << "face detector is empty!" << std::endl;
return 0;
}
//加载人脸形状探测器
dlib::shape_predictor sp;
dlib::deserialize("shape_predictor_68_face_landmarks.dat") >> sp;
cv::VideoCapture cam("3.mp4");
while (cam.isOpened()) {
//haar级联分类器探测人脸区域,获取一系列人脸所在区域
std::vector<cv::Rect> objects;
std::vector<dlib::rectangle> dets;
cv::Mat frame;
cv::Mat src;
cam >> frame;
cv::pyrDown(frame, frame, frame.size() / 2);
cv::imshow("原图", frame);
//提取灰度图
cv::cvtColor(frame, src, CV_BGR2GRAY);
dlib::assign_image(dimg, dlib::cv_image<uchar>(src));
faceDetector.detectMultiScale(src, objects);
for (int i = 0; i < objects.size(); i++)
{
//cv::rectangle(frame, objects[i], CV_RGB(200, 0, 0));
dlib::rectangle r(objects[i].x, objects[i].y, objects[i].x + objects[i].width, objects[i].y + objects[i].height);
dets.push_back(r);
}
//获取人脸68个特征点部位分布
std::vector<dlib::full_object_detection> shapes;
for (int i = 0; i < dets.size(); i++)
{
dlib::full_object_detection shape = sp(dimg, dets[i]);
shapes.push_back(shape);
}
if (!shapes.empty()) {
for (int i = 0; i < 68; i++) {
circle(frame, cvPoint(shapes[0].part(i).x(), shapes[0].part(i).y()), 1, cv::Scalar(255, 255, 255), -1);
}
}
//上下嘴唇
CvPoint p66 = cvPoint(shapes[0].part(66).x(), shapes[0].part(66).y());
CvPoint p62 = cvPoint(shapes[0].part(62).x(), shapes[0].part(62).y());
//左眼上下
CvPoint p37 = cvPoint(shapes[0].part(37).x(), shapes[0].part(37).y());
CvPoint p41 = cvPoint(shapes[0].part(41).x(), shapes[0].part(41).y());
double L_mouth = getDistance(p66, p62);
double L_left_eye = getDistance(p37,p41);
cout << L_left_eye << endl;
if (L_mouth == 0) {
cv::putText(frame, "close mouth", cvPoint(10, 50), 5, 1, cv::Scalar(0, 0, 255), 1, 8, 0);
}
cv::imshow("frame", frame);
cv::waitKey(27);
}
return 0;
}
double getDistance(CvPoint pointO, CvPoint pointA)
{
double distance;
distance = powf((pointO.x - pointA.x), 2) + powf((pointO.y - pointA.y), 2);
distance = sqrtf(distance);
return distance;
}
速度很快,无卡顿现象