【opencv】示例-dbt_face_detection.cpp 使用级联分类器进行人脸检测

c2fa8b19abddd85a1997b9bc59a553af.png

data/lbpcascades/lbpcascade_frontalface.xml

fe4316656ec4504729c975106c15f549.png

data/haarcascades/haarcascade_frontalface_alt.xml

49afd366e4b99903662e806a2477c638.png

// 这是一段条件编译代码,只有在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);

68c21725aa8b722b7fd1adecdedc21fa.png

b02d243ffa8969c719de957a399fc5e9.png

DetectionBasedTracker Detector(MainDetector, TrackingDetector, params);

0f4bd7dce17c9d55efd4023820b47bdc.png

  • 9
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值