QT实现人脸识别

news2024/11/18 7:34:10

QT实现人脸识别

Face.pro文件:

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    widget.cpp

HEADERS += \
    widget.h

FORMS += \
    widget.ui

INCLUDEPATH += D:/opencv/opencv3.4-qt-intall/install/include
INCLUDEPATH += D:/opencv/opencv3.4-qt-intall/install/include/opencv
INCLUDEPATH += D:/opencv/opencv3.4-qt-intall/install/include/opencv2
LIBS += D:/opencv/opencv3.4-qt-intall/install/x86/mingw/lib/libopencv_*.a

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

 widget.h文件:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QWidget>
#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
#include<opencv2/face.hpp>
#include <vector>
#include <map>
#include <QMessageBox>
#include <QDebug>
#include <QFile>
#include <QTextStream>
#include <QDateTime>
#include <QTimerEvent>
#include<QtSerialPort/QtSerialPort>
#include<QtSerialPort/QSerialPortInfo>
using namespace  cv;
using namespace cv::face;
using namespace std;

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void on_openBtn_clicked();

    void on_closeBtn_clicked();

    void on_faceBtn_clicked();

private:
    Ui::Widget *ui;

    //=========摄像头相关成员的设置=========
    VideoCapture v; //摄像头容器
    Mat src; //存放  原图  的容器
    Mat gray; //存放  灰度图  的容器
    Mat dst; //存放  直方图  的容器
    Mat rgb; //存放  rgb图  的容器
    CascadeClassifier c; //定义一个级联分类器容器
    vector<Rect> faces; // 定义一个数组存放人脸矩形框
    int camera_id; //打开摄像头的定时器id
    void timerEvent(QTimerEvent *e); //定时器事件  重写函数事件声明

    //=========人脸录入相关成员的设置=========
    Ptr<LBPHFaceRecognizer> recognizer; //人脸  识别器指针
    vector<Mat> study_faces; //定义一个存放录入人脸的数组
    vector<int> study_lables; //定义一个存放人脸对应的标签数组
    int count; //记录录入人脸的次数
    int flag; //用来区别是人脸录入还是人脸识别
    int face_id; // 人脸录入定时器id

    //=========人脸检测相关成员的设置=========
    int check_id; //

};
#endif // WIDGET_H

widget.cpp文件:

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    ui->weChatBtn->setEnabled(false);

    //打开系统摄像头
    if(!v.open(0))
    {
        QMessageBox::information(this, "", "打开系统摄像头失败!");
        return;
    }

    //配置  级联分类器
    if(!c.load("D:\\opencv\\image\\haarcascade_frontalface_alt.xml"))
    {
        QMessageBox::information(this, "", "配置级联分类器失败!");
        return;
    }

    //判断是否录入过人脸
    QFile file("D:\\opencv\\image\\my_face.xml");
    //判断文件是否存在
    if(file.exists())
    {
        //表示之前录入过人脸  则下载文件
        recognizer = LBPHFaceRecognizer::load<LBPHFaceRecognizer>("D:\\opencv\\image\\my_face.xml");

    }else {
        //表示之前没有录入过人脸
        recognizer = LBPHFaceRecognizer::create();
    }

    //启动一个人脸检测定时器
    check_id = startTimer(3000);
    flag = 1; //可以人脸检测
    recognizer->setThreshold(100);

}

Widget::~Widget()
{
    delete ui;
}

//打开摄像头按钮对应的  槽函数
void Widget::on_openBtn_clicked()
{
    //启动一个定时器
    camera_id = startTimer(30);
}

