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;           //清空计数器
}

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

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

相关文章

jenkins常见问题

1、忘记密码&#xff1f; 解决办法&#xff1a; 找到安装目录&#xff0c;linux安装目录一般是在/root/.jenkins,下用户文件users/admin_xxxxxx/config.xml文件。 打开文件&#xff0c;找到passwordHash块改为&#xff1a;#jbcrypt:$2a 10 10 10DdaWzN64JgUtLdvxWIflcuQu2fgrrM…

Java 复习笔记 - 面向对象篇

文章目录 一&#xff0c;面向对象概述二&#xff0c;类和对象&#xff08;一&#xff09;类和对象的概述&#xff08;二&#xff09;定义类的补充注意事项 三&#xff0c;封装四&#xff0c;就近原则和this关键字&#xff08;一&#xff09;就近原则&#xff08;二&#xff09;…

自学Python01-创建文件写入内容

此处省去安装和前言&#xff0c;需要两个东西 一个去下载安装python官方库 Welcome to Python.org 一个是编译器pycharm PyCharm 安装教程&#xff08;Windows&#xff09; | 菜鸟教程 PyCharm: the Python IDE for Professional Developers by JetBrains 第一节 练习print…

Java复习-23-包

包的定义与使用 包的定义 包 存放类程序文件的目录&#xff0c;程序类中定义的包名称必须采用小写字母的形式定义。 package com.example.demo ; // 定义包&#xff0c;其中.表示分割子目录 (子包) public class Hello {public static void main(String args[]) {System.ou…

记录--移动端的双击事件好不好用?

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 前言 2023年了&#xff0c;我不允许还有人不会自己实现移动端的双击事件。 过来&#xff0c;看这里&#xff0c;不足 50 行的代码实现的双击事件。 听笔者娓娓道来。 dblclick js原生有个dblclick双击…

UDP的可靠性传输

UDP系列文章目录 第一章 UDP的可靠性传输-理论篇&#xff08;一&#xff09; 第二章 UDP的可靠性传输-理论篇&#xff08;二&#xff09; 文章目录 UDP系列文章目录前言1.TCP 和UDP格式对比2.UDP分片原理3.UDP 传输层应该注意问题4.MTU5.UDP 分片机制设计重点 一、ARQ协议什么…

Python基础知识详解:数据类型、对象结构、运算符完整分析

文章目录 python基础知识数据类型类型检查对象&#xff08;object&#xff09;对象的结构变量和对象类型转换运算符(操作符)1. 算术运算符2. 赋值运算符3. 比较运算符&#xff08;关系运算符&#xff09;4. 逻辑运算符5. 条件运算符&#xff08;三元运算符&#xff09; 总结 py…

【PowerQuery】PowerQuery导入JSON数据

Json数据是目前使用的最为频繁和广泛的一种数据交换格式,JSON的全称为JavaScript Object Notation。Json 主要用于在互联网的消息的数据交换信息传递,他的格式与XML有什么区别呢?为什么不用XML,用Json有啥好处呢?我们接下来讨论下Json相比XML的优势: XML传递的数据过多服…

git回退到某个提交

git是一个分布式版本控制软件&#xff0c;分布式版本库的做法使源代码的发布和交流都极为方便&#xff0c;因此有不少用户都在使用git。最近小编也正在学习git这款软件&#xff0c;发现要想熟练运用git&#xff0c;学会git中的一些命令是很重要的&#xff0c;如果我们要回滚到某…

手写RPC框架--2.介绍Zookeeper

RPC框架-Gitee代码(麻烦点个Starred, 支持一下吧) RPC框架-GitHub代码(麻烦点个Starred, 支持一下吧) 该项目的RPC通信将采用NettyZookeeper&#xff0c;所以会在前两章介绍使用方法 介绍Zookeeper Zookeepera.概述1) 数据模型2) Watcher机制 b.安装和基本操作1) Java操作zooke…

16字节协议的串口通信

