dlib+vs2013+opencv实现人脸特征点检测
刷知乎的時(shí)候發(fā)現(xiàn)dlib做特征點(diǎn)檢測(cè)和人臉識(shí)別的效果都好于OpenCV,就想著動(dòng)手玩一下。沒(méi)想到也是遇坑重重。
首先,在官網(wǎng) install命令和setup.py文件進(jìn)行安裝時(shí)報(bào)錯(cuò),先是報(bào)錯(cuò)cmake沒(méi)有找到,添加了環(huán)境變量之后仍然報(bào)錯(cuò)c++11需要在vs2015下才能運(yùn)行。后來(lái)找到的資料也說(shuō)明了要想在vs2013下開(kāi)發(fā)需要安裝較早的版本。不想再重新安裝vs了,可是官網(wǎng)也找不到早期的dlib版本,幸好有人做了匯總。下載了18.17版本,發(fā)現(xiàn)文件夾中沒(méi)有setup文件,這時(shí)應(yīng)該還需要cmake進(jìn)行編譯。
Cmake編譯已經(jīng)很熟悉了,選擇編譯的源文件和生成文件的目的地址,目的地址可以選擇dlib主目錄下新建的文件夾。第一步是configuration,要選擇和自己vs版本對(duì)應(yīng)的配置。Vs2013win32就選擇visual studio 12 2013 (沒(méi)有ARM)。下一步generation,然后就可以打開(kāi)sln或者open project了。
然后就是新建c++工程,配置包含目錄、庫(kù)目錄、附加依賴項(xiàng)。Vs2013預(yù)編譯頭已經(jīng)包含了stdafx.h,不必在cpp文件中重新包含,否則會(huì)報(bào)錯(cuò)。期間遇到了LNK2019: 無(wú)法解析的外部符號(hào)的問(wèn)題,不用說(shuō),鏈接庫(kù)肯定沒(méi)添加對(duì)。錯(cuò)誤各有各的錯(cuò)法,我遇到的是在cmake的時(shí)候就出錯(cuò)了:configuration應(yīng)該選擇和自己vs平臺(tái)一樣的,我的是vs2013win32版的,卻選擇了win64,后來(lái)改成arm還是不對(duì),只能是下圖中所選的。
這下編譯終于通過(guò)了,但是在讀入shape_predictor_5_face_landmarks.dat中就異常中斷了,中斷處的代碼顯示是未能正確打開(kāi)文件。郁悶了半天才意識(shí)到應(yīng)該是路徑中有中文連接符號(hào)-。把文件放到工作目錄就解決問(wèn)題了。
可以看到程序已經(jīng)實(shí)現(xiàn)了在圖像中檢測(cè)人臉位置并將人臉中標(biāo)志性的符號(hào)(如眼角,嘴角)標(biāo)記出來(lái),可以根據(jù)這些標(biāo)志信息進(jìn)一步知道人臉的表情信息(或者說(shuō)動(dòng)作pose)。實(shí)現(xiàn)人臉位置檢測(cè)的是frontal_face_detector,實(shí)現(xiàn)標(biāo)志提取的是shape_predictor,前者使用傳統(tǒng)的HOG特征和線性分類(lèi)器、圖像金字塔、滑窗實(shí)現(xiàn),后者通過(guò)根據(jù)2014年的一篇CVPR文章訓(xùn)練好的網(wǎng)絡(luò)模型實(shí)現(xiàn)。在網(wǎng)上可以找到兩個(gè)模型,一個(gè)可以找出68個(gè)人臉中的特征點(diǎn),一個(gè)可以找到5個(gè)特征點(diǎn)。更換對(duì)應(yīng)的.dat文件就可以實(shí)現(xiàn),當(dāng)然特征點(diǎn)更少時(shí)耗時(shí)更少。
P.s 更改模型文件后要記得更改繪制特征點(diǎn)圓圈的for循環(huán)中的循環(huán)次數(shù),不然會(huì)溢出中斷。
在這里的代碼中使用了OPenCV實(shí)現(xiàn)圖像導(dǎo)入和最后的顯示和保存,在官網(wǎng)提供的例子中,可以全部使用dlib庫(kù)完成。
/*dlib::deserialize("D:\\program\Anaconda2\\Tools\dlib-18.17\\shape_predictor_68_face_landmarks.dat") >> pose_model;cv::Mat img = imread("D:\\program\Anaconda2\\Tools\dlib-18.17\\zkaj.jpg", 1);*/ #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{// Load face detection and pose estimation models. frontal_face_detector detector = get_frontal_face_detector();//正臉檢測(cè)器,得到人臉的邊界框//檢測(cè)器使用經(jīng)典的HOG特征和線性分類(lèi)器,圖像金字塔和滑窗完成shape_predictor pose_model;//shape_predictor用于預(yù)測(cè)臉上標(biāo)志的位置deserialize("shape_predictor_68_face_landmarks.dat") >> pose_model;//讀取已經(jīng)訓(xùn)練好的模型,在 iBUG 300-W人臉數(shù)據(jù)集(禁止商用)上訓(xùn)練得到 http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2.// Grab and process frames until the main window is closed by the user. // Grab a frame cv::Mat temp;//cap >> temp; temp = cv::imread("timg.jpg", 1);//cv::VideoCapture cap(0);也可以從攝像頭獲取當(dāng)前畫(huà)面cv_image<bgr_pixel> cimg(temp);//拷貝賦值 dlib的圖像格式是array2d// Detect faces std::vector<rectangle> faces = detector(cimg);// Find the pose of each face. std::vector<full_object_detection> shapes;//用于存放特征點(diǎn)的容器for (unsigned long i = 0; i < faces.size(); ++i)shapes.push_back(pose_model(cimg, faces[i]));//68個(gè)點(diǎn)組成人臉poseif (!shapes.empty()){for (int j = 0; j < shapes.size(); j++)//遍歷每個(gè)檢測(cè)到的人臉{for (int i = 0; i < 68; i++)//遍歷每個(gè)人臉的68個(gè)特征點(diǎn){circle(temp, cvPoint(shapes[j].part(i).x(), shapes[j].part(i).y()), 3, cv::Scalar(0, 0, 255), -1);//半徑是3,顏色是紅色。-1表示圓被填充putText(temp, to_string(i), cvPoint(shapes[j].part(i).x(), shapes[j].part(i).y()), CV_FONT_HERSHEY_PLAIN, 1, cv::Scalar(255, 0, 0), 1, 4);//線條寬度是1,字形是4鄰域。to_string將int轉(zhuǎn)為string,這是c++11新添加的}}}//Display it all on the screen imshow("Dlib特征點(diǎn)", temp);imwrite("Dlib特征點(diǎn)1.jpg", temp);cv::waitKey(0);}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;}}Python接口的配置
直接下載安裝包更方便。dlib · PyPI注意還是要選擇和自己python版本和機(jī)器相符合的安裝包。通過(guò)命令pip install dlib-18.17.100-cp35-none-win_amd64.whl進(jìn)行安裝。我遇到的問(wèn)題是pip版本不夠高,使用python -m pip install --upgrade pip進(jìn)行升級(jí)。總是弄不清楚到底進(jìn)不進(jìn)入python命令行,現(xiàn)在看來(lái)看來(lái)命令行中含python的就可以直接在cmd中執(zhí)行。Pip也是直接在cmd中執(zhí)行。
但是在pycharmn中的python版本是anaconda(python2.7),沒(méi)有安裝opencv。在https://www.lfd.uci.edu/~gohlke/pythonlibs/#numpy中找到了opencv的安裝包。
使用pip install命令安裝opencv,注意應(yīng)該將D:\Anaconda3\Scripts(這是我電腦的安裝目錄)加入到環(huán)境變量,這樣就可以使用pip命令。
一切就緒以后以管理員身份運(yùn)行cmd或PowerShell。依次輸入以下命令:
pip install --upgrade setuptools
pip install opencv-python
雖然網(wǎng)絡(luò)還可以,順利下載成功,但是依然無(wú)法import。原來(lái)pip自動(dòng)下載也可能版本不對(duì),于是下載了whl安裝包(名字叫輪子?),再使用pip安裝。
然后又遇到了numpy無(wú)法導(dǎo)入的問(wèn)題,也是先卸載,重新安裝。conda remove numpy;conda install numpy。
最后一個(gè)問(wèn)題是cv2.rectangle的使用,我的opencv版本沒(méi)有cv2.LINE_AA這個(gè)參數(shù),注釋掉就好了。
反正就是一步步走,一個(gè)個(gè)解決問(wèn)題。終于看到了結(jié)果:
Reference:
總結(jié)
以上是生活随笔為你收集整理的dlib+vs2013+opencv实现人脸特征点检测的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 一篇文章搞懂数据仓库:常用ETL工具、方
- 下一篇: haar级联分类器--人脸检测和匹配