QT--day6(人脸识别、图像处理)

人脸识别:

cpp 复制代码
/***********************************************************************************头文件****************************************************************************************/



#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QWidget>
#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;

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

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

private slots:
    void on_opencameraBtn_clicked();

    void on_closecameraBtn_clicked();

    void on_faceStudyBtn_clicked();

private:
    Ui::Widget *ui;

    /***********************第一模块:摄像头展示相关成员**************************/

    //定义视频流对象
    VideoCapture v;

    //定义图像容器
    Mat src;       //存储原色图

    Mat gray;     //存储灰度图

    Mat dst;     //存储均衡化图像

    Mat rgb;     //存储转化成的rgb图

    //定义级联分类器类
    CascadeClassifier c;    //该类用于使用模型进行相关区域分类工作

    //定义存储人脸矩形框的数组
    vector<Rect>faces;

    //定义展示摄像头的定时器
    int camera_timer_id;

    //重写定时器事件处理函数
    void timerEvent(QTimerEvent *e);

    /***********************第二模块:人脸录入相关成员****************************/

    Ptr<LBPHFaceRecognizer> recognizer;   //人脸识别的指针

    vector<Mat>study_faces;        //训练人脸的人脸容器

    vector<int>study_lab;         //记录要存储人脸的id标签

    int count;                  //记录机器学习的次数

    int flag;                    //记录是否正在录入人脸

    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(!v.open(0))
    {
       QMessageBox::information(this,"","摄像头打开失败");
       return;
    }

    //加栽级联分类器
    if(!c.load("D:\\opencv\\resource\\haarcascade_frontalface_alt2.xml"))
    {
        QMessageBox::information(NULL,"","级联分类器加载失败");
        return ;
    }

    //给人脸识别区空间
    QFile file("D:\\opencv\\resource\\myface.xml");

    //判断人脸模型是否存在
    if(file.exists())
    {
        //判断人脸模型是否存在
        recognizer=FaceRecognizer::load<LBPHFaceRecognizer>("D:\\opencv\\resource\\myface.xml");

    }else
    {
        //此时表明人脸模型不存在,需要创建出一个人脸模型
        recognizer=LBPHFaceRecognizer::create();  //调用静态成员函数,创建出一个人脸模型
    }
    //初始时将登录按钮设置成不可用状态,当人脸识别成功后,该按钮设置层可用状态
    ui->loginBtn->setEnabled(false);

    //启动人脸预测的定时器
    check_timer_id=startTimer(3000);

    //程序运行时应处于检测过程而不是学习过程
    flag=1;

    //设置可信度
    recognizer->setThreshold(100);   //后期识别后,如果可信度低于100,则说明识别成功

}

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

