人脸识别项目

#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("主页");
}

                
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值