Visual Studio 是微軟提供的面向任何開發者的同類最佳工具。
OpenCV(開源計算機視覺庫)是一個開源的計算機視覺和機器學習軟件庫。
目前最新版本:Visual Studio 2019、OpenCV 4.1.1
本文先介紹如何在本地計算機 Windows 7 x64 上安裝 OpenCV,然后介紹如何在 VS2019 中配置 OpenCV 開發環境,最后創建一個從圖片中提取人臉的 c++ 程序。
1、安裝 OpenCV
在官網下載你需要的 exe 版本(這里選擇的 opencv-4.1.1-vc14_vc15.exe),然后雙擊它(即安裝),實質就是解壓一下,解壓完出來一個文件夾(如:D:\Users\Downloads)。
解壓后的文件夾內容如下:
其中 build 是 OpenCV 使用時要用到的一些庫文件,而 sources 中則是 OpenCV 官方為我們提供的一些 demo 示例源碼。
(說明:如果要在未安裝 OpenCV 的機器上運行調用了 OpenCV 接口的程序,只需把 OpenCV 安裝目錄下把相應的 lib 文件復制到程序運行目錄下即可,類似 MFC 程序的部署。如:D:\Users\Downloads\opencv\build\x64\vc15\lib\opencv_world411.dll)
最后依次選擇計算機—>屬性—>高級系統設置—>環境變量,找到Path變量,選中並點擊編輯,添加 D:\Users\Downloads\opencv\build\x64\vc15\bin;
現在搭建好了運行 OpenCV 程序的環境,接下來就結合 VS2019 來編寫需要的程序。(VS2019 的安裝步驟可以參考官網上的安裝說明,注意要選擇 c++ 模塊)
二、在 VS2019 中配置 OpenCV
1.添加空項目(c++)
右鍵點擊項目->添加->添加新項,選擇 main.cpp 文件,如下圖:
在視圖菜單中選擇其他窗口->屬性管理器,如下圖:
然后右擊 Debug | 64,選擇屬性,進行參數配置,如下圖:
首先配置包含目錄(即添加 OpenCV 頭文件所在的目錄),如果“計算的值”下面包含了以前的文件目錄,並需要刪除,可以先找到相應的配置文件,然后進行清理。
如:C:\Users\zhangsan\AppData\Local\Microsoft\MSBuild\v4.0\Microsoft.Cpp.x64.user.props
類似地配置好庫目錄,如下圖:
接下來還需配置鏈接器的依賴項(調試模式則選擇 opencv_world411d.lib,發布模式則選擇 opencv_world411.lib),如下圖:
其中的庫文件的位置在 OpenCV 的安裝目錄下:
三、從圖片中提取人臉的程序
#include <iostream> #include <opencv2/opencv.hpp> #include <opencv2/calib3d/calib3d.hpp> using namespace std; using namespace cv; int main() { String facefile = "D:\\Users\\wzl\\Downloads\\opencv\\build\\etc\\haarcascades\\haarcascade_frontalface_alt.xml"; String eyefile = "D:\\Users\\wzl\\Downloads\\opencv\\build\\etc\\haarcascades\\haarcascade_eye.xml"; Mat image, image_gray; //定義兩個Mat變量,用於存儲每一幀的圖像 image = imread("F:\\test.jpg"); //imshow("原圖", image); cvtColor(image, image_gray, COLOR_RGB2GRAY);//轉為灰度圖 equalizeHist(image_gray, image_gray);//直方圖均衡化,增加對比度方便處理 CascadeClassifier eye_Classifier; //載入分類器 CascadeClassifier face_cascade; //載入分類器 //加載分類訓練器,OpenCv官方文檔提供的xml文檔,可以直接調用 if (!eye_Classifier.load(eyefile)) //需要將xml文檔放在自己指定的路徑下 { cout << "Load haarcascade_eye.xml failed!" << endl; return 0; } if (!face_cascade.load(facefile)) { cout << "Load haarcascade_frontalface_alt failed!" << endl; return 0; } //vector 是個類模板 需要提供明確的模板實參 vector<Rect>則是個確定的類 模板的實例化 vector<Rect> eyeRect; vector<Rect> faceRect; //檢測關於眼睛部位位置 //eye_Classifier.detectMultiScale(image_gray, eyeRect, 1.1, 2, 0 | 1, Size(30, 30)); //for (size_t eyeIdx = 0; eyeIdx < eyeRect.size(); eyeIdx++) //{ // rectangle(image, eyeRect[eyeIdx], Scalar(0, 0, 255)); //用矩形畫出檢測到的位置 //} //檢測關於臉部位置 face_cascade.detectMultiScale(image_gray, faceRect, 1.1, 2, 0 | 1, Size(50, 50)); for (size_t i = 0; i < faceRect.size(); i++) { //用矩形畫出檢測到的位置(一個臉對應一個矩形框) rectangle(image, faceRect[i], Scalar(0, 0, 255)); //保存臉部圖片 Mat face = image(Rect(faceRect[i])); Mat faceLittle; resize(face, faceLittle, Size(100, 100)); Mat faceLittle_gray; cvtColor(faceLittle, faceLittle_gray, COLOR_RGB2GRAY);//轉為灰度圖 equalizeHist(faceLittle_gray, faceLittle_gray);//直方圖均衡化,增加對比度方便處理 imwrite("F:\\testface.jpg", faceLittle_gray); } imshow("人臉識別圖", image); //顯示當前幀 waitKey(0); }
以上程序的允許結果如下圖:
通過攝像機來提取人臉照片:
#include <opencv2/opencv.hpp> #include <opencv2/core.hpp> #include <opencv2/imgproc.hpp> #include <opencv2/highgui.hpp> #include <iostream> #include <string> #include <stdlib.h> using namespace std; using namespace cv; void faceDetect() { String facefile = "D:\\Users\\Downloads\\opencv\\build\\etc\\haarcascades\\haarcascade_frontalface_alt.xml"; //臉部識別分類器 CascadeClassifier faceCascader; if (!faceCascader.load(facefile)) { printf("無法加載臉部特征文件:%s", facefile); return; } namedWindow("攝像頭"); VideoCapture capture(0);//打開攝像頭 Mat frame; Mat gray; vector<Rect> faces; int sn = 0; //實時讀取攝像頭的圖像幀 while (capture.read(frame)) { cvtColor(frame, gray, COLOR_RGB2GRAY); equalizeHist(gray, gray); faceCascader.detectMultiScale(gray, faces, 1.2, 3, 0, Size(30, 30)); for (size_t faceSize = 0; faceSize < faces.size(); faceSize++) { Rect roi; roi.x = faces[static_cast<int>(faceSize)].x; roi.y = faces[static_cast<int>(faceSize)].y; roi.width = faces[static_cast<int>(faceSize)].width; roi.height = faces[static_cast<int>(faceSize)].height; Mat faceROI = frame(roi); //在人臉區域畫一個矩形 rectangle(frame, faces[static_cast<int>(faceSize)], Scalar(0, 0, 255), 2, 8, 0); sn++; //將sn整型值轉為字符串 stringstream stream; stream << sn; //生產一個新的文件名 String snStr = "F:\\testface\\img-" + stream.str() + ".jpg"; cout << snStr << endl; imwrite(snStr, faceROI); } imshow("攝像頭", frame); //必須加時延,否則無法顯示圖像 char key = waitKey(30); //按ESC鍵退出 if (key == 27) { break; } } }