人脸识别系统
#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;
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_opencamerabtn_clicked();
void timerEvent(QTimerEvent *event)override;
void on_cameraclosebtn_clicked();
void on_faceinbtn_clicked();
void on_facerecbtn_clicked();
private:
Ui::Widget *ui;
Mat src;
Mat grey;
Mat dest;
Mat rgb;//存放转变后的RGB图
VideoCapture video;
CascadeClassifier c;
vector<Rect> myface; //人脸矩形容器
int camera_timer_d; //关于ui界面展示图片的定时器
Ptr<LBPHFaceRecognizer> recognizer;//人脸识别器指针
vector<Mat> train_faces;//人脸训练容器
vector<int> train_labs;//人脸编号 容器
int count=0;//人脸识别次数
int study_timer_id;//人脸录入定时器
int check_timer_id; //定义一个人脸识别定时器
};
#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
if(!video.open(0))
{
QMessageBox::information(this,"提示","摄像头打开失败");
return;
}
if(!c.load("D:\\opencv\\resources\\haarcascade_frontalface_alt.xml"))
{
QMessageBox::information(this,"提示","级联分类器下载失败");
return;
}
//给recognizer实意化类对象
QFile file("D:\\opencv\\resources\\myface.xml");
if(file.exists())
{
recognizer = FaceRecognizer::load<LBPHFaceRecognizer>("D:\\opencv\\resources\\myface.xml");
}
else
{
recognizer = LBPHFaceRecognizer::create();
}
recognizer->setThreshold(70);//设置模型的阈值
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_opencamerabtn_clicked()
{
camera_timer_d = startTimer(20);
ui->faceinbtn->setEnabled(true);
ui->facerecbtn->setEnabled(true);
}
void Widget::timerEvent(QTimerEvent *event)
{
if(event->timerId()==camera_timer_d)
{
// static int num;
// ui->cameralab->setNum(num++);
// if(!video.open(0))
// {
// QMessageBox::information(this,"提示","摄像头打开失败");
// return;
// }
if(!video.read(src))
{
QMessageBox::information(this,"提示","图像读取错误");
return;
}
flip(src,src,1);//图像翻转
cvtColor(src,grey,CV_BGR2GRAY);//灰度图
equalizeHist(grey,dest);
c.detectMultiScale(dest,myface);
for(uint i=0;i<myface.size();i++)//将每张图片
{
rectangle(src,myface[i],Scalar(0,255,0));
}
// imshow("test",src);
//将图像调整大小
cvtColor(src,rgb,CV_BGR2RGB);//Mat类的是BGR图像,转成RGB
cv::resize(src,rgb,Size(300,300));
//将Mat图像转换为Qt能够识别的图像
QImage image=QImage(rgb.data,rgb.cols,rgb.rows,rgb.cols*rgb.channels(),QImage::Format_RGB888);
//将图像展示到UI界面上
ui->cameralab->setPixmap(QPixmap::fromImage(image));
}
//判断是否是人链录入定时器是否到位
if(event->timerId() == study_timer_id)
{
qDebug() << "人脸录入中,请稍后";
//处理人脸录入
//用于存储人脸区域图像
Mat face;
face = src(myface[0]); //将框中人脸截取
//将图像重新设置大小,以便识别与录入图片大小一样
cv::resize(face,face,Size(100,100));
cvtColor(face,face,CV_BGRA2GRAY);//灰度图
equalizeHist(face,face);//均衡化处理
//将该图像放入到学习容器中
train_faces.push_back((face));
train_labs.push_back((1));
count++;
if(count==30)
{
//使用容器中的数据更新模型
recognizer->update(train_faces,train_labs);
//将模型保存到本地磁盘
recognizer->save("D:\\opencv\\resources\\myface.xml");
//处理后续操作
count=0; //便于下次人脸录入使用
//清空容器
train_faces.clear();
train_labs.clear();
ui->facerecbtn->setEnabled(true);
ui->faceinbtn->setEnabled(true);
killTimer(study_timer_id);
QMessageBox::information(this,"提示","人脸录入成功");
//关闭定时器
}
}
//判断是否是人链录入定时器是否到位
if(event->timerId() == check_timer_id)
{
//判断图像上是否有矩形框
// if(myface.empty() || recognizer.empty())
// {
// return;
// }
//从摄像头中获取人脸检测矩形区域图像
Mat face = src(myface[0]);
//重新获取设置大小
cv::resize(face,face,Size(100,100));
//灰度处理
cvtColor(face,face,CV_BGR2GRAY);
//均衡化处理
equalizeHist(face,face);
//定义接受识别后接收结果的变量
int lab = -1;
double conf = 0;
recognizer->predict(face,lab,conf);
//参数一 预测图像
//参数二 返回的图像编号
//参数三 预测可信度
qDebug() << lab << conf;
//判断人脸预测后的结果,进而执行相关逻辑
if(conf <= 100 && lab != -1)
{
// qDebug() << lab << conf;
QMessageBox::information(this,"提示","欢迎回来");
//后续操作
killTimer(check_timer_id);//关闭定时器
//将两个按钮设置可用状态
ui->faceinbtn->setEnabled(true);
ui->facerecbtn->setEnabled(true);
ui->functionbtn->setEnabled(true);
}
}
}
void Widget::on_cameraclosebtn_clicked()
{
killTimer(camera_timer_d);
ui->cameralab->clear();
}
//录入人脸按钮对应的槽函数
void Widget::on_faceinbtn_clicked()
{
study_timer_id = startTimer(50);
ui->faceinbtn->setEnabled(false);
ui->facerecbtn->setEnabled(false);
}
void Widget::on_facerecbtn_clicked()
{
//将两个按钮设置成不可用状态
ui->faceinbtn->setEnabled(false);
ui->faceinbtn->setEnabled(false);
check_timer_id=startTimer(30);
}