参考文章: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; }速度很快,无卡顿现象