当前位置: 首页 > news >正文

QT实现人脸识别

QT实现人脸识别

Face.pro文件:

QT       += core guigreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsCONFIG += 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.0SOURCES += \main.cpp \widget.cppHEADERS += \widget.hFORMS += \widget.uiINCLUDEPATH += 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_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic: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; //打开摄像头的定时器idvoid 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 转换成  rgbcvtColor(src, rgb, CV_BGR2RGB);//将图像重新设置大小  适应labcv::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; // 将录入人脸的次数设置为0flag = 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布局:

 

相关文章:

  • 模版与策略模式
  • 百度文心智能体,创建属于自己的智能体应用
  • 安全管理中心-集中管控(6点)
  • C++ 结构体对齐详解
  • 一个易于使用、与Android系统良好整合的多合一游戏模拟器
  • 计算机网络 静态路由及动态路由RIP
  • JSON.parse 解析NaN, Infinity, -Infinity失败
  • 如何通过编程获取桌面分辨率、操作像素点颜色、保存位图和JPG格式图片,以及图片数据的处理和存储方式
  • 锂电池安全监测中会用到哪些气体传感器?
  • Java程序之可爱的小兔兔
  • 【初阶数据结构】深入解析栈:探索底层逻辑
  • 计算机网络面试HTTP篇二
  • 北京互联网企业出海服务小程序开发的主要功能
  • ReactNative进阶(二十八)Metro
  • 对称/非对称加密
  • 《微软的软件测试之道》成书始末、出版宣告、补充致谢名单及相关信息
  • HashMap剖析之内部结构
  • JS实现简单的MVC模式开发小游戏
  • Mysql数据库的条件查询语句
  • oschina
  • SSH 免密登录
  • 闭包--闭包作用之保存(一)
  • 对话 CTO〡听神策数据 CTO 曹犟描绘数据分析行业的无限可能
  • 多线程事务回滚
  • 理解在java “”i=i++;”所发生的事情
  • 驱动程序原理
  • 我的业余项目总结
  • 移动端解决方案学习记录
  • FaaS 的简单实践
  • ​3ds Max插件CG MAGIC图形板块为您提升线条效率!
  • ​软考-高级-系统架构设计师教程(清华第2版)【第15章 面向服务架构设计理论与实践(P527~554)-思维导图】​
  • ​一帧图像的Android之旅 :应用的首个绘制请求
  • # Swust 12th acm 邀请赛# [ K ] 三角形判定 [题解]
  • #pragma pack(1)
  • $LayoutParams cannot be cast to android.widget.RelativeLayout$LayoutParams
  • (JSP)EL——优化登录界面,获取对象,获取数据
  • (顶刊)一个基于分类代理模型的超多目标优化算法
  • (附源码)ssm码农论坛 毕业设计 231126
  • (附源码)基于SSM多源异构数据关联技术构建智能校园-计算机毕设 64366
  • (蓝桥杯每日一题)平方末尾及补充(常用的字符串函数功能)
  • (三十五)大数据实战——Superset可视化平台搭建
  • (一)UDP基本编程步骤
  • .form文件_一篇文章学会文件上传
  • .NET MAUI Sqlite程序应用-数据库配置(一)
  • .NET 快速重构概要1
  • .net操作Excel出错解决
  • .net分布式压力测试工具(Beetle.DT)
  • .NET开发者必备的11款免费工具
  • .NET命名规范和开发约定
  • .net专家(张羿专栏)
  • /dev/VolGroup00/LogVol00:unexpected inconsistency;run fsck manually
  • @ResponseBody
  • [2023年]-hadoop面试真题(一)
  • [Android]How to use FFmpeg to decode Android f...
  • [Angular] 笔记 6:ngStyle