简易版人脸识别qt opencv

news2024/11/27 10:24:30

1、配置文件.pro

#-------------------------------------------------
#
# Project created by QtCreator 2023-09-05T19:00:36
#
#-------------------------------------------------

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = 01_face
TEMPLATE = app


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

2、头文件

#ifndef WIDGET_H
#define WIDGET_H

#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;

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
    void timerEvent(QTimerEvent *event);         //定时器事件处理函数


private slots:
    void on_open_camera_Btn_clicked();

    void on_close_camera_Btn_clicked();

    void on_input_face_Btn_clicked();

private:
    Ui::Widget *ui;

    /************************第一模块:关于摄像头的组件***********************/
    VideoCapture v; //定义一个视频流对象

    Mat src;   //原图像
    Mat rgb;   //由于qt不识别grb图像,所以需要转化为rgb图像
    Mat gray;  //灰度图
    Mat dst;  //均衡化图像

    CascadeClassifier c;  //级联分类器,用来获取人像的矩形框
    vector<Rect> faces;  //定义一个存储人像矩形的容器

    int camera_timer_id;  //定时器

    /************************第二模块:录入人脸的组件***********************/
    Ptr<FaceRecognizer> recognizer;  //人脸识别器

    vector<Mat> study_face;   //要录入的人脸容器
    vector<int> Study_lab;    //要录入的人脸标签

    int input_timer_id;     //录入人脸的定时器

    int flag;    //判断是否正在录入中
    int count;   //记录收集到的人脸的次数



    /************************第三模块:人脸检测的组件***********************/
    int check_timer_id;   //定义一个人脸检测的定时器


};

#endif // WIDGET_H

3、源文件

main.app

#include "widget.h"
#include <QApplication>

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

    return a.exec();
}

widget.cpp

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

int face_count = 1;  //录入对应的标签号
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

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

    }
    //将级联分类器加载进来
    if(!c.load("D:/opencv/resource/haarcascade_frontalface_alt2.xml"))
    {
        QMessageBox::information(this, "提示", "练级分类器加载失败");
        return;
    }

    //配置人脸识别器
    QFile file("D:/opencv/resource/Face.xml");

    //判断是否存在,存在将其下载下来,不存在创建人脸模型
    if(file.exists())
    {
        //存在人脸模型,下载进来
        recognizer = FaceRecognizer::load<LBPHFaceRecognizer>("D:/opencv/resource/Face.xml");
    }
    else
    {
        //不存在,创建LBPHFaceRecognizer::create()
        recognizer = LBPHFaceRecognizer::create();
    }

    //启动人脸检测定时器
    check_timer_id = startTimer(3000);
    flag = 0;

    //设置可信度
    recognizer->setThreshold(100);

}

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

//打开摄像头按钮的槽函数
void Widget::on_open_camera_Btn_clicked()
{
    //开启定时器
    camera_timer_id = this->startTimer(20);

}

void Widget::on_close_camera_Btn_clicked()
{
    //关闭定时器
    this->killTimer(camera_timer_id);
}