//定时器重写的功能函数
void Widget::timerEvent(QTimerEvent *e)
{
    //判断是否是  摄像头定时器  超时
    if(e->timerId() == camera_id)
    {
        //读取系统摄像头中的图像
        v.read(src);

        //图像反转
        flip(src, src, 1);

        //将 bgr 转换成  rgb
        cvtColor(src, rgb, CV_BGR2RGB);

        //将图像重新设置大小  适应lab
        cv::resize(rgb, rgb, Size(301,251));

        //灰度处理
        cvtColor(rgb, gray, CV_RGB2GRAY);

        //均衡化处理
        equalizeHist(gray, dst);

        //锁定人脸矩形框位置
        c.detectMultiScale(dst, faces);

        //将矩形框绘制到人脸上
        for(uint i=0; i<faces.size(); i++)
        {
            rectangle(rgb, faces[i], Scalar(255,0,0),2);
        }

        //将图像放入 lab 中
        QImage img(rgb.data, rgb.cols, rgb.rows, rgb.cols*rgb.channels(), QImage::Format_RGB888);

        ui->label->setPixmap(QPixmap::fromImage(img));

    }

    //判断是否是  人脸录入定时器  超时
    if(e->timerId() == face_id)
    {
        if(0 == flag)
        {

            qDebug() << "人脸录入中,请正视摄像头!";

            Mat face = src(faces[0]); //将摄像头当前的一帧图像上的一个人脸给face

            //灰度处理
            cvtColor(face, face, CV_BGR2GRAY);

            //均衡化处理
            equalizeHist(face, face);

            //将人脸放入数组中
            study_faces.push_back(face);
            study_lables.push_back(1);

            count++;
            if(50 == count)
            {
                //将图像模型转换成数据模型
                recognizer->update(study_faces, study_lables);
                recognizer->save("D:\\opencv\\image\\my_face.xml");

                QMessageBox::information(this, "", "录入人脸成功!");
                //关闭定时器
                killTimer(face_id);
                flag = 1; //表示可以人脸识别
                study_faces.clear(); //将存放人脸数组清空,方便下次录入
                study_lables.clear();

            }
        }
    }

    //判断是否是  人脸检测定时器  超时
    if(e->timerId() == check_id)
    {
        if(1 == flag)
        {
            QFile file("D:\\opencv\\image\\my_face.xml");

            if(file.exists())
            {
                if(recognizer.empty() || faces.empty())
                {
                    return;
                }

                Mat face = src(faces[0]);

                //灰度处理
                cvtColor(face, face, CV_BGR2GRAY);

                //
                equalizeHist(face, face);

                int lab = -1;
                double cof = 0.0;

                recognizer->predict(face, lab, cof);

                //根据 lab 判断是否识别成功
                if(lab != -1)
                {
                    QMessageBox::information(this, "", "人脸识别成功!");

                    ui->weChatBtn->setEnabled(true);

                    killTimer(check_id);

                }

            }

        }
    }

}

//关闭摄像头按钮对应的槽函数
void Widget::on_closeBtn_clicked()
{
    killTimer(camera_id);
}

//录入人脸按钮对应的槽函数
void Widget::on_faceBtn_clicked()
{
    count = 0; // 将录入人脸的次数设置为0
    flag = 0; //表示只能做人脸录入,不能做人脸检测
    face_id = startTimer(50);

}

main.c文件:

#include "widget.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}

 ui布局:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1857107.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

我在高职教STM32——LCD液晶显示(4)

大家好&#xff0c;我是老耿&#xff0c;高职青椒一枚&#xff0c;一直从事单片机、嵌入式、物联网等课程的教学。对于高职的学生层次&#xff0c;同行应该都懂的&#xff0c;老师在课堂上教学几乎是没什么成就感的。正因如此&#xff0c;才有了借助 CSDN 平台寻求认同感和成就…

AIGC发展方向和前景

引言 背景介绍 AIGC的定义及其发展历程 AIGC&#xff0c;即人工智能生成内容&#xff0c;是近年来在人工智能领域兴起的一项重要技术。它通过使用机器学习和深度学习等技术&#xff0c;使得计算机能够自动生成各种形式的数字内容&#xff0c;如文本、图像、音频和视频等。 …

钢铁企业环保创A

朗观视觉小编观察发现&#xff0c;在当下全球环保浪潮的推动下&#xff0c;钢铁企业作为传统重工业的代表&#xff0c;正面临着前所未有的挑战与机遇。为了实现可持续发展&#xff0c;许多钢铁企业纷纷加入到环保创A的行列中&#xff0c;通过技术创新和管理升级&#xff0c;推动…

Lipowerline5.0 雷达电力应用软件下载使用

1.配网数据处理分析 针对配网线路点云数据&#xff0c;优化了分类算法&#xff0c;支持杆塔、导线、交跨线、建筑物、地面点和其他线路的自动分类&#xff1b;一键生成危险点报告和交跨报告&#xff1b;还能生成点云数据采集航线和自主巡检航线。 获取软件安装包联系邮箱:289…

ONLYOFFICE8.1版本桌面编辑器测评

OO官方链接点这里&#xff1a;ONLYOFFICE 文档 8.1 现已发布&#xff1a;功能全面的 PDF 编辑器、幻灯片版式、优化电子表格的协作等等 | ONLYOFFICE 博客 一、界面与用户体验 整体布局和设计的美观性、易用性&#xff1a; ONLYOFFICE 8.1 版本的桌面编辑器展现出了令人眼前一亮…

电路学习——经典运放电路(2024.06.21)

参考链接1: 11个经典运放电路 在此感谢各位前辈大佬的总结&#xff0c;写这个只是为了记录学习大佬资料的过程&#xff0c;内容基本都是搬运的大佬博客&#xff0c;觉着有用自己搞过来自己记一下&#xff0c;如果有大佬觉着我搬过来不好&#xff0c;联系我删。 电路学习——经典…

[职场] 公务员的利弊分析 #知识分享#经验分享#其他

公务员的利弊分析 公务员作为一种稳定的职业选择&#xff0c;一直备受人们的关注。然而&#xff0c;就像任何其他职业一样&#xff0c;公务员职位也有其利与弊。本文将对公务员的利弊进行分析&#xff0c;帮助读者更好地了解这一职业的特点。 利&#xff1a; 1. 稳定的职业&a…

【C++】文件处理(IO流)

