QT5+OpenCV人脸识别

【2017-04-01:完整项目文件GitHub


需要用到OpenCV扩展包里的相关函数,请先编译OpenCV的contrib包。参考:Windows环境中编译opencv3.0同时加入OPENCV_contrib库及解决遇到相关问题


定义相关变量

vector images; //训练样本
vector labels; //标签,用来标记样本
QString name[10];   //用来存储姓名,因为标签是整型无法标识姓名
QString modelXml = "att_model.xml";//用来存储训练好的模型

Ptr model = createLBPHFaceRecognizer();
if(QFile::exists(modelXml)) //加载训练好的模型
{
    model->load(modelXml.toStdString());
}


训练模型
images.push_back(imread(imgName.toStdString(),CV_LOAD_IMAGE_GRAYSCALE));
labels.push_back(ui->labelBox->value());
    
name[ui->labelBox->value()] = ui->nameEdit->text(); //根据训练标签来存储姓名
    
model->update(images,labels); //更新训练模型,train()也是训练函数但会清空之前的模型


人脸识别
Mat image = imread(imgName.toStdString(), CV_LOAD_IMAGE_GRAYSCALE);//用来识别的图片

model->setThreshold(ui->doubleSpinBox->value()); //设置识别阉值,同一个人训练的图片越多此值可以设置得越小,具体需要自己调试

int result = model->predict(image);//识别并返回匹配的标签

if(result < 0)
    ui->nameLabel->setText(tr("无法识别此人"));
else
    ui->nameLabel->setText(tr("%1").arg(name[result]));//根据返回的标签索引姓名


保存模型
model->save(modelXml.toStdString());



效果如图QT5+OpenCV人脸识别_第1张图片



PS:
  • 经测试同一个人用正面,正面偏左、偏右、偏上、偏下五个角度各一张图片训练后阉值设置为85-90识别率比较高
  • 测试用的训练图片可以用ORL人脸库

完整代码:
  • mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include
#include
#include
#include
#include
#include
#include
#include
#include

using namespace std;
using namespace cv;
using namespace face;

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void on_loadButton_clicked();
    void on_testButton_clicked();
    void on_regButton_clicked();
    void closeEvent(QCloseEvent *e);

private:
    Ui::MainWindow *ui;
    Ptr model;
    QString fileName,saveXml,saveName,name[10];
};

#endif // MAINWINDOW_H


  • mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include
#include
#include
#include

//正面,上,下,左,右5张.阉值85.00

MainWindow::MainWindow(QWidget *parent):
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    saveName = "Names.txt";
    saveXml = "att_model.xml";

    model = createLBPHFaceRecognizer();

    if(QFile::exists(saveXml)&&QFile::exists(saveName))
    {
        model->load(saveXml.toStdString());
        QFile file(saveName);
        if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
            return;
        QTextStream in(&file);
        QString lineText;
        while(!in.atEnd())
        {
            lineText = in.readLine();
            QString i = lineText.split(":").first();
            name[i.toInt()] = lineText.split(":").last();
        }
    }
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::closeEvent(QCloseEvent *e)
{
    model->save(saveXml.toStdString());
    QFile file(saveName);
    if(!file.open(QIODevice::WriteOnly|QIODevice::Text))
        return;
    QTextStream out(&file);
    for(int i=0;i<10;i++)
    {
        if(name[i].isEmpty())
            continue;
        out<accept();
}

void MainWindow::on_loadButton_clicked()
{
    fileName = QFileDialog::getOpenFileName(this,tr("选择图片"),tr("."));
    if(fileName.isEmpty())
        return;
    ui->showLabel->setPixmap(QPixmap(fileName));
    ui->textBrowser->append(tr("打开图片%1").arg(fileName.split("/").last()));
}

void MainWindow::on_testButton_clicked()
{
    if(fileName.isEmpty()||ui->nameEdit->text().isEmpty())
        return;
    vector images;
    vector labels;
    images.push_back(imread(fileName.toStdString(),CV_LOAD_IMAGE_GRAYSCALE));
    labels.push_back(ui->labelBox->value());
    name[ui->labelBox->value()] = ui->nameEdit->text();
    ui->textBrowser->append(tr("准备训练: 姓名:%1 标签:%2 ...").arg(ui->nameEdit->text()).arg(ui->labelBox->value()));
    model->update(images,labels);
    ui->textBrowser->append(tr("训练完成"));
}

void MainWindow::on_regButton_clicked()
{
    ui->nameLabel->clear();
    if(fileName.isEmpty())
        return;
    Mat image = imread(fileName.toStdString(), CV_LOAD_IMAGE_GRAYSCALE);
    model->setThreshold(ui->doubleSpinBox->value());
    ui->textBrowser->append(tr("准备识别Threshold:%1 ...").arg(ui->doubleSpinBox->value()));
    int result = model->predict(image);
    ui->textBrowser->append(tr("识别完成"));
    if(result < 0)
        ui->nameLabel->setText(tr("无法识别此人"));
    else
        ui->nameLabel->setText(tr("%1").arg(name[result]));
}

  • main.cpp
#include "mainwindow.h"
#include 

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}





你可能感兴趣的:(C/C++)