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);


}
相关推荐
Geek之路28 分钟前
QT-多线程、线程池的使用
qt·多线程
凯子坚持 c1 小时前
C语言复习概要(四)
c语言·开发语言
何陈陈1 小时前
【Linux】线程池
linux·服务器·开发语言·c++
清风玉骨1 小时前
Qt-QHBoxLayout布局类控件(42)
开发语言·qt
夏旭泽1 小时前
C-include
开发语言·c++
通信仿真实验室1 小时前
MATLAB使用眼图分析QPSK通信系统接收端匹配滤波后的信号
开发语言·算法·matlab
感谢地心引力1 小时前
【Qt】Qt安装(2024-10,QT6.7.3,Windows,Qt Creator 、Visual Studio、Pycharm 示例)
c++·windows·python·qt·visual studio
通信仿真实验室2 小时前
(15)衰落信道模型作用于信号是相乘还是卷积
开发语言·人工智能·算法·matlab
远望樱花兔2 小时前
【d59】【Java】【力扣】146.LRU缓存
java·开发语言·算法
Bruce_Liuxiaowei2 小时前
Python小示例——质地不均匀的硬币概率统计
开发语言·python·概率统计