face.pro
#-------------------------------------------------
#
# Project created by QtCreator 2024-03-28T11:48:59
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = 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
widget.h
#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();
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;//摄像头的定时器id
void timerEvent(QTimerEvent *e);//重写定时器事件函数声明
//人脸录入相关设置
Ptr<LBPHFaceRecognizer> recognizer;//人脸识别器指针
vector<Mat> study_faces;//保存录入人脸的数组
vector<int> study_labels;//保存录入人脸对应标签的数组
int count;//记录录入人脸次数
int flag;//区分是人脸录入还是人脸检测
int face_id;//人脸录入定时器id
//人脸检测设置
int check_id;//人脸检测id
};
#endif // WIDGET_H
main.cpp
#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"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
//将QQ设置不可用
ui->QQbtn->setEnabled(false);
//打开系统摄像头
if(!v.open(0))
{
QMessageBox::information(this,"","打开系统摄像头失败");
return;
}
//下载级联分类器的配置文件
if(!c.load("D:\\opencv\\image\\haarcascade_frontalface_alt2.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(1000);
//设置可信度
recognizer->setThreshold(100);//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图转换成rgb
cvtColor(src,rgb,CV_BGR2RGB);
//将图像重新设置大小
cv::resize(rgb,rgb,Size(350,350));
//灰度处理
cvtColor(rgb,gray,CV_RGB2GRAY);
//均衡化处理
equalizeHist(gray,dst);
c.detectMultiScale(dst,faces);
//将矩形框绘制到图像人脸上
for(int i=0;i<faces.size();i++)
{
rectangle(rgb,faces[i],Scalar(255,0,0),1);
}
QImage img(rgb.data,rgb.cols,rgb.rows,rgb.cols*rgb.channels(),QImage::Format_RGB888);
//将图像设置到label
ui->label->setPixmap(QPixmap::fromImage(img));
}
//判断是否是人脸录入超时
if(e->timerId()==face_id)
{
if(flag==0)
{
qDebug() << "人脸录入中,请正视摄像头";
Mat face=src(faces[0]);
//灰度处理
cvtColor(face,face,CV_BGR2GRAY);
//均衡化处理
equalizeHist(face,face);
//存放到数组里
study_faces.push_back(face);
study_labels.push_back(1);
count++;
if(count==50)//录入50张人脸
{
//人脸模型转化成数字模型
recognizer->update(study_faces,study_labels);
//保存
recognizer->save("D:\\opencv\\image\\my_face.xml");
QMessageBox::information(this,"","人脸录入成功");
//关闭定时器
killTimer(face_id);//关闭人脸录入定时器
count=0;
study_faces.clear();
study_labels.clear();
flag=1;//表示可以进行人脸检测
}
}
}
//判断是否是人脸检测超时
if(e->timerId()==check_id)
{
if(flag==1)
{
QFile file("D:\\opencv\\image\\my_face.xml");
if(file.exists())
{
if(faces.empty() || recognizer.empty())
{
return;
}
Mat face=src(faces[0]);
//灰度处理
cvtColor(face,face,CV_BGR2GRAY);
//均衡化处理
equalizeHist(face,face);
int lab=-1;
double con=0.0;
recognizer->predict(face,lab,con);
if(lab!=-1)
{
QMessageBox::information(this,"","欢迎主人");
ui->QQbtn->setEnabled(true);
killTimer(check_id);
flag=0;
}
}
}
}
}
//关闭按钮对应槽函数
void Widget::on_closebtn_clicked()
{
//关闭定时器
killTimer(camera_id);
}
//人脸录入按钮对应槽函数
void Widget::on_facebtn_clicked()
{
count=0;//人脸录入次数为0
flag=0;//此时表示只能人脸录入
//启动一个定时器
face_id=startTimer(50);
}
widget.ui
运行结果
**************************代码来自上海华清远见C++课程老师周锁琴**************************