基于OpenCV读取摄像头实现单个人脸验证MFC程序

yizhihongxing

我们来详细讲解一下“基于OpenCV读取摄像头实现单个人脸验证MFC程序”的完整攻略。

1. 确定开发环境

首先,确定使用的开发环境和所需的库文件。本攻略选用以下开发环境:

  • Windows 10 操作系统
  • Visual Studio 2017 集成开发环境
  • OpenCV 4.0.0 库文件

2. 创建MFC项目

接下来,创建一个MFC项目。在Visual Studio中选择“文件” > “新建” > “项目”,在弹出的“新建项目”对话框中选择“MFC应用程序”类型,填写项目名称和保存路径等信息,最后点击“确定”按钮即可。

3. 配置OpenCV库

在创建好MFC项目后,我们需要将OpenCV库文件添加到项目中。

  1. 下载OpenCV 4.0.0库文件,并解压到本地任意目录下。

  2. 在Visual Studio中,选择“项目” > “属性” > “VC++目录”,在“包含目录”中添加解压后的OpenCV库文件夹路径(如:D:\opencv\build\include),并在“库目录”中添加OpenCV库文件夹路径下lib文件夹的路径(如:D:\opencv\build\x64\vc14\lib)。

  3. 在“链接器” > “输入”中,添加需要链接的OpenCV库文件名称,包括opencv_world400.lib和opencv_world400d.lib两个文件(其中400表示OpenCV版本号),并在“忽略特定库”中添加“libcmt.lib”库。

4. 编写MFC程序

接下来,我们就可以开始编写MFC程序实现基于OpenCV读取摄像头实现单个人脸验证了。首先,在主界面上创建一个画布,用来显示摄像头捕获的画面。

// MFC程序主界面类
class CMyCameraDlg : public CDialogEx
{
public:
    CMyCameraDlg(CWnd* pParent = nullptr);    // 标准构造函数

// 对话框数据
#ifdef AFX_DESIGN_TIME
    enum { IDD = IDD_MYCAMERA_DIALOG };
#endif

protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现
protected:
    HICON m_hIcon;

    // 用于OpenCV读取摄像头
    cv::VideoCapture m_cap;

    // 显示画面的画布
    CStatic m_frame;

    // 确定ROI区域
    cv::Rect m_roi;
    bool m_draw = false;

    virtual BOOL OnInitDialog();
    afx_msg void OnPaint();
    afx_msg HCURSOR OnQueryDragIcon();
    DECLARE_MESSAGE_MAP()
};

接着,在OnInitDialog函数中,初始化摄像头和画布,并启动摄像头刷新线程循环读取画面,并通过opencv检测人脸,并选取ROI区域。

BOOL CMyCameraDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();

    // 初始化图标
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    SetIcon(m_hIcon, TRUE);
    SetIcon(m_hIcon, FALSE);

    // 初始化画布
    m_frame.Attach(GetDlgItem(IDC_FRAME)->GetSafeHwnd());

    // 初始化摄像头
    m_cap.open(0);
    if (!m_cap.isOpened())
        AfxMessageBox(_T("无法打开摄像头!"));
    else
    {
        // 启动摄像头线程
        AfxBeginThread(CMyCameraDlg::ThreadProc, this, THREAD_PRIORITY_NORMAL);
    }

    return TRUE;  // 返回 TRUE 以便进行聚焦设置
}

UINT CMyCameraDlg::ThreadProc(LPVOID lParam)
{
    CMyCameraDlg* dlg = (CMyCameraDlg*)lParam;

    cv::Mat frame;
    cv::Mat gray;

    // 调整摄像头分辨率
    dlg->m_cap.set(cv::CAP_PROP_FRAME_WIDTH, 320);
    dlg->m_cap.set(cv::CAP_PROP_FRAME_HEIGHT, 240);

    // 读取画面并进行处理
    while (1)
    {
        dlg->m_cap.read(frame);
        if (frame.empty())
            break;

        // 转为灰度图
        cv::cvtColor(frame, gray, cv::COLOR_BGR2GRAY);

        // 检测人脸,选取ROI区域
        if (dlg->m_draw)
        {
            cv::rectangle(frame, dlg->m_roi, cv::Scalar(0, 0, 255), 2);
            gray(dlg->m_roi).copyTo(gray);
        }

        // 将检测到的图像显示到画面上
        dlg->m_frame.SetBitmap(dlg->Mat2Bitmap(frame));
    }

    return 0;
}