//定时器事件的函数
void Widget::timerEvent(QTimerEvent *event)
{
    //判断是否是打开摄像头定时器到位
    if(event->timerId() == camera_timer_id)
    {
        //获取图像
        //函数原型:virtual bool read(OutputArray image);
        //参数:存储读取到的图像容器
        //成功返回真,失败/读取完毕返回假
        v.read(src);

        //翻转图像
        //函数原型:oid flip(InputArray src, OutputArray dst, int flipCode);
        flip(src, src, 1);

        //将图像转为rgb模式
        cvtColor(src, rgb, CV_BGR2RGB);

        //重新设置图像大小
        cv::resize(rgb, rgb, Size(300,300));

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

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

        //使用级联分类器获取人脸图像的矩形框,并存入参数2中(人像矩形框容器中)
        //函数原型:void detectMultiScale( InputArray image,
          //                        CV_OUT std::vector<Rect>& objects,
            //                      double scaleFactor = 1.1,
              //                    int minNeighbors = 3, int flags = 0,
                //                  Size minSize = Size(),
                  //                Size maxSize = Size() );
        c.detectMultiScale(dst, faces);

        //将矩形框绘制到rgb图像中去
        for(int i=0; i<faces.size(); i++)
        {
            //使用全局函数rectangle函数,进行绘制
            rectangle(rgb, faces[i], Scalar(255, 0, 0), 1);
        }

        //将图像显示到ui界面上,ui界面的图像为QPixmap
        //需要将rgb图转为QImage的图像,再转为QPIXmap
        QImage img(rgb.data, rgb.cols, rgb.rows, rgb.cols*rgb.channels(), QImage::Format_RGB888);
        //功能:通过其他图像构造一个QImage图像
        //参数1:其他图像的数据
        //参数2:图像的宽度(列)
        //参数3:图像的高度(4)
        //参数4:每一行的字节数(列*通道)
        //参数5:图像格式,24位图,每一中颜色使用1字节8位表示

        //将其设置到ui界面的组件上
        ui->camera_Lab->setPixmap(QPixmap::fromImage(img));   //QPixmap::fromImage(img);  将QImage图像转为QPixmap图像

    }

    //判断是否是录入人脸定时器到位
    if(input_timer_id == event->timerId())
    {
        qDebug() << "正在录入....";
        //判断ui界面是否有矩形框
        if(faces.empty()) return;

        //判断人脸识别器是否存在
        if(recognizer.empty()) return;

        //获取矩形框中的图像
        Mat face = src(faces[0]);

        //重新设置大小
        cv::resize(face, face, Size(100, 100));

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

        //均衡化处理
        equalizeHist(face, face);
        qDebug() << face_count;
        //将图像放入学习容器中
        study_face.push_back(face);
        Study_lab.push_back(face_count);
        count++;


        //当收集50张后更新学习模型
        if(50 == count)
        {
            qDebug() << "hahhah";
            //将图像模型转为数据模型
            //函数原型:virtual void update(InputArrayOfArrays src, InputArray labels);
            //参数1:要进行更新的人脸图像容器
            //参数2:要进行封信的人脸标签容器
            recognizer->update(study_face, Study_lab);

            //将数据模型存入到本地磁盘中去
            recognizer->save("D:/opencv/resource/Face.xml");
            QMessageBox::information(this, "提示", "人脸录入成功");

            flag = 0;
            count = 0;
            killTimer(input_timer_id);
            study_face.clear();
            Study_lab.clear();
            face_count++;
        }

    }

    //判断是否是人脸检测定时器到位
    if(event->timerId() == check_timer_id)
    {
        if(0 == flag)
        {
            QFile file("D:/opencv/resource/Face.xml");
            //判断文件是否存在
            if(file.exists())
            {
                //判断ui->界面是否有矩形框和人脸识别器是否有
                if(faces.empty() || recognizer.empty()) return;

                //到此说明开始检测
                //获取ui界面上的矩形框中的图像
                Mat face = src(faces[0]);

                //重新设置图像大小, 与录入人脸时的大小一致
                cv::resize(face, face, Size(100, 100));

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

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

                //定义记录,检测后的结果
                int lab = -1;
                double conf = 0.0;

                //将人脸进行检测
                recognizer->predict(face, lab, conf);

                //判断是否匹配
                if(lab != -1)
                {
                    qDebug() <<"匹配成功";
                }
                qDebug() << lab;
            }
        }
    }
}

//录入人脸对应的参函数
void Widget::on_input_face_Btn_clicked()
{
    //启动定时器
    input_timer_id = startTimer(60);

    //将flag设置为1, 表明正在录入
    flag = 1;
    count = 0;

}

4、ui界面

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

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

相关文章

【trie树】CF Edu12 E

