#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),count(0),isSay(true)
{
ui->setupUi(this);
this->setWindowFlags(Qt::WindowCloseButtonHint);
this->setFixedSize(800,480);
//文本转语音对象
//tts = new QTextToSpeech(this);
//默认显示主页
ui->stackedWidget->setCurrentWidget(ui->page_main);
//识别界面定时器
timer_recogn = new QTimer(this);
connect(timer_recogn,&QTimer::timeout,this,&MainWindow::onRecognition);
timer_recogn->setInterval(1000/30);
//采集界面定时器
timer_collect = new QTimer(this);
connect(timer_collect,&QTimer::timeout,this,&MainWindow::onCollect);
timer_collect->setInterval(1000/30);
//加载人脸分类器
cascade.load("../lbpcascade_frontalface_improved.xml");
//cascade.load("../haarcascade_frontalface_alt2.xml");
model = cv::face::createLBPHFaceRecognizer();
//model = cv::face::createEigenFaceRecognizer();
//创建人脸图像存放目录
QDir dir;
dir.mkdir(FACEPATH);
//数据库功能实现对象
mydb = new MyDatabase(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::sayHello(int index)
{
if(!isSay)
return;
qDebug() << "index = " << index;
QString name = mydb->getName(index);
if(name.isEmpty())
return;
//tts->say(QString("%1,你好").arg(name));
isSay = false;
QTimer::singleShot(3000,this,&MainWindow::onChangTTS);
}
void MainWindow::createCSV()
{
QFile file(CSVFILE);
if(!file.open(QIODevice::WriteOnly))
{
QMessageBox::information(this,"提示",file.errorString());
return;
}
QDir dir(FACEPATH);
QStringList list = dir.entryList();
for(int i = 0; i < list.size(); ++i)
{
if(list.at(i) == "." || list.at(i) == "..")
continue;
QString num = list.at(i);
dir.cd(list.at(i));
QStringList slist = dir.entryList();
for(int i = 0; i < slist.size(); ++i)//10
{
if(slist.at(i) == "." || slist.at(i) == "..")
continue;
QString path = dir.absoluteFilePath(slist.at(i));
file.write(path.toUtf8());
file.write(",");
file.write(num.toUtf8());
file.write("\r\n");
}
dir.cdUp();
}
file.close();
}
void MainWindow::createXML()
{
std::vector<cv::Mat> faces;
std::vector<int> labels;
QFile file(CSVFILE);
if(!file.open(QIODevice::ReadOnly))
{
qDebug() << "open csv file error: " << file.errorString();
return;
}
QTextStream in(&file);
while(!in.atEnd())
{
QString line = in.readLine();
QStringList list = line.split(",");
if(list.size() == 2)
{
faces.push_back(cv::imread(list.at(0).toStdString(),0));
labels.push_back(list.at(1).toInt());
}
}
model->train(faces,labels);
model->save("myface.xml");
}
//超时槽函数,获取一帧图像 并处理: 1/30
void MainWindow::onCollect()
{
//获取一帧图像
cap >> srcface;
if(srcface.empty())
return;
//灰度化
cv::cvtColor(srcface,grayface,cv::COLOR_RGB2GRAY);
cv::equalizeHist(grayface,grayface);
//检测人脸
std::vector<cv::Rect> faces;
cascade.detectMultiScale(grayface,faces);
//在原图中用矩形 框出 人脸
for(auto &x: faces)
{
cv::rectangle(srcface,x,cv::Scalar(255,0,0));
//保存灰度人脸
if(faces.size() == 1)
{
cv::Mat face = grayface(x);
cv::resize(face,face,cv::Size(92,112));
QString path = QString(FACEPATH) + "/" + QString::number(ui->spinBox_num->value()) + "/" + QString("%1.jpg").arg(count++);
cv::imwrite(path.toStdString(),face);
if(count == 10)
{
timer_collect->stop();
QMessageBox::information(this,"提示","采集完成!");
ui->btn_start_cap->setEnabled(true);
count = 0;
return;
}
}
}
//在界面上显示原图
QImage img(srcface.data,srcface.cols,srcface.rows,QImage::Format_RGB888);
ui->label_collect_cameral->setPixmap(QPixmap::fromImage(img.rgbSwapped()));
}
//槽函数:识别
void MainWindow::onRecognition()
{
//获取一帧图像
cap >> srcface;
if(srcface.empty())
return;
//灰度化
cv::cvtColor(srcface,grayface,cv::COLOR_RGB2GRAY);
cv::equalizeHist(grayface,grayface);
//检测人脸
std::vector<cv::Rect> faces;
cascade.detectMultiScale(grayface,faces);
//在原图中用矩形 框出 人脸
for(auto &x: faces)
{
cv::rectangle(srcface,x,cv::Scalar(255,0,0));
if(faces.size() == 1)
{
cv::Mat face = grayface(x);
cv::resize(face,face,cv::Size(92,112));
int index = model->predict(face);
// sayHello(index);
qDebug()<<index <<endl;
}
}
//在界面上显示原图
QImage img(srcface.data,srcface.cols,srcface.rows,QImage::Format_RGB888);
ui->label_recogn_cameral->setPixmap(QPixmap::fromImage(img.rgbSwapped()));
}
//槽函数:isSay
void MainWindow::onChangTTS()
{
qDebug() << "single shot ...";
isSay = !isSay;
}
//去采集
void MainWindow::on_btn_goCollection_clicked()
{
ui->stackedWidget->setCurrentWidget(ui->page_collection);
this->setWindowTitle("信息采集");
}
//去识别
void MainWindow::on_btn_goRecognition_clicked()
{
try
{
model->load("myface.xml");
}
catch(cv::Exception &e)
{
qDebug() << "catch exception :" << e.what();
return;
}
ui->stackedWidget->setCurrentWidget(ui->page_recognition);
this->setWindowTitle("人脸识别");
}
//设置编号
void MainWindow::on_btn_num_ok_clicked()
{
int num = ui->spinBox_num->value();
// ./faces/1
QString subdir = QString("%1/%2").arg(FACEPATH).arg(num);
QDir dir;
dir.mkdir(subdir);
dir.cd(subdir);
// /mnt/hgfs/share/shuqi/qt/build-FaceRecognition-Desktop_Qt_5_9_1_GCC_64bit-Debug/faces/1
curFacePath = dir.absolutePath();
ui->btn_start_cap->setEnabled(true);
}
//开始采集 按钮
void MainWindow::on_btn_start_cap_clicked()
{
//打开摄像头
bool ok = cap.open(0);
if(!ok)
{
QMessageBox::information(this,"提示","摄像头打开失败!");
return;
}
// capture.set(CV_CAP_PROP_FRAME_WIDTH, 320);
// capture.set(CV_CAP_PROP_FRAME_HEIGHT, 240);
//打开成功,则禁用启动按钮
ui->btn_start_cap->setEnabled(false);
//启动定时器
timer_collect->start();
}
//采集 返回 主页面
void MainWindow::on_btn_collect_return_clicked()
{
ui->stackedWidget->setCurrentWidget(ui->page_main);
this->setWindowTitle("主页");
}
//处理图像:训练生成xml文件
void MainWindow::on_btn_process_img_clicked()
{
createCSV();
createXML();
}
//开始识别
void MainWindow::on_btn_recog_start_clicked()
{
//打开摄像头
bool ok = cap.open(0);
if(!ok)
{
QMessageBox::information(this,"提示","摄像头打开失败!");
return;
}
//打开成功,则禁用启动按钮
ui->btn_recog_start->setEnabled(false);
//启动定时器
timer_recogn->start();
}
//停止识别
void MainWindow::on_btn_recogn_stop_clicked()
{
timer_recogn->stop();
ui->btn_recog_start->setEnabled(true);
}
//从识别页 返回 主页
void MainWindow::on_btn_recogn_return_clicked()
{
timer_recogn->stop();
ui->btn_recog_start->setEnabled(true);
ui->stackedWidget->setCurrentWidget(ui->page_main);
this->setWindowTitle("主页");
}
//去人员管理页
void MainWindow::on_btn_goEmployee_clicked()
{
ui->stackedWidget->setCurrentWidget(ui->page_Employee);
this->setWindowTitle("人员管理");
ui->tableView->horizontalHeader()->setStretchLastSection(true);
ui->tableView->setModel(mydb->getTableModel());
}
//插入一行
void MainWindow::on_btn_add_row_clicked()
{
mydb->insertRow();
}
//移除一行
void MainWindow::on_btn_delete_row_clicked()
{
int r = ui->tableView->currentIndex().row();
qDebug() << "r = " << r;
mydb->deleteRow(r);
}
//提交
void MainWindow::on_btn_submit_clicked()
{
mydb->submit();
}
//从人员页 返回 主页
void MainWindow::on_btn_employee_return_clicked()
{
ui->stackedWidget->setCurrentWidget(ui->page_main);
this->setWindowTitle("主页");
}