通过以上代码,我们已经可以成功读取摄像头并在画面上实时显示了。接下来,我们添加单个人脸验证的代码。

void CMyCameraDlg::OnPaint()
{
    if (IsIconic())
    {
        CPaintDC dc(this); // 用于绘制的设备上下文

        SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

        // 缩小图标到客户区矩形中心。
        int cxIcon = GetSystemMetrics(SM_CXICON);
        int cyIcon = GetSystemMetrics(SM_CYICON);
        CRect rect;
        GetClientRect(&rect);
        int x = (rect.Width() - cxIcon + 1) / 2;
        int y = (rect.Height() - cyIcon + 1) / 2;

        // 绘制图标
        dc.DrawIcon(x, y, m_hIcon);
    }
    else
    {
        CDialogEx::OnPaint();

        // 在画面上显示检测结果
        CString strResult = DetectFace()?_T("验证通过"):_T("验证失败");
        CClientDC dc(&m_frame);
        dc.TextOutW(10, 10, strResult);
    }
}

最后,我们需要实现通过OpenCV检测人脸,并采用人脸关键点识别和模板匹配进行单个人脸验证的功能。

// 通过OpenCV检测人脸,并进行人脸关键点识别和模板匹配进行单个人脸验证
bool CMyCameraDlg::DetectFace()
{
    cv::Mat frame;
    cv::Mat gray;
    cv::Mat face;

    // 读取画面
    m_cap.read(frame);
    if (frame.empty())
        return false;

    // 转为灰度图
    cv::cvtColor(frame, gray, cv::COLOR_BGR2GRAY);

    // 检测人脸
    std::vector<cv::Rect> faces;
    m_faceCascade.detectMultiScale(gray, faces, 1.1, 3, 0, cv::Size(30, 30), cv::Size(200, 200));

    // 如果检测到多个人脸或没有检测到人脸则返回false
    if (faces.size() != 1)
        return false;

    // 保存人脸ROI区域并进行人脸关键点识别
    cv::Point2f src[4], dst[4];
    src[0] = cv::Point2f(faces[0].x, faces[0].y);
    src[1] = cv::Point2f(faces[0].x + faces[0].width, faces[0].y);
    src[2] = cv::Point2f(faces[0].x, faces[0].y + faces[0].height);
    src[3] = cv::Point2f(faces[0].x + faces[0].width, faces[0].y + faces[0].height);
    dst[0] = cv::Point2f(0, 0);
    dst[1] = cv::Point2f(70, 0);
    dst[2] = cv::Point2f(0, 90);
    dst[3] = cv::Point2f(70, 90);
    cv::Mat map_matrix = cv::getPerspectiveTransform(src, dst);
    cv::warpPerspective(gray, face, map_matrix, cv::Size(70, 90));
    std::vector<cv::Point2f> landmarks = m_landmarkDetector.Detect(face);

    // 通过模板匹配确定是否为指定人脸
    cv::Mat feature = m_featureExtractor.Extract(face, landmarks);
    double distance = m_faceDatabase.CalcDistance(feature, m_specifiedFaceFeature);
    return distance < m_threshold;
}

以上就是基于OpenCV读取摄像头实现单个人脸验证MFC程序的完整攻略。其中,我们通过OpenCV读取摄像头并实时显示画面,并采用人脸关键点识别和模板匹配进行单个人脸验证的功能。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:基于OpenCV读取摄像头实现单个人脸验证MFC程序 - Python技术站

(0)
上一篇 2023年5月25日
下一篇 2023年5月25日