文章目录 C IO流1. C语言IO2. CIO2.1 C标准IO流2.2 C文件IO流2.3 C IO 文件常用函数总结表2.4 C stringstream C IO流 回顾一下&#xff0c;C语言中IO输入输出的 1. C语言IO C语言中常用的输入输出函数有如下几种&#xff1a;前者是格式化标准输入输出&#xff0c;后者是格式化…

GD32 串口接受异常的几个原因

前面我们介绍过GD32 485发送时出现异常的最常见原因&#xff0c;有小伙伴反馈想要知道GD32 串口接受异常的可能原因&#xff0c;今天我们就来安排。 一、波特率异常导致收发出错 我们知道&#xff0c;串口是异步通讯接口&#xff0c;通讯双方或者多方都需要工作在相同波特率下…

C++必修:模版的入门到实践

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;C学习 贝蒂的主页&#xff1a;Betty’s blog 1. 泛型编程 首先让我们来思考一个问题&#xff0c;如何实现一个交换函数&#x…

(超详细)YOLOV7改进-Soft-NMS(支持多种IoU变种选择)

1.在until/general.py文件最后加上下面代码 2.在general.py里面找到这代码&#xff0c;修改这两个地方 3.之后直接运行即可

对撞指针技巧

对撞指针技巧 我们以LeetCode的一道题目来讲解一下对撞指针&#xff1b; LeetCode第27题移除元素&#xff0c;链接如下&#xff1a; https://leetcode.cn/problems/remove-element 如果使用快慢指针 如果使用快慢指针&#xff0c;将会有大量的后面元素赋值给前面元素的操作…

面向二级及二级以下医院的云HIS系统源码,涵盖患者、费用、医嘱、电子病历等核心业务功能。

云HIS系统源码&#xff0c;二级医院信息管理系统源码&#xff0c;电子病历系统 云HIS系统&#xff0c;采用云计算、互(物)联网、大数据、人工智能等现代信息技术&#xff0c;融合医保、医疗、医药全方位的管理和服务&#xff0c;为各类中小型医疗机构&#xff0c;包括二级及二…

【Python机器学习实战】 | 基于K近邻算法和一般线性回归算法对电视剧播放数据进行回归预测

&#x1f3a9; 欢迎来到技术探索的奇幻世界&#x1f468;‍&#x1f4bb; &#x1f4dc; 个人主页&#xff1a;一伦明悦-CSDN博客 ✍&#x1f3fb; 作者简介&#xff1a; C软件开发、Python机器学习爱好者 &#x1f5e3;️ 互动与支持&#xff1a;&#x1f4ac;评论 &…

unity-特效-雷达扫描效果

使用后处理方式制作 using System; using System.Collections; using System.Collections.Generic; using UnityEngine;public class GlobalScanEffect : MonoBehaviour {public float startScanRange 0;public float maxScanRange 20;public float scanWidth 3;public flo…

数据库期末复习知识点

A卷 1. 选择题(30) 2. 判断范式(10) 判断到第三范式 3. 程序填空(20) 4. 分析填空(15) 5. 写SQL(25) 5一题 恶性 B卷 1. 单选(30) 2. 填空 (20) 3. 程序填空(20) 4. 写SQL(30) 知识点 第一章 数据库管理系统(DBMS) 主要功能 数据定义功能 (DDL, 数据定义语言, …

第二证券股市知识:小白炒股是做长线好还是短线好?

关于小白来说&#xff0c;挑选炒长线比炒短线要好一些&#xff0c;其间原因如下&#xff1a; ​ 1、对出资者技能要求相对较低 短线出资&#xff0c;需要出资者对个股的走势掌握比较精确&#xff0c;才干通过高抛低吸赚取必定的差价&#xff0c;否则很容易让散户卖飞个股&am…

快速记忆成百上千个账号密码

在日常生活中&#xff0c;我们不仅需要记忆6位数字的银行卡密码&#xff0c;还需要记忆各式各样网站和应用的账号密码&#xff0c;可能我们自己也不记得曾经注册过多少个账号。账号和密码如此繁多&#xff0c;管理这些账号和密码&#xff0c;也是一个让人头疼的问题。 最原始的…

前两天上线了一个小功能,差点把我们项目搞崩溃

项目场景&#xff1a; 最近一直在迭代公司的系统&#xff0c;业务提出需要增加一个消息通知的功能&#xff0c;对接完需求之后&#xff0c;我们就 开始热火朝天的编码、测试、上线&#xff0c; 就是右上角这个小图标&#xff0c;为了提升用户体验&#xff0c;我们采用每隔20S…

有效利用MRP能为中小企业带来什么?

在离散制造企业&#xff0c;主流的生产模式主要为面向订单生产和面向库存生产&#xff08;又称为预测生产&#xff09;&#xff0c;在中小企业中&#xff0c;一般为面向订单生产&#xff0c;也有部分面向库存和面向订单混合的生产方式&#xff08;以面向订单为主&#xff0c;面…