我们常常看到一些手机app可以给摄像头下的自己添加各种小挂件,现在有了dlib库,我们也能简单轻易的实现这些功能
思路
利用dlib库的对人脸描绘出68点,根据68点坐标值,通过计算和掩模算法,对图像进行叠加即可。
在这儿我们需要注意的是,我们要利用合理的掩模算法,使得png图像在copyTo上去时不留白边。
代码
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 |
#include <dlib/opencv.h> #include <opencv2/opencv.hpp> #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> using namespace dlib; using namespace std; int main() { try { cv::VideoCapture cap(0); int dis=0; cv::Mat frame; cv::Mat frame_bird; cv::Mat mask; cv::Mat imageROI; frame = cv::imread("face.png"); frame_bird = cv::imread("bianfu.png"); mask = cv::imread("bianfu.png", 0); frontal_face_detector detector = get_frontal_face_detector(); shape_predictor pose_model; deserialize("shape_predictor_68_face_landmarks.dat") >> pose_model; cv::Mat temp; while (1) { cap >> frame; temp = frame.clone(); cv_image<bgr_pixel> cimg(temp); std::vector<rectangle> faces = detector(cimg); std::vector<full_object_detection> shapes; for (unsigned long i = 0; i < faces.size(); ++i) shapes.push_back(pose_model(cimg, faces[i])); imageROI = temp(cv::Rect(0, 0, frame_bird.cols, frame_bird.rows)); if (!shapes.empty()) { //for (int i = 0; i < 68; i++) { //circle(temp, cvPoint(shapes[0].part(i).x(), shapes[0].part(i).y()), 3, cv::Scalar(0, 0, 255), -1); //putText(temp, to_string(i), cvPoint(shapes[0].part(i).x(), shapes[0].part(i).y()), CV_FONT_HERSHEY_PLAIN, 1, cv::Scalar(0, 0, 255)); // shapes[0].part(i).x();//68个 //} dis = shapes[0].part(8).y() - shapes[0].part(0).y(); if (dis * 2 / 3 < shapes[0].part(1).y() && dis != 0) { imageROI = temp(cv::Rect(shapes[0].part(8).x() - 64, shapes[0].part(0).y() - 64 - dis * 2 / 3, frame_bird.cols, frame_bird.rows)); } } frame_bird.copyTo(imageROI, mask); imshow("Dlib特征点", temp); cv::waitKey(1); } } 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; } } |
效果图