1. 程式人生 > >opencv聯合dlib人臉檢測例子

opencv聯合dlib人臉檢測例子

原始碼比較簡潔,雜餘資訊全部去掉,原始碼中已經做了中文註釋。本例子是用opencv載入影象,然後呼叫dlib進行人臉檢測,得到人臉所在區域以及特徵點,最後還是用opencv描繪人臉特徵點。

例子原始碼以及解釋:

#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 <iostream> #include <dlib/opencv.h> #include "opencv2/opencv.hpp" #include <vector> #include <ctime> //由於dlib和opencv中有相當一部分類同名,故不能同時對它們使用using namespace,否則會出現一些莫名其妙的問題 //using namespace dlib; using namespace std; //using namespace cv; void line_one_face_detections(cv::Mat img, std
::vector<dlib::full_object_detection> fs) { int i, j; for(j=0; j<fs.size(); j++) { cv::Point p1, p2; for(i = 0; i<67; i++) { // 下巴到臉頰 0 ~ 16 //左邊眉毛 17 ~ 21 //右邊眉毛 21 ~ 26 //鼻樑 27 ~ 30 //鼻孔 31 ~ 35
//左眼 36 ~ 41 //右眼 42 ~ 47 //嘴脣外圈 48 ~ 59 //嘴脣內圈 59 ~ 67 switch(i) { case 16: case 21: case 26: case 30: case 35: case 41: case 47: case 59: i++; break; default: break; } p1.x = fs[j].part(i).x(); p1.y = fs[j].part(i).y(); p2.x = fs[j].part(i+1).x(); p2.y = fs[j].part(i+1).y(); cv::line(img, p1, p2, cv::Scalar(0,0,255), 2, 4, 0); } } } int main(int argc, char *argv[]) { if(argc != 2) { std::cout<< "you should specified a picture!"<<std::endl; return 0; } cv::Mat frame = cv::imread(argv[1]); cv::Mat dst; //提取灰度圖 cv::cvtColor(frame, dst, CV_BGR2GRAY); //載入dlib的人臉識別器 dlib::frontal_face_detector detector = dlib::get_frontal_face_detector(); //載入人臉形狀探測器 dlib::shape_predictor sp; dlib::deserialize("./shape_predictor_68_face_landmarks.dat") >> sp; //Mat轉化為dlib的matrix dlib::array2d<dlib::bgr_pixel> dimg; dlib::assign_image(dimg, dlib::cv_image<uchar>(dst)); //獲取一系列人臉所在區域 std::vector<dlib::rectangle> dets = detector(dimg); std::cout << "Number of faces detected: " << dets.size() << std::endl; if (dets.size() == 0) return 0; //獲取人臉特徵點分佈 std::vector<dlib::full_object_detection> shapes; int i = 0; for(i = 0; i < dets.size(); i++) { dlib::full_object_detection shape = sp(dimg, dets[i]); //獲取指定一個區域的人臉形狀 shapes.push_back(shape); } //指出每個檢測到的人臉的位置 for(i=0; i<dets.size(); i++) { //畫出人臉所在區域 cv::Rect r; r.x = dets[i].left(); r.y = dets[i].top(); r.width = dets[i].width(); r.height = dets[i].height(); cv::rectangle(frame, r, cv::Scalar(0, 0, 255), 1, 1, 0); } line_one_face_detections(frame, shapes); cv::imshow("frame", frame); cv::waitKey(0); return 0; }

效果:
原圖
人臉識別效果