//定时器事件处理函数
void Widget::timerEvent(QTimerEvent *e)
{
    if(e->timerId()==camera_timer_id)   //说明展示摄像头的定时器到位,处理摄像头的功能
    {
        //从视频流中读取一张图像放入src中
        v.read (src);

        //镜像处理
        flip(src, src, 1);

        //色彩空间转化,将bgr图转化为rgb图
        cvtColor(src,rgb,CV_BGR2RGB);

        //将图像重新设置大小
        cv::resize(rgb,rgb,Size(300,300));

        //灰度处理
        cvtColor(rgb,gray,CV_BGR2GRAY);

        //均衡化处理
        equalizeHist(gray,dst);

        //获得人脸矩形框
        c.detectMultiScale(dst,faces);

        //将人脸矩形区域绘制到rgb图上
        for(int i=0;i<faces.size();i++)
        {
            rectangle(rgb,faces[i],Scalar(255,0,0),2);
        }

        //使用rgb图构造出一个qt能够识别的图像
        //QImage (const uchar *data,int width,int height,int bytesPerLine,Format format;
        //功能:构造一个QImage图
        //参数1:其他图像的数据域
        //参数2:其他图像的宽度
        //参数3:其他图像的高度
        //参数4:一行内的字节数
        //参数5:图像格式
        QImage img(rgb.data,rgb.cols,rgb.rows,rgb.cols*rgb.channels(),QImage::Format_RGB888);

        //在ui界面中展示构造出来的图像
        ui->cameraLab->setPixmap(QPixmap::fromImage(img));
    }

    //判断是否是人脸录入定时器到位
    if(e->timerId()==study_timer_id)
    {
        qDebug()<<"正在录入,请稍后...";

        //获取ui界面中的矩形框框起来的人脸区域
        Mat face;            //要存储的人脸

        //判断人脸矩形框是否存在
        if(faces.empty())
            return ;            //如果ui界面上人脸矩形框不存在,则直接结束

        //从摄像头原图中截取一个矩形框大小的图像放到face变量中
        face=src(faces[0]);

        //将该脸进行重新设置大小
        cv::resize(face,face,Size(50,50));

        //色彩空间转换
        cvtColor(face,face,CV_BGR2GRAY);

        //均衡化处理
        equalizeHist(face,face);

        //此时,要存储的脸已经准备好了,需要使用人脸识别器进行更新模型操作

        //将刚学习的这张脸放入学习容器中
        study_faces.push_back(face);
        study_lab.push_back(1);

        count++;         //表明己经学习了一张人脸
        if(count==50)    //需要学习50次,完成人脸模型的配置
        {
            recognizer->update(study_faces,study_lab);//完成人脸模型的更新,将图像模型转化为数据模型
            //将刚刚生成的人脸数据模型,保存到本地磁盘文件中
            recognizer->save("D:\\opencv\\resource\\myface.xml");

            //殿后工作
            QMessageBox::information(this,"","录入成功");
            flag=1;                 //表明可以进行人脸检测工作
            ui->faceStudyBtn->setEnabled(true);//按钮设置成可用状态
            study_faces.clear();
            study_lab.clear();   //清空两个容器
            count=0;             //清空计数器,以便下次使用
            killTimer(study_timer_id);//关闭人脸录入的定时器

        }
    }

    //判断是否是人脸识别定时器到位
    if(e->timerId()==check_timer_id)
    {
        //判断是否可以进行检测
        if(flag==1)
        {
             qDebug()<<"正在寻找...";

             //找到人脸模型
             QFile file("D:\\opencv\\resource\\myface.xml");
             if(file.exists())    //在人脸模型存在的基础上进行识别
             {
                 //继续判断当前摄像头中是否有人脸存在
                 if(faces.empty()||recognizer.empty())
                     return;           //表明没有人脸或人脸识别器不存在

                 //开始进行人脸识别工作
                 //1、获取摄像头中的人脸区域
                 Mat face=src(faces[0]);

                 //2.重新设置大小,为存储时的大小
                 cv::resize(face,face,Size(50,50));

                 //3.灰度处理和均衡化处理
                 cvtColor(face,face,CV_BGR2GRAY);
                 equalizeHist(face,face);

                 //定义变量存储人脸预测后的结果
                 int lab=-1;      //预测后的人脸编号
                 double conf=0.0;  //预测后的人脸可信度

                 //5、进行人脸预测工作
                 //函数原型: void predict (InputArray src,cv_our int &label,cv_our double &confidence) const;
                 //功能:对给定的图像进行预测工作
                 //参数1:要预测的图像
                 //参数2:预测后的该图像的编号,如果识别失败,则编号保持之前的不变,如果预测成功,则将该图像对应的编号返回
                 //参数3:人脸识别后的可信度
                 recognizer->predict(face,lab,conf);

                 qDebug()<<"lab="<<lab<<"  conf="<<conf;
                 //对人脸识别后的数据进行判断
                 if(lab!=-1)
                 {
                     //说明人脸识别成功
                     ui->loginBtn->setEnabled(true);
                 }
             }


        }
    }


}

//打开摄像头按钮对应的槽函数
void Widget::on_opencameraBtn_clicked()
{
    //启动打开摄像头的定时器
    camera_timer_id=startTimer(20);
}

//关闭摄像头按钮对应的槽函数
void Widget::on_closecameraBtn_clicked()
{
    //关闭摄像头的定时器
    killTimer(camera_timer_id);
}

//录入人脸按钮对应的槽函数
void Widget::on_faceStudyBtn_clicked()
{
    qDebug()<<"开始录入人脸,请正视摄像头...";
    flag=0;                         //0表示正在录入人脸,不要进行检测工作
    count=0;                        //将学习次数清零
    //启动录入人脸的定时器
    study_timer_id=startTimer(50);    //每隔50毫秒学习一次

    //将录入按钮设置成不可用状态
    ui->faceStudyBtn->setEnabled(false);


}
相关推荐
用户805533698034 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner4 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz9 天前
QML Hello World 入门示例
qt
xcyxiner12 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner13 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner13 天前
DicomViewer (添加模型类)3
qt
xcyxiner14 天前
DicomViewer (目录调整) 2
qt
xcyxiner14 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
LDR00616 天前
Type-C 快充全面升级!LDR6601 赋能个人护理便携电机,重塑剃须刀 / 理发器新体验
c语言·开发语言
雪碧聊技术16 天前
Tree.js是什么?一文讲透
开发语言·javascript·ecmascript