轉自https://blog.csdn.net/zmdsjtu/article/details/53454071?ticket=ST-3153-47Plcph2ez6yRnbTZqXP-passport.csdn.net
主要在官網給的Demo基礎之上用Opencv把特征點描繪出來了。
很早之前寫過一篇配置Dlib環境的部落格,現在來稍微梳理下提取特征點的使用方法。
上一篇配置環境部落格位址:http://blog.csdn.net/zmdsjtu/article/details/52422847
慣例先放效果圖吧:
動圖如下:
接着就是簡單粗暴的代碼:
- //@[email protected]
- //2016-12-4
- //http://blog.csdn.net/zmdsjtu/article/details/53454071
- #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();
- if (!cap.isOpened())
- {
- cerr << "Unable to connect to camera" << endl;
- return ;
- }
- //image_window win;
- // Load face detection and pose estimation models.
- frontal_face_detector detector = get_frontal_face_detector();
- shape_predictor pose_model;
- deserialize( "shape_predictor_68_face_landmarks.dat") >> pose_model;
- // Grab and process frames until the main window is closed by the user.
- while (cv::waitKey( ) != )
- {
- // Grab a frame
- cv::Mat temp;
- cap >> temp;
- cv_image<bgr_pixel> cimg(temp);
- // Detect faces
- std:: vector<rectangle> faces = detector(cimg);
- // Find the pose of each face.
- std:: vector<full_object_detection> shapes;
- for ( unsigned long i = ; i < faces.size(); ++i)
- shapes.push_back(pose_model(cimg, faces[i]));
- if (!shapes.empty()) {
- for ( int i = ; i < ; i++) {
- circle(temp, cvPoint(shapes[ ].part(i).x(), shapes[ ].part(i).y()), , cv::Scalar( , , ), );
- // shapes[0].part(i).x();//68個
- }
- }
- //Display it all on the screen
- imshow( "Dlib特征點", temp);
- }
- }
- 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;
- }
- }
來看下上面那段代碼,所有的需要的特征點都存儲在Shapes裡。仔細看看下面這行代碼:
circle(temp, cvPoint(shapes[].part(i).x(), shapes[].part(i).y()), , cv::Scalar(, , ), );
可以看到shpes[0]代表的是第一個人(可以同時檢測到很多個人),part(i)代表的是第i個特征點,x()和y()是通路特征點坐标的途徑。
每個特征點的編号如下:
在上述畫圖的基礎上加了如下一行代碼:
putText(temp, to_string(i), cvPoint(shapes[].part(i).x(), shapes[].part(i).y()), CV_FONT_HERSHEY_PLAIN, , cv::Scalar(, , ),,);
效果圖:
對照着上圖,比如說想擷取鼻尖的坐标,那麼橫坐标就是shapes[0].part[30].x(),其餘的類似。
在這個的基礎上就可以做很多有意思的事情啦,2333
最後祝大家開發愉快:)