Problem - E - Codeforces 题意&#xff1a; 思路&#xff1a; 这其实是一个套路题 区间异或转化成前缀异或&#xff0c;然后枚举 i 对于每一个 i&#xff0c;ai ^ x k&#xff0c;对 x 计数 先建一棵字典树&#xff0c;然后在字典树上计数 先去对 > k 的部分计数&a…

m8130kt GPS模块测试

m8130kt GPS模块测试 ✨在某宝捡电子垃圾&#xff0c;10块钱的价格&#xff0c;就是没有资料可以提供的。上面携带有u-blox UBX-M8130-KT芯片&#xff0c;是肯定的&#xff0c;至于HMC5883芯片不确定&#xff0c;拆了屏蔽罩&#xff0c;芯片实在是太小&#xff0c;使用40倍放大…

SpringCloud实战项目(1)---创建空项目 jdk17

创建空项目 New ProjectAdd Jdk17创建空白标准Maven项目不要选择Create from archetype选项填写相关项目信息创建项目得到一个标准的maven项目&#xff0c;作为一个Parent project存在的&#xff0c;需删除src文件夹。 New Project 使用Idea, File -> New ->Project Add …

语音特征提取与预处理

导入相关包 import librosa import librosa.display import soundfile as sf import numpy as np import matplotlib.pyplot as plt from playsound import playsound 语音读取与显示 file_path test1.wav data, fs librosa.load(file_path, srNone, monoTrue) librosa.d…

word如何插入图片?3种常用的方法

word作为一款常用的办公软件&#xff0c;不仅可以处理文本内容&#xff0c;还能够轻松地插入图片以丰富文档内容。插入图片可以使文档更具吸引力、可读性和信息传达能力。本文将为您介绍word如何插入图片的3种方法&#xff0c;帮助您在文档中灵活、高效地添加图像元素。 word插…

SLAM从入门到精通(矩阵的使用)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 学习SLAM&#xff0c;离开了矩阵肯定是玩不转的。大学数学里面除了微积分&#xff0c;剩下的就是线性代数和概率论。而矩阵就是线性代数的一部分。…

selenium 动态爬取页面使用教程以及使用案例

Selenium 介绍 概述 Selenium是一款功能强大的自动化Web浏览器交互工具。它可以模拟真实用户在网页上的操作&#xff0c;例如点击、滚动、输入等等。Selenium可以爬取其他库难以爬取的网站&#xff0c;特别是那些需要登录或使用JavaScript的网站。Selenium可以自动地从Web页面…

在多机多卡训练时,保存的文件无法读取,报错文件已经损坏

问题描述&#xff1a;多机多卡训练保存了optimizer.pt文件&#xff0c;但是该文件在被读取时显示已经损坏。 原来的报错&#xff1a; Traceback (most recent call last):File "/mnt/petrelfs/tongjingqi/train-moe/smoe/entrypoint/cpt_fpt.py", line 280, in <…

Android Aidl跨进程通讯(三)--进阶使用

学更好的别人&#xff0c; 做更好的自己。 ——《微卡智享》 本文长度为2478字&#xff0c;预计阅读6分钟 前言 Android的AIDL使用和异常报错都已经介绍过了&#xff0c;今天这篇还是在原来的Demo基础上加入几个AIDL的进阶使用方法。 】 AIDL进阶使用 微卡智享 in,out,inout的使…

定时线程池原理解析

基本使用 ScheduledThreadPoolExecutor继承自ThreadPoolExecutor。它主要用来在给定的延迟之后运行任务&#xff0c;或者定期执行任务。 public class ScheduledThreadPoolExecutorTest {public static void main(String[] args) {ScheduledThreadPoolExecutor threadPoolExecu…

QT DAY7

主要完成多人聊天室&#xff0c;注册与登录使用sql3数据库进行对密码的保存&#xff0c;避免了用户重复登录、错误密码登录、重复注册的问题&#xff0c;之后使用TCP通信&#xff0c;连接上服务器后可在聊天室多人交流