相关文章

  • PHP swoole中使用task进程异步的处理耗时任务应用案例分析

    【攻略】PHP swoole中使用task进程异步的处理耗时任务应用案例分析 什么是PHP swoole task进程 swoole是一款支持高并发、异步、协程的PHP网络编程框架。而swoole中的task进程是指同步执行完毕后,再进行异步处理的一种进程。可以看作是PHP中的后台异步任务处理进程。 task进程的用途 task进程通常用于那些需要执行时间较…

    人工智能概览 2023年5月25日
    00
  • python实现的接收邮件功能示例【基于网易POP3服务器】

    下面是“Python实现接收邮件功能示例【基于网易POP3服务器】”的完整攻略: 概述 本示例基于Python编程语言,使用网易POP3服务器实现接收邮件的功能。接收邮件是指从指定的邮件服务器获取用户的电子邮件。本示例将通过Python程序,登录网易邮箱的POP3服务器,获取并下载指定的邮件,最后在本地查看邮件内容。 准备工作 在进行此示例前,你需要先完成以…

    人工智能概论 2023年5月25日
    00
  • 联想拯救者Y9000P 2022款值得入手吗 联想拯救者Y9000P 2022游戏本深度评测

    联想拯救者Y9000P 2022款的评测 一、外观设计 联想拯救者Y9000P 2022款采用了与上一代相同的黑色金属机身,看起来非常稳重、沉稳。机身采用了镜面印花技术和雾面工艺,让整体外观更加细腻,而且不容易留下指纹和污渍。键盘背光也经过了升级,按下键盘之后的反馈更加顺畅,手感更加舒适。 另外,拯救者Y9000P 2022款还加入了最新的2.5K OLED…

    人工智能概览 2023年5月25日
    00
  • Django3.2 自动发现所有路由代码详解

    关于“Django3.2 自动发现所有路由代码详解”的完整攻略,我会在下面进行详细的讲解。具体过程如下: 1. 理解自动发现路由 在 Django 3.2 中,自动发现路由是一个新的特性。它可以让开发者方便地在模块之间共享路由信息,而无需手动处理路由注册的过程。具体来说,它可以帮助 Django 自动地从各个应用程序文件中导入视图,并且自动地将这些视图与 U…

    人工智能概论 2023年5月25日
    00
  • Python集成开发环境Pycharm的使用及技巧

    Python集成开发环境Pycharm的使用及技巧 Pycharm是一款强大的Python集成开发环境,具有代码自动补全、调试、代码质量检查、版本控制等众多功能,提高了Python程序开发的效率。本文将为大家介绍使用Pycharm的基本操作和一些技巧,帮助大家更好地利用这款工具进行Python程序开发。 1. 安装和配置Pycharm 首先我们需要下载和安装…

    人工智能概览 2023年5月25日
    00
  • Nginx服务器上搭建图片缓存服务的基本配置解析

    以下是“Nginx服务器上搭建图片缓存服务的基本配置解析”的详细攻略。 1. 基本概念解析 Nginx服务器 Nginx是一款高性能的Web服务器,也可作为反向代理服务器、负载均衡服务器以及HTTP缓存服务器等使用。通过配置Nginx服务器,可实现对Web应用程序的代理、负载均衡、缓存加速等功能。 图片缓存服务 图片缓存服务指的是将图片缓存在服务器中,在用户…

    人工智能概览 2023年5月25日
    00
  • php 广告调用类代码(支持Flash调用)

    下面是详细讲解“php 广告调用类代码(支持Flash调用)”的完整攻略: 1. 代码介绍 这是一个基于 PHP 编写的广告调用类,支持调用图片、Flash 和 HTML 广告,适用于 PHP 网站开发。 该类封装了广告调用的功能,可以方便地在模板中调用广告,而不需要写重复的广告代码。除此之外,该类还具备缓存功能,可以减轻数据库和服务器的负担。 2. 使用步…

    人工智能概论 2023年5月25日
    00
  • java动态代理(jdk与cglib)详细解析

    Java动态代理(JDK与CGLIB)详细解析 什么是动态代理 代理模式是一种非常常见的设计模式,其核心思想是为其他对象提供一个代理对象来控制对这个对象的访问。静态代理必须手动编写代理类,而动态代理则是在运行期动态生成代理类。 JDK动态代理 JDK动态代理是Java官方提供的动态代理实现方式,它是基于反射机制实现的。JDK动态代理需要实现Invocatio…

    人工智能概览 2023年5月25日
    00
合作推广
合作推广
分享本页
返回顶部