1.协议要求 协议为帧传输&#xff0c;一共16字节。主要是2字节的固定帧头 EB 90&#xff0c;2字节的帧计数(用来计数发出的帧),10字节的数据和2字节的校验位 帧头&#xff1a;2字节&#xff0c;固定值 8’HEB、8’H90 帧计数&#xff1a;2字节&#xff0c;用来说明发出去帧是…

Netty服务端启动的整体流程-基于源码4.1.96Final分析

Netty采用的是主从Reactor多线程的模型&#xff0c;参考Scalable IO in Java&#xff0c;但netty的subReactor为一个组 一、从FileServer服务器示例入手 public final class FileServer {static final boolean SSL System.getProperty("ssl") ! null;// Use the …

【笔记】软件测试的艺术

软件测试的心理学和经济学 测试是为发现错误而执行程序的过程&#xff0c;所以它是一个破坏性的过程&#xff0c;测试是一个“施虐”的过程。 软件测试的10大原则 1、测试用例需要对预期输出的结果有明确的定义 做这件事的前提是能够提前知晓需求和效果图&#xff0c;如果不…

ChatGPT是否可以协助人们提高公共演讲和表达能力?

ChatGPT作为一种自然语言处理的AI技术&#xff0c;具有潜在的能力协助人们提高公共演讲和表达能力。公共演讲和表达是重要的沟通技能&#xff0c;对于职业和个人发展都具有关键性的作用。本文将探讨ChatGPT如何在这方面发挥作用&#xff0c;包括以下几个方面&#xff1a; 1. *…

Linux 操作系统实战视频课 - GPIO 基础介绍

文章目录 一、GPIO 概念说明二、视频讲解沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇我们将讲解 GPIO 。 一、GPIO 概念说明 ARM 平台中的 GPIO(通用输入/输出)是用于与外部设备进行数字输入和输出通信的重要硬件接口。ARM 平台的 GPIO 特性可以根据具体的芯…

C++11新特性① | C++11 常用关键字实战详解

目录 1、引言 2、C11 新增关键字详解 2.1、auto 2.2、override 2.3、final 2.4、nullptr 2.5、使用delete阻止拷贝类对象 2.6、decltype 2.7、noexcept 2.8、constexpr 2.9、static_assert VC常用功能开发汇总&#xff08;专栏文章列表&#xff0c;欢迎订阅&#xf…

LeetCode 剑指 Offer 10- I. 斐波那契数列

LeetCode 剑指 Offer 10- I. 斐波那契数列 题目描述 写一个函数&#xff0c;输入 n &#xff0c;求斐波那契&#xff08;Fibonacci&#xff09;数列的第 n 项&#xff08;即 F(N)&#xff09;。斐波那契数列的定义如下&#xff1a; F(0) 0, F(1) 1 F(N) F(N - 1) F(N - …

Unity项目包体优化经验方法论(Android平台)

前言 本篇文章主要讲解对于Unity Android平台也就是APK包体的优化经验&#xff0c;使用哪些工具能够更加便利的定位资源重灾区。本篇讲解的方法中对于Unity资源使用的AssetBundle的方式&#xff0c;如果使用addressable或其他资源管理方式&#xff0c;我还不是很清楚是否适用&…

使用pyenv安装python缓慢或无法安装

使用pyenv安装python缓慢或无法安装 这一定程度上和网络情况有关&#xff0c;下面提供几个常见方法&#xff1a; 关闭 VPN 后重新安装使用管理员权限打开命令窗口后安装如下 手动安装 pyenv 在执行 pyenv install --- 命令的时候&#xff0c;会连接远程库&#xff0c;将要安…

matlab使用教程(28)—微分方程(ODE)求解常见问题

1.非负 ODE 解 本博客说明如何将 ODE 解约束为非负解。施加非负约束不一定总是可有可无&#xff0c;在某些情况下&#xff0c;由于方程的物理解释或解性质的原因&#xff0c;可能有必要施加非负约束。仅在必要时对解施加此约束&#xff0c;例如不这样做积分就会失败或者解将不…