怎么处理zk或redis脑裂

很极端场景会出现脑裂 什么是分布式的脑裂 怎么理解zk脑裂 就是ZK&#xff0c;与客户端可能因为网络原因&#xff0c;客户端A还在跑着后续程序&#xff0c;而zk与客户端之前的心跳断了&#xff0c;此zk就把这节点给删除了&#xff0c;这时另一个客户会加锁成功&#xff0c;就样…

[Java]异常

目录 1.异常的概念与体系结构 1.1异常的概念 1.1.1算术异常 1.1.2数组越界异常 1.1.3空指针异常 1.2异常的体系结构 1.3异常的分类 2.异常的处理 2.1 防御式编程 2.2异常的抛出 2.3异常的捕获 2.3.1 异常声明throws 将光标放在抛出异常方法上&#xff0c;alt Insert …

咖啡店小程序:吸引顾客的创新营销手段

近日&#xff0c;“酱香拿铁”的大火让大家再次把目标聚焦在年轻人都喜欢的咖啡上。现在咖啡已经成为年轻一代的社交硬通货&#xff0c;咖啡店也遍地开花。而随着移动互联网的快速发展&#xff0c;咖啡店小程序已经成为了各大咖啡店主的选择&#xff0c;因为它提供了便捷的方式…

【Leetcode-面试经典150题-day22】

目录 97. 交错字符串 97. 交错字符串 题意&#xff1a; 给定三个字符串 s1、s2、s3&#xff0c;请你帮忙验证 s3 是否是由 s1 和 s2 交错 组成的。 两个字符串 s 和 t 交错 的定义与过程如下&#xff0c;其中每个字符串都会被分割成若干 非空 子字符串&#xff1a; s s1 s2 …

便捷、快速、稳定、高性能!以 GPU 实例演示 Alibaba Cloud Linux 3 对 AI 生态的支持 | 龙蜥技术

编者按&#xff1a;日前&#xff0c;Alibaba Cloud Linux 3 为使 AI 开发体验更高效&#xff0c;提供了一些优化升级&#xff0c;本文为“Alibaba Cloud Linux 3 AI 能力介绍”系列文章预告篇&#xff0c;以 GPU 实例为例&#xff0c;为大家演示 Alibaba Cloud Linux 3 对 AI 生…

Vue + Element UI 前端篇(五):国际化实现

Vue Element UI 实现权限管理系统 前端篇&#xff08;五&#xff09;&#xff1a;国际化实现 国际化支持 1.安装依赖 执行以下命令&#xff0c;安装 i18n 依赖。 yarn add vue-i18n $ yarn add vue-i18n yarn add v1.9.4 warning package-lock.json found. Your project …

数据分析必知的统计知识——区间估计(其四)

4. 区间估计 还以为你被上节课的内容唬住了~终于等到你&#xff0c;还好没放弃&#xff01; 本节我们将说明两个问题&#xff1a;总体均值 μ \mu μ 的区间估计和总体比例 p ˉ \bar{p} pˉ​ 的区间估计。 区间估计经常用于质量控制领域来检测生产过程是否正常运行或者在…

机车整备场数字孪生 | 图扑智慧铁路

机车整备场是铁路运输系统中的重要组成部分&#xff0c;它承担着机车的维修、保养和整备工作&#xff0c;对保障铁路运输的运维和安全起着至关重要的作用。 随着铁路运输的发展、机车技术的不断进步&#xff0c;以及数字化转型的不断推进&#xff0c;数字孪生技术在机车整备场…

【Nginx23】Nginx学习:响应头与Map变量操作

Nginx学习&#xff1a;响应头与Map变量操作 响应头是非常重要的内容&#xff0c;浏览器或者客户端有很多东西可能都是根据响应头来进行判断操作的&#xff0c;比如说最典型的 Content-Type &#xff0c;之前我们也演示过&#xff0c;直接设置一个空的 types 然后指定默认的数据…