data/lbpcascades/lbpcascade_frontalface.xml
data/haarcascades/haarcascade_frontalface_alt.xml
// 这是一段条件编译代码,只有在Linux、苹果系统、安卓系统或者是Visual Studio 2013及以上版本的环境下才会编译。
#if defined(__linux__) || defined(LINUX) || defined(__APPLE__) || defined(ANDROID) || (defined(_MSC_VER) && _MSC_VER>=1800)
// 包括OpenCV库的不同模块的头文件。
#include <opencv2/imgproc.hpp> // 高斯模糊
#include <opencv2/core.hpp> // OpenCV基础结构 (cv::Mat, Scalar)
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp> // OpenCV窗口输入输出
#include <opencv2/features2d.hpp>
#include <opencv2/objdetect.hpp>
#include <stdio.h>
// 使用std和cv名称空间中的元素,避免名称冲突。
using namespace std;
using namespace cv;
// 定义一个常量字符串,用于窗口的名字。
const string WindowName = "Face Detection example";
// 定义一个CascadeDetectorAdapter类,继承于DetectionBasedTracker::IDetector
class CascadeDetectorAdapter: public DetectionBasedTracker::IDetector
{
public:
// 构造函数,接受一个OpenCV中的CascadeClassifier智能指针作为参数。
CascadeDetectorAdapter(cv::Ptr<cv::CascadeClassifier> detector):
IDetector(),
Detector(detector)
{
// 断言,确保传入的detector参数是有效的。
CV_Assert(detector);
}
// 定义detect函数,用于检测图像中的对象。
void detect(const cv::Mat &Image, std::vector<cv::Rect> &objects) CV_OVERRIDE
{
// 使用CascadeClassifier的detectMultiScale方法进行多尺度检测。
Detector->detectMultiScale(Image, objects, scaleFactor, minNeighbours, 0, minObjSize, maxObjSize);
}
// 虚析构函数,当CascadeDetectorAdapter对象被销毁时调用。
virtual ~CascadeDetectorAdapter() CV_OVERRIDE
{}
private:
// 默认构造函数是私有的,这样就不能在类外部无参构造CascadeDetectorAdapter对象。
CascadeDetectorAdapter();
// 一个CascadeClassifier智能指针,用于检测对象。
cv::Ptr<cv::CascadeClassifier> Detector;
};
// 主函数
int main(int , char** )
{
// 创建一个名为Face Detection example的窗口。
namedWindow(WindowName);
// 创建一个VideoCapture对象,用于从摄像头捕获视频流。
VideoCapture VideoStream(0);
// 如果无法打开视频流,则打印错误信息并返回1。
if (!VideoStream.isOpened())
{
printf("Error: Cannot open video stream from camera\n");
return 1;
}
// 从预设的数据路径查找面部识别分类器文件,并创建一个CascadeClassifier对象。
std::string cascadeFrontalfilename = samples::findFile("data/lbpcascades/lbpcascade_frontalface.xml");
cv::Ptr<cv::CascadeClassifier> cascade = makePtr<cv::CascadeClassifier>(cascadeFrontalfilename);
// 使用CascadeClassifier创建一个CascadeDetectorAdapter对象。
cv::Ptr<DetectionBasedTracker::IDetector> MainDetector = makePtr<CascadeDetectorAdapter>(cascade);
// 确保分类器文件加载成功。
if ( cascade->empty() )
{
printf("Error: Cannot load %s\n", cascadeFrontalfilename.c_str());
return 2;
}
// 再次加载面部识别分类器文件。
cascade = makePtr<cv::CascadeClassifier>(cascadeFrontalfilename);
// 使用CascadeClassifier创建另一个CascadeDetectorAdapter作为追踪检测器。
cv::Ptr<DetectionBasedTracker::IDetector> TrackingDetector = makePtr<CascadeDetectorAdapter>(cascade);
// 确保分类器文件再次加载成功。
if ( cascade->empty() )
{
printf("Error: Cannot load %s\n", cascadeFrontalfilename.c_str());
return 2;
}
// 创建DetectionBasedTracker对象的参数。
DetectionBasedTracker::Parameters params;
// 创建一个DetectionBasedTracker对象,用于人脸跟踪。
DetectionBasedTracker Detector(MainDetector, TrackingDetector, params);
// 初始化检测器,如果失败,则打印错误信息并返回2。
if (!Detector.run())
{
printf("Error: Detector initialization failed\n");
return 2;
}
// 创建用于存储帧的矩阵对象。
Mat ReferenceFrame;
Mat GrayFrame;
vector<Rect> Faces;
do
{
// 从视频流中捕获一帧。
VideoStream >> ReferenceFrame;
// 将捕获的帧转换为灰度图像。
cvtColor(ReferenceFrame, GrayFrame, COLOR_BGR2GRAY);
// 对灰度图像进行处理。
Detector.process(GrayFrame);
// 获取检测到的人脸对象的向量。
Detector.getObjects(Faces);
// 对于每个检测到的人脸,绘制矩形框。
for (size_t i = 0; i < Faces.size(); i++)
{
rectangle(ReferenceFrame, Faces[i], Scalar(0,255,0));
}
// 在名为Face Detection example的窗口中显示带有矩形框的人脸。
imshow(WindowName, ReferenceFrame);
// 当按键小于0(即没有按键),继续循环。
} while (waitKey(30) < 0);
// 停止检测器。
Detector.stop();
// 主程序正常结束。
return 0;
}
// 当不是在上述定义的系统环境时,执行以下代码。
#else
#include <stdio.h>
// 主函数
int main()
{
// 打印提示信息,表明此代码只能在特定系统环境下运行。
printf("This sample works for UNIX or ANDROID or Visual Studio 2013+ only\n");
return 0;
}
// 结束条件编译代码。
#endif
这段代码是一个使用OpenCV进行面部检测的C++程序,仅在UNIX、安卓或Visual Studio 2013+ 环境下运行。它首先定义了一个CascadeDetectorAdapter用于封装OpenCV的CascadeClassifier,便于进行面部检测。主函数创建了视频捕获对象用于从摄像头读取视频帧,加载了面部检测的分类器文件,并初始化了Detector对象。程序进入一个循环,持续捕捉视频帧,将其转换为灰度图像,并利用面部检测器侦测和标记人脸。对于不支持的环境,程序会打印出相应的消息。
Detector->detectMultiScale(Image, objects, scaleFactor, minNeighbours, 0, minObjSize, maxObjSize);
DetectionBasedTracker Detector(MainDetector, TrackingDetector, params);