1.配置文件
# Project created by QtCreator 2023-09-22T10:34:23
#
#-------------------------------------------------QT += core guigreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsTARGET = project
TEMPLATE = appSOURCES += main.cpp\widget.cppHEADERS += widget.hFORMS += 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>
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_studyBtn_clicked();private:Ui::Widget *ui;/***************功能模块1:摄像头的获取并展示****************/VideoCapture v; //视频流对象Mat src; //获取摄像头原图Mat rgb; //存放rgb图Mat gray; //灰度图Mat dst; //均衡化图CascadeClassifier c; //级联分类器vector<Rect> faces; //人脸矩形框容器int camera_id; //摄像头的定时器void timerEvent(QTimerEvent *e); //重写定时器事件处理函数/****************功能模块2:人脸录入操作*******************/int study_id; //人脸录入的定时器Ptr<FaceRecognizer> recognizer; //人脸识别器的指针vector<Mat> studyFaces; //人脸学习的数组vector<int> studyLabs; //人脸的标签数组int flag; //标记是否正在录入人脸int count; //记录学习次数/****************功能模块3:人脸检测***********************/int check_id; //人脸检测的定时器};#endif // WIDGET_H
3.源文件
#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);ui->loginBtn->setEnabled(false); //将登录按钮设置成不可用状态ui->closeCameraBtn->setEnabled(false); //关闭摄像头按钮禁用//给级联分类器装载人脸分类模型if(!c.load("D:\\opencv\\resources\\haarcascade_frontalface_alt2.xml")){QMessageBox::information(this,"失败","人脸分类模型下载失败");return;}//创建一个人脸识别器对象QFile file("D:\\opencv\\resources\\myface.xml");if(file.exists()){//表明人脸识别模型存在,直接下载即可recognizer = LBPHFaceRecognizer::load<LBPHFaceRecognizer>("D:\\opencv\\resources\\myface.xml");}else{//人脸模型不存在,需要创建一个recognizer = LBPHFaceRecognizer::create();}//当系统启动时,就要启动人脸检测的定时器check_id = this->startTimer(2000); //每隔2秒检测一次flag = 0; //表明刚开始时处于检测过程recognizer->setThreshold(70); //设置可信度,当检测的可信度低于100时,表明识别成功}Widget::~Widget()
{delete ui;
}//打开摄像头按钮对应的槽函数
void Widget::on_openCameraBtn_clicked()
{//打开摄像头if(!v.open(0)){QMessageBox::information(this,"失败","摄像头打开失败");return;}//启动定时器,每隔20毫秒,将摄像头中内容展示到ui界面的lab中camera_id = this->startTimer(20);//将该按钮设置成不可用状态ui->openCameraBtn->setEnabled(false);ui->closeCameraBtn->setEnabled(true);}//关闭摄像头按钮对应的槽函数
void Widget::on_closeCameraBtn_clicked()
{//关闭定时器this->killTimer(camera_id);//将启动按钮设置成可用状态ui->openCameraBtn->setEnabled(true);ui->closeCameraBtn->setEnabled(false);ui->faceLab->clear();//关闭摄像头v.release();
}//重写的定时器事件处理函数
void Widget::timerEvent(QTimerEvent *e)
{//判断是哪个定时器到位if(e->timerId() == camera_id){//1、从摄像头中读取一张图像v.read(src);//2、翻转flip(src,src, 1);//3、重新设置大小cv::resize(src,src,Size(300,300));//4、转换为rgb图cvtColor(src,rgb,CV_BGR2RGB);//5、灰度处理cvtColor(rgb, gray, CV_BGR2GRAY);//6、均衡化处理equalizeHist(gray,dst);//7、使用级联分类器找到人脸矩形框c.detectMultiScale(dst, faces);//8、将人脸矩形框绘制到rgb图上for(quint32 i=0; i<faces.size(); i++){rectangle(rgb, faces[i], Scalar(255,0,0), 2);}//9、通过使用Mat类型的rgb图,构造一个QT能够识别的图像QImage img(rgb.data, rgb.cols, rgb.rows, rgb.cols*rgb.channels(), QImage::Format_RGB888);//10、将qimage图转换为qpixmap图展示到UI界面ui->faceLab->setPixmap(QPixmap::fromImage(img));}//判断人脸录入的定时器是否到位if(e->timerId() == study_id){qDebug()<<"正在录入,请稍后...";//定义容器,存放摄像头中矩形框框起来的人脸区域Mat face = src(faces[0]);//将人脸重新设置尺寸cv::resize(face,face,Size(100,100));//灰度处理cvtColor(face,face,CV_BGR2GRAY);//均衡化处理equalizeHist(face,face);//将处理好的人脸图像放入学习容器中studyFaces.push_back(face);studyLabs.push_back(1);count++;if(count==60) //判断是否已经完成学习{//更新人脸识别模型//函数原型:virtual void update(InputArrayOfArrays src, InputArray labels);//功能:将给定的图像模型转换为数据模型//参数1:图像数组//参数2:标签数组recognizer->update(studyFaces,studyLabs);//将人脸数据模型保存到本地磁盘文件中recognizer->save("D:\\opencv\\resources\\myface.xml");//后续操作this->killTimer(study_id); //关闭定时器ui->studyBtn->setEnabled(true); //按钮设置成可用状态studyFaces.clear(); //清空容器studyLabs.clear();flag = 0; //设置flag为0,表明可以继续监测人脸count = 0;QMessageBox::information(this,"成功", "录入成功");}}//判断人脸检测定时器是否到位if(e->timerId() == check_id){//判断是否能进行检测if(flag == 0){if(faces.empty() || recognizer.empty())return;qDebug()<<"正在寻找人脸";QFile file("D:\\opencv\\resources\\myface.xml"); //人脸模型存在if(file.exists()){//1、获取摄像头中人脸区域Mat face = src(faces[0]);//2、重新设置大小cv::resize(face,face,Size(100,100));//3、灰度处理cvtColor(face,face, CV_BGR2GRAY);//4、均衡化处理equalizeHist(face,face);//5、准备变量接受预测后的结果int lab = -1;double conf = 0.0;//6、人脸预测recognizer->predict(face, lab, conf);qDebug()<<"lab: "<<lab<<" conf: "<<conf;//7、判断预测的结果if(lab != -1){//预测成功,给定按钮的权限ui->loginBtn->setEnabled(true);}}}}
}//人脸录入按钮对应的槽函数
void Widget::on_studyBtn_clicked()
{qDebug()<<"开始录入....";study_id = this->startTimer(50); //每隔50毫秒学习一次count =0; //计数器清零ui->studyBtn->setEnabled(false); //按钮不能使用flag = 1; //表明正在录入
}
4.主函数
#include "widget.h"
#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);Widget w;w.show();return a.exec();
}