QT人脸识别知识
机器学习的作用:根据提供的图片模型通过算法生成数据模型,从而在其它图片中查找相关的目 标。
级联分类器:是用来人脸识别。 在判断之前,我们要先进行学习,生成人脸的模型以便后续识别使用。
人脸识别器:判断是谁的面部。 FaceRecognizer类是opencv提供的人脸识别器基类,LBPHFaceRecognizer是根据LBPH算法实现的识别器类,其中LBPHFaceRecognizer识别器支持在原有模型基础上继续学习(模型数据可以累计)。
创建LBPHFaceRecognizer识别器对象
所需的头文件:#include 、using namespace cv::face;创建空的人脸识别器对象:Ptr<FaceRecognizer> recognizer =LBPHFaceRecognizer::create();根据已有的模型创建人脸识别器对象,在创建人脸识别器的时候,需要一个已经学习好的模型文件:Ptr<FaceRecognizer> recognizer = FaceRecognizer::load<LBPHFaceRecognizer>("模型文件.xml");
机器学习并更新模型
容器:容器中装了n张人脸Mat对象,先采集脸,装到容器中,存储标签,人的身份证,每一张脸给一个编号:1 张三脸 2 李四脸 3 王五脸。功能函数1:void update(InputArrayOfArray src,InputArray labels)//机器学习并更新模型功能函数2:void train(InputArrayOfArrays src,InputArray labels);//只是学习,不更新//参数1src:图片模型数组 vector<Mat>//参数2labels:标签数组,每个模型识别后的标签vector<int>
保存模型
功能函数:void save(const String& filename);//参数1:模型文件的名字例如:recognizer->update(study_faces,study_label);//学习recognizer->save("face.xml");//将学习的成果,保存到face.xml模型文件中,生成模型:study_faces.clear();、study_labels.clear();
预测目标
判断这个人脸到底是谁。功能函数:void predict(InputArray src, int &label, double &confidence)//参数1:预测图形 Mat src//参数2::预测后的标签,学习时对应的标签//参数3:预测出结果的可信度,数值越小可信度越高例如:int label = -1;//预测后的标签,学习时对应的标签double confidence = 0;//可信度Mat face = frame(faces[0]);//人脸区域cvtColor(face,face,CV_BGR2GRAY);//更改色彩空间cv::resize(face,face,Size(90,90));//设置人脸的大小recognizer->predict(face,label,confidence); //预测,相当于识别人脸,预测出人脸是谁的面部,label的值就那张脸对应的标签,如果预测不到,label的值是-1。
设置可信度
功能函数:void setThreshold(double val);//参数1:预测可信度极值,预测可信度超出极值则预测失败。
实例:
头文件
#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_OBJECTpublic:explicit Widget(QWidget *parent = 0);~Widget();private slots:void on_openCameraBtn_clicked();void on_closeCameraBtn_clicked();void on_inputFaceBtn_clicked();private:Ui::Widget *ui;/***********************第一模块:关于摄像头的相关组件**********************/VideoCapture v; //视频流对象Mat src; //原图像Mat rgb; //存放rgb图像,因为qt能识别的图像色彩空间为rgbMat gray; //灰度图Mat dst; //均衡化图像CascadeClassifier c; //级联分类器vector<Rect> faces; //存储人脸矩形区域的容器int cameraId; //摄像头的定时器void timerEvent(QTimerEvent *event); //定时器事件处理函数/**********************第二模块:录入人脸的相关组件************************/Ptr<FaceRecognizer> recognizer; //人脸识别器vector<Mat> study_face; //要录入的人脸容器vector<int> study_lab; //要录入的人脸的标签int studyId; //人脸录入的定时器int flag; //标识是否正在录入人脸int count; //记录学习的次数/**********************第三模块:人脸检测相关组件*************************/int checkId; //人脸检测的定时器};#endif // WIDGET_H
源文件:
#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);//将登录按钮设置成不可用状态ui->loginBtn->setEnabled(false);//启动摄像头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/myFace.xml");//判断文件是否存在,如果存在,则直接下载,如果不存在,则创建一个人脸识别器if(file.exists()){//人脸模型存在,直接下载即可recognizer = FaceRecognizer::load<LBPHFaceRecognizer>("D:/opencv/resource/myFace.xml");}else{//人脸模型不存在,需要进行创建recognizer = LBPHFaceRecognizer::create();}//启动人脸检测的定时器checkId = this->startTimer(3000);//设置人脸识别的可信度recognizer->setThreshold(100);flag = 0; //表明开始时就处于检测}Widget::~Widget()
{delete ui;
}
//打开摄像头按钮对应的槽函数
void Widget::on_openCameraBtn_clicked()
{//启动定时器cameraId = this->startTimer(20);ui->cameraLab->show();
}//关闭摄像头
void Widget::on_closeCameraBtn_clicked()
{//关闭定时器this->killTimer(cameraId);ui->cameraLab->hide();}//定时器事件处理函数
void Widget::timerEvent(QTimerEvent *event)
{//判断是哪个定时器到位if(event->timerId() == cameraId){//1、从摄像头中读取一张图像v.read(src); //得到原图//2、将图像翻转flip(src, src, 1);//3、将src的bgr图像转换为rgb图像cvtColor(src, rgb, CV_BGR2RGB);//4、重新设置大小cv::resize(rgb, rgb, Size(300,300));//5、灰度处理cvtColor(rgb, gray, CV_RGB2GRAY);//6、均衡化处理equalizeHist(gray, dst);//7、使用级联分类器获取人脸矩形区域c.detectMultiScale(dst, faces);//8、将矩形框绘制到rgb图像上for(int i=0; i<faces.size(); i++){rectangle(rgb, faces[i], Scalar(255,0,0), 2);}//9、使用rgb图像,将Mat图,构造出一个qt能识别的图像QImage img(rgb.data, rgb.cols, rgb.rows, rgb.cols*rgb.channels(), QImage::Format_RGB888);//功能:通过其他图像构造出一个QImage图像//参数1:其他图像的数据//参数2:图像的宽度//参数3:图像的高度//参数4:每一行的字节数//参数5:图像格式,24位图,每一种颜色使用8位表示//10、将图像展示到lab中ui->cameraLab->setPixmap(QPixmap::fromImage(img));}//判断是否是人脸录入定时器到位if(event->timerId() == studyId){//判断ui界面是否有矩形框if(faces.empty())return;//判断人脸识别器是否存在if(recognizer.empty()) return;//提示正在录入人脸qDebug()<<"正在录入,请稍后...";//获取ui界面中矩形框框起来的人脸区域Mat face = src(faces[0]);//将该图像进行重新设置大小cv::resize(face,face,Size(100,100));//灰度处理cvtColor(face,face,CV_BGR2GRAY);//均衡化处理equalizeHist(face,face);//将人脸放入学习容器中study_face.push_back(face);study_lab.push_back(1);count++; //表明完成一次人脸的存放if(count == 50) //已经收集50张人脸进行学习{count = 0; //以便于下一次录入//更新人脸模型,将图像模型转换为数据模型//函数原型:void update(InputArrayOfArrays src, InputArray labels);//参数1:要进行更新的人脸数组//参数2:要跟新的人脸标签数组//返回值:无recognizer->update(study_face, study_lab);//将数据模型保存到本地磁盘中recognizer->save("D:/opencv/resource/myFace.xml");//殿后工作study_face.clear(); //清空人脸数组study_lab.clear(); //清空标签数组flag = 0; //表明录入已经结束,可以进行人脸检测了ui->inputFaceBtn->setEnabled(true); //按钮设置成可用状态this->killTimer(studyId); //关闭人脸录入的定时器QMessageBox::information(this,"成功","人脸录入成功");}}//判断是否是人脸检测的定时器到位if(event->timerId() == checkId){qDebug()<<"正在检测...";//判断是否处于检测if(flag == 0){QFile file("D:/opencv/resource/myFace.xml");if(file.exists()) //表明人脸模型存在的基础上进行识别{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);qDebug()<<"lab = "<<lab<<" conf = "<<conf;//对人脸识别后的结果进行判断if(lab != -1){ui->loginBtn->setEnabled(true);}}}}}//录入人脸按钮对应的槽函数
void Widget::on_inputFaceBtn_clicked()
{//启动人脸录入的定时器qDebug()<<"开始进行人脸录入...";studyId = this->startTimer(60);//将按钮设置成不可用状态ui->inputFaceBtn->setEnabled(false);//将flag设置成1,表示正在录入人脸,不要进行人脸检测了flag = 1;count = 0; //清空计数器
}
相关文章:
QT人脸识别知识
机器学习的作用:根据提供的图片模型通过算法生成数据模型,从而在其它图片中查找相关的目 标。 级联分类器:是用来人脸识别。 在判断之前,我们要先进行学习,生成人脸的模型以便后续识别使用。 人脸识别器:…...

熟悉Redis6
NoSQL数据库简介 技术发展 技术的分类 1、解决功能性的问题:Java、Jsp、RDBMS、Tomcat、HTML、Linux、JDBC、SVN 2、解决扩展性的问题:Struts、Spring、SpringMVC、Hibernate、Mybatis 3、解决性能的问题:NoSQL、Java线程、Hadoop、Nginx…...
ip地址会随网络变化而变化吗
随着科技的飞速发展,互联网已深入我们生活的方方面面。在这庞大的网络世界中,IP地址作为网络通信的基础元素,引起了广泛关注。网络变化与IP地址之间存在着密切的关系。那么,IP地址是否会随着网络变化而变化呢?虎观代理…...
QT连接服务器通信,客户端以及服务器端
服务器端 .h文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTcpServer> //服务器头文件 #include <QTcpSocket> //客户端头文件 #include <QList> //链表头文件,用来存放客户端容器 #include <QDebug> #i…...

Vuex仓库的创建
vuex 的使用 - 创建仓库 文章目录 vuex 的使用 - 创建仓库1.安装 vuex2.新建 store/index.js 专门存放 vuex3.创建仓库 store/index.js4 在 main.js 中导入挂载到 Vue 实例上5.测试打印Vuex 1.安装 vuex 安装vuex与vue-router类似,vuex是一个独立存在的插件&#x…...

C++中的红黑树
红黑树 搜索二叉树搜索二叉树的模拟实现平衡搜索二叉树(AVL Tree)平衡搜索二叉树的模拟实现红黑树(Red Black Tree)红黑树的模拟实现 红黑树的应用(Map 和 Set)Map和Set的封装 搜索二叉树 搜索二叉树的概念:二叉搜索树又称二叉排序树,它或者是一棵空树&…...

SQL语法知识回顾
一、SQL语言的分类 由于数据库管理系统(数据库软件)功能非常多,不仅仅是存储数据,还要包含:数据的管理、表的管理、库的管理、账户管理、权限管理等等。所以,操作数据库的SQL语言,也基于功能&am…...
Java基础二十七(泛型)
泛型 Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。 泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。 Java的泛型是伪…...
Python入门教程36:urllib网页请求模块的用法
urllib是Python中的一个模块,它提供了一些函数和类,用于发送HTTP请求、处理URL编码、解析URL等操作。无需安装即可使用,包含了4个模块: #我的Python教程 #官方微信公众号:wdPythonrequest:它是最基本的htt…...
LeetCode 每日一题 2023/9/4-2023/9/10
记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步 目录 9/4 449. 序列化和反序列化二叉搜索树9/5 2605. 从两个数字数组里生成最小数字9/6 1123. 最深叶节点的最近公共祖先9/7 2594. 修车的最少时间9/8 2651. 计算列车到站时间9/…...

C# Onnx Yolov8 Seg 分割
效果 项目 代码 using Microsoft.ML.OnnxRuntime; using Microsoft.ML.OnnxRuntime.Tensors; using OpenCvSharp; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System…...

Postman接口测试流程
一、工具安装 ● 安装Postman有中文版和英文版,可以选择自己喜欢的版本即可。安装时重新选择一下安装路径(也可以默认路径),一直下一步安装完成即可。(本文档采用英文版本)安装文件网盘路径链接࿱…...

探索GreatADM:如何快速定义监控
引文 在数据库运维过程中,所使用的运维管理平台是否存在这样的问题: 1、默认监控粒度不够,业务需要更细颗粒度的监控数据。2、平台默认的监控命令不适合,需要调整阈值量身定制监控策略。3、不同类型的实例或组件需要有不同的监控重点,但管理平台监控固…...

C# 参数名加冒号,可以打乱参数顺序
今天看到Python有这种语法,参数名后面跟着等号写参数,联想到前几天用到的Serilog,好像有个参数名加冒号的写法,搜索了一下,果真有这种用法。 函数特别大的时候,用这种方法很直观,而且参数可以打…...

AVL树 模拟实现(插入)
目录 模拟插入节点 左单旋 右单旋 右左双旋 左右双旋 总结 实现 插入实现 左单旋实现 右单旋实现 右左双旋实现 左右双旋实现 AVL树 模拟实现(插入) AVL 树,是高度平衡二叉搜索树,其主要通过旋转来控制其左右子树的高…...
Java面试整理(三)《JavaSE》
反射机制(低) 在我刚开始学Java的时候,大家都很难理解反射这个概念,在实际开发中,虽然都有反射的踪影,但感觉自己又能理解是的。反射机制是指在程序运行时,对任意一个类都能获取其所有属性和方法,并且对任意一个对象都能调用其任意一个方法。 反射的步骤如下: 获取想要…...

LeetCode 1282. Group the People Given the Group Size They Belong To【哈希表】1267
本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章…...

Vue2项目练手——通用后台管理项目第八节
Vue2项目练手——通用后台管理项目 菜单权限功能tab.jsLogin.vueCommonAside.vuerouter/index.js 权限管理问题解决router/tab.jsCommonHeader.vuemain.js 菜单权限功能 不同的账号登录,会有不同的菜单权限通过url输入地址来显示页面对于菜单的数据在不同页面之间的…...

leetcode872. 叶子相似的树(java)
叶子相似的树 题目描述递归 题目描述 难度 - 简单 leetcode - 872. 叶子相似的树 请考虑一棵二叉树上所有的叶子,这些叶子的值按从左到右的顺序排列形成一个 叶值序列 。 举个例子,如上图所示,给定一棵叶值序列为 (6, 7, 4, 9, 8) 的树。 如果…...

【Linux从入门到精通】信号(初识信号 信号的产生)
本篇文章会对Linux下的信号进行详细解释。主要内容是什么是信号、信号的产生、核心转储等问题。希望本篇文章会对你有所帮助。 文章目录 引入 一、初识信号 1、1 生活中的信号 1、2 Linux 下的信号 1、3 信号进程所得的初识结论 二、信号的产生 2、1 用户通过终端输入产生信号 …...

网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...

如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...

selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...

DingDing机器人群消息推送
文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人,点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置,详见说明文档 成功后,记录Webhook 2 API文档说明 点击设置说明 查看自…...