lihuifei 2020-05-04
人脸识别是图像处理与OpenCV非常重要的应用之一,opencv官方专门有教程和代码讲解其实现方法。此示例程序就是使用objdetect模块检测摄像头视频流中的人脸,位于...\opencv\sources\samples\cpp\tutorial_code\objectDetection路径之下。需要注意的是,要将“...\opencv\sources\data\haarcascades”路径下的haarcascade_eye_tree_eyeglasses.xml和haarcascade_frontalface_alt.xml文件复制到和源文件同一目录中,才能正确运行。运行程序,将自己的脸对准摄像头,或者放置一张照片对准摄像头任其捕获,便可以发现程序准确地识别除了人脸,并用彩色的圆将脸圈出。
//--------------------------------------【程序说明】------------------------------------------- // 程序说明:《OpenCV3编程入门》OpenCV2版书本配套示例程序11 // 程序描述:来自OpenCV安装目录下Samples文件夹中的官方示例程序-人脸识别 // 开发测试所用操作系统: Windows 7 64bit // 开发测试所用IDE版本:Visual Studio 2010 // 开发测试所用OpenCV版本: 2.4.9 // 2014年11月 Revised by @浅墨_毛星云 //------------------------------------------------------------------------------------------------ /** * @file ObjectDetection.cpp * @author A. Huaman ( based in the classic facedetect.cpp in samples/c ) * @brief A simplified version of facedetect.cpp, show how to load a cascade classifier and how to find objects (Face + eyes) in a video stream */ //---------------------------------【头文件、命名空间包含部分】---------------------------- // 描述:包含程序所使用的头文件和命名空间 //------------------------------------------------------------------------------------------------- #include "opencv2/objdetect/objdetect.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <stdio.h> using namespace std; using namespace cv; void detectAndDisplay(Mat frame); //--------------------------------【全局变量声明】---------------------------------------------- // 描述:声明全局变量 //------------------------------------------------------------------------------------------------- //注意,需要把"haarcascade_frontalface_alt.xml"和"haarcascade_eye_tree_eyeglasses.xml"这两个文件复制到工程路径下 String face_cascade_name = "haarcascade_frontalface_alt.xml"; String eyes_cascade_name = "haarcascade_eye_tree_eyeglasses.xml"; CascadeClassifier face_cascade; CascadeClassifier eyes_cascade; string window_name = "Capture - Face detection"; RNG rng(12345); //--------------------------------【help( )函数】---------------------------------------------- // 描述:输出帮助信息 //------------------------------------------------------------------------------------------------- static void ShowHelpText() { //输出欢迎信息和OpenCV版本 cout << "\n\n\t\t\t非常感谢购买《OpenCV3编程入门》一书!\n" << "\n\n\t\t\t此为本书OpenCV2版的第11个配套示例程序\n" << "\n\n\t\t\t 当前使用的OpenCV版本为:" << CV_VERSION << "\n\n ----------------------------------------------------------------------------"; } //-----------------------------------【main( )函数】-------------------------------------------- // 描述:控制台应用程序的入口函数,我们的程序从这里开始 //------------------------------------------------------------------------------------------------- int main(void) { VideoCapture capture; Mat frame; //-- 1. 加载级联(cascades) if (!face_cascade.load(face_cascade_name)){ printf("--(!)Error loading\n"); return -1; }; if (!eyes_cascade.load(eyes_cascade_name)){ printf("--(!)Error loading\n"); return -1; }; //-- 2. 读取视频 capture.open(0); ShowHelpText(); if (capture.isOpened()) { for (;;) { capture >> frame; //-- 3. 对当前帧使用分类器(Apply the classifier to the frame) if (!frame.empty()) { detectAndDisplay(frame); } else { printf(" --(!) No captured frame -- Break!"); break; } int c = waitKey(10); if ((char)c == ‘c‘) { break; } } } return 0; } void detectAndDisplay(Mat frame) { std::vector<Rect> faces; Mat frame_gray; cvtColor(frame, frame_gray, COLOR_BGR2GRAY); equalizeHist(frame_gray, frame_gray); //-- 人脸检测 face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(30, 30)); for (size_t i = 0; i < faces.size(); i++) { Point center(faces[i].x + faces[i].width / 2, faces[i].y + faces[i].height / 2); ellipse(frame, center, Size(faces[i].width / 2, faces[i].height / 2), 0, 0, 360, Scalar(255, 0, 255), 2, 8, 0); Mat faceROI = frame_gray(faces[i]); std::vector<Rect> eyes; //-- 在脸中检测眼睛 eyes_cascade.detectMultiScale(faceROI, eyes, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(30, 30)); for (size_t j = 0; j < eyes.size(); j++) { Point eye_center(faces[i].x + eyes[j].x + eyes[j].width / 2, faces[i].y + eyes[j].y + eyes[j].height / 2); int radius = cvRound((eyes[j].width + eyes[j].height)*0.25); circle(frame, eye_center, radius, Scalar(255, 0, 0), 3, 8, 0); } } //-- 显示最终效果图 imshow(window_name, frame); }