QT5+OpenCV人脸识别

来源:互联网 发布:mac u盘 200m 编辑:程序博客网 时间:2024/06/02 11:42

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


定义相关变量

vector<Mat> images; //训练样本vector<int> labels; //标签,用来标记样本QString name[10];   //用来存储姓名,因为标签是整型无法标识姓名QString modelXml = "att_model.xml";//用来存储训练好的模型Ptr<LBPHFaceRecognizer> 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());



效果如图



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

完整代码:
  • mainwindow.h
#ifndef MAINWINDOW_H#define MAINWINDOW_H#include<QMainWindow>#include<QCloseEvent>#include<opencv2/highgui/highgui.hpp>#include<opencv2/imgproc/imgproc.hpp>#include<opencv2/core/core.hpp>#include<opencv2/objdetect/objdetect.hpp>#include<opencv2/face.hpp>#include<opencv2/face/facerec.hpp>#include<iostream>using namespace std;using namespace cv;using namespace face;namespace Ui {class MainWindow;}class MainWindow : public QMainWindow{    Q_OBJECTpublic:    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<LBPHFaceRecognizer> model;    QString fileName,saveXml,saveName,name[10];};#endif // MAINWINDOW_H


  • mainwindow.cpp
#include "mainwindow.h"#include "ui_mainwindow.h"#include<QDebug>#include<QFileDialog>#include<QPixmap>#include<QFile>#include<QTextStream>//正面,上,下,左,右5张.阉值85.00MainWindow::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<<i<<":"<<name[i]<<"\n";    }    e->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<Mat> images;    vector<int> 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 <QApplication>int main(int argc, char *argv[]){    QApplication a(argc, argv);    MainWindow w;    w.show();    return a.exec();}





1 0