• 基于OpenCV+QT的人脸识别打卡项目


    1.基本概念

    基于OpenCV的人脸识别是一个多步骤的过程,通常涉及以下步骤:

    1. 人脸检测:使用Haar级联或深度学习模型来检测图像中的面部区域。OpenCV提供了预训练的Haar级联分类器,可以用于快速检测。

    2. 特征提取:一旦检测到人脸,就需要从人脸图像中提取特征。特征提取可以使用多种方法,如LBP(局部二值模式)、HOG(方向梯度直方图)或更先进的深度学习方法。

    3. 人脸识别:使用特征匹配或机器学习模型来识别检测到的面部。可以使用如支持向量机(SVM)、k-最近邻(k-NN)、神经网络等方法。

    4. 训练模型:在实际应用中,通常需要收集一些人脸图像来训练识别模型。训练过程中,模型会学习区分不同的人脸。

    5. 实时识别:在训练完成后,可以使用模型进行实时人脸识别。这可以用于多种应用,如安全监控、身份验证等。

    2.项目展示

    (1)打开QT,并运行项目,把电脑摄像头对准人脸

    (2)输入要录入人的姓名,输入完之后点击录入,录入完之后会有提示

    (3)成功录入之后,就可以进行打卡了,把摄像头对准人脸,等待识别,识别成功就签到成功了

    (4) 打卡签到成功之后,点击打卡时间就可以查看打卡历史记录。

    3.项目开发流程

    (1)准备工作

     pro文件配置:加载OpenCV文件路径

    INCLUDEPATH += D:/opencv/opencv3.4-install/install/include

    INCLUDEPATH += D:/opencv/opencv3.4-install/install/include/opencv

    INCLUDEPATH += D:/opencv/opencv3.4-install/install/include/opencv2

    LIBS += D:/opencv/opencv3.4-install/install/x86/mingw/lib/libopencv_*.a

     头文件支持

    #include 

    #include 

    #include 

    #include 

    #include 

    #include 

    #include 

    #include 

    #include 

    using namespace cv::face;

    using namespace cv;

    using namespace std;

    (2)QT的UI界面

    (3)摄像头初始化模块

    mainwindow.h添加:

    //定义摄像头的初始化

    private:

        void initVideoCapture();

    //定义视频流工具对象属性

    private:

    VideoCapture vc;

    mainwindow.c添加:

    //实现摄像头初始化函数

    void MainWindow::initVideoCapture(){

        //打开摄像头,摄像头标识是0号

        //打开摄像头

        if(vc.open(0) == false){

            //输出内容

            qDebug() << "call initVideoCapture open error";

            //返回

            return;

        }else{

            //输出内容

            qDebug() << "call initVideoCapture open ok";

        }

    }

     

    (4)级联分类器初始化模块

    mainwindow.h添加:

    //定义级联分类器对象的初始化

    private:

        void initCascadeClassifier();

    //定义级联分类器对象:人脸识别工作

    private:

    CascadeClassifier classifier;

    mainwindow.c添加:

    //实现级联分类器对象的初始化

    void MainWindow::initCascadeClassifier(){

        //分类:人脸

        //分类配置:人脸配置

        //人脸配置文件位置:D:/opencv/heads/haarcascade_frontalface_alt2.xml

        //通过配置文件haarcascade_frontalface_alt2.xml创建级联分类器对象

        classifier = CascadeClassifier(FACETOOL);

        //参数1:人脸识别的配置文件

        //CascadeClassifier工具类

        //CascadeClassifier()工具类的构造器方法

        //判断级联分类器对象classifier是否创建成功

        if(classifier.empty() == true){

             //输出内容

            qDebug() << "call initCascadeClassifier classifier error";

            return;

        }else{

            //输出内容

            qDebug() << "call initCascadeClassifier classifier ok";

        }

    }

    (5)人脸识别器初始化模块

    mainwindow.h添加:

    //定义人脸识别器的初始化

    private:

        void initFaceRecognizer();

    //定义人脸识别器的对象的指针变量

    Ptr<FaceRecognizer> recognizer;

    mainwindow.c添加:

    //实现人脸识别器的初始化

    void MainWindow::initFaceRecognizer(){

        //训练的模型存储的地方:D:/opencv/heads/myface.xml

        //访问模型文件,关联模型文件

        QFile file("D:/opencv/heads/myface.xml");

        //QFile是文件管理工具类

        //file是文件管理工具类的对象

        //file()构建文件管理工具对象的构造器

        //参数:要管理的文件的路径

        //判断文件是否存在

        if(file.exists() == true){

            //输出内容

            qDebug() << "call initFaceRecognizer file exist";

            //加载模型创建人脸识别器对象

            recognizer = FaceRecognizer::load<LBPHFaceRecognizer>("D:/opencv/heads/myface.xml");

            //FaceRecognizer 人脸识别器工具类的基类

            //load()方法是加载模型的方法,创建一个人脸识别器对象

            //LBPHFaceRecognizer是人脸识别器的子类

            //参数1:模型的路径

            //模型文件:xxx.xml

            //输出内容

            qDebug() << "call initFaceRecognizer load myface.xml";

        }else{

            //输出内容

            qDebug() << "call initFaceRecognizer file not exist";

            //创建人脸识别器对象

            recognizer = LBPHFaceRecognizer::create();

            //create()方法是创建人脸识别器对象的方法

            //输出内容

            qDebug() << "call initFaceRecognizer LBPHFaceRecognizer create";

        }

    }

    (6)定时器模块

    mainwindow.h添加:

    //定义定时器标识属性

    private:

    Mat src;//定义摄像头读取的图像

    //声明定时器处理方法(定时器事件触发)

    private:

    void timerEvent(QTimerEvent *e);

    mainwindow.c添加:

    //定时器处理方法实现

    void MainWindow::timerEvent(QTimerEvent *e){

        vc>>src;//读取图像

        if(src.empty())//判断是否加载到了图像

            return;

    flip(src,src,1);//翻转摄像头

    //重置图像大小

        cv::resize(src,src,Size(600,600));

    }

    (7)人脸绘制模块

    mainwindow.h添加:

    private:

     Rect ret;//定义有效矩形

    private:

     void blackSrc();//画有效区域


    mainwindow.cpp添加:
    void MainWindow::blackSrc()

    {

        //创建矩形对象

        ret = Rect(src.cols/2-150,src.rows/2-150,300,300);

        //画白框

        rectangle(src,ret,Scalar(255,255,255),2);

        //遍历像素点

        for(int i=0;i<src.cols;i++)

        {

            for(int j=0;j<src.rows;j++)

            {

                //判断是否在有效区域内

                if(!ret.contains(Point(i,j)))

                {

                    //修改像素点的值

                    src.at<Vec3b>(j,i)[0] = saturate_cast<uchar>(src.at<Vec3b>(j,i)[0]-50);//蓝色

                    src.at<Vec3b>(j,i)[1] = saturate_cast<uchar>(src.at<Vec3b>(j,i)[1]-50);//绿色

                    src.at<Vec3b>(j,i)[2] = saturate_cast<uchar>(src.at<Vec3b>(j,i)[2]-50);//红色

                }

            }

        }

    }

    补充代码:

    //定时器处理方法实现

    void MainWindow::timerEvent(QTimerEvent *e){

        vc>>src;//读取图像

        if(src.empty())//判断是否加载到了图像

            return;

        flip(src,src,1);//翻转摄像头

    //重置图像大小

        cv::resize(src,src,Size(600,600));

    blackSrc();

    }

    (8)人脸识别模块

    mainwindow.h添加:

    //定义人脸查找方法

    private:

        void findFace();

    //定义属性存储摄像头数据

    private:

        Mat mid;//定义图像对象

    //定义属性存储摄像头人脸的位置关系

    private:

        vector<Rect> faces;

    mainwindow.c添加:

    void MainWindow::findFace()

    {

        //创建灰度图对象

        Mat gray;

        //截取有效区域内图像

        mid = src(ret);

        //色彩空间转换

        cvtColor(mid,gray,CV_BGR2GRAY);

        //检测函数来获取人脸矩形

        classifier.detectMultiScale(gray,faces);

        //给人脸矩形画红框

        if(faces.size()>0)//判断是否找到人脸

            rectangle(mid,faces[0],Scalar(0,0,255),2);

    }

    补充代码:

    //定时器处理方法实现

    void MainWindow::timerEvent(QTimerEvent *e){

        vc>>src;//读取图像

        if(src.empty())//判断是否加载到了图像

            return;

    flip(src,src,1);//翻转摄像头

    //重置图像大小

        cv::resize(src,src,Size(600,600));

    blackSrc();

    findFace();

    }

    (9)人脸显示模块

    mainwindow.h添加:

    //定义人脸显示函数

    private:

    void showImage();//显示图像

    mainwindow.cpp添加:

    //实现人脸显示功能

    void MainWindow::showImage()

    {

        //qt : rgb   opencv :bgr

        Mat rgb;

        //色彩空间转换

        cvtColor(src,rgb,CV_BGR2RGB);

        //Mat->QImage

        QImage img(rgb.data,rgb.cols,rgb.rows,rgb.cols*rgb.channels(),QImage::Format_RGB888);

        //QImage->QPixmap

        QPixmap p = QPixmap::fromImage(img);

        //显示图像

        ui->label_video->setPixmap(p);

    }

    补充代码:

    //定时器处理方法实现

    void MainWindow::timerEvent(QTimerEvent *e){

        vc>>src;//读取图像

        if(src.empty())//判断是否加载到了图像

            return;

        flip(src,src,1);//翻转摄像头

    blackSrc();

    findFace();

    showImage();

    }

    (10)按键的槽函数实现

    mainwindow.h添加:

    //定义自定义定时器

         QTimer studyTimer;

    mainwindow.cpp添加:

    void MainWindow::on_pushButton_insert_clicked()

    {

        studyTimer.start(1000);//开启机械学习定时器,每一秒执行一次

    }

    //自定义定时器的连接函数

        connect(&studyTimer,SIGNAL(timeout()),this,SLOT(slot_luru()));

    (11)机器学习模块

    mainwindow.h添加:

    //定义人脸查找方法

    private:

        void slot_luru(); 

    private:

    //定义属性存储摄像头人脸face内容

        vector studyFaces;

        //定义属性存储摄像头人脸对应的id

         int id;

    bool isLuru;//定义学习状态变量

    mainwindow.c添加:

    //实现机器学习功能

    void MainWindow::slot_luru()

    {

        if(faces.size()<=0)

            return;

        if(studyFace.size() == 10)

        {

            studyTimer.stop();//停止机械学习

            vector<int> labels;//保存标签的容器

            //从ui端获取名字

            QString name = ui->lineEdit_name->text();

            //更新人员表

            ManagerFactory::getIns()->user->insertUser(name);

            //获取当前的用户id

            id = ManagerFactory::getIns()->user->selectId();

            //往容器中插入标签 插入10个一样的标签

            labels.insert(labels.begin(),10,id);

            //学习并且更新模型文件

            recognizer->update(studyFace,labels);

            recognizer->save("face.xml");//保存模型文件

            //提示:录入成功  #include 

            QMessageBox::information(this,"提示","恭喜,录入人员成功");

            ui->lineEdit_name->clear();//清空单行输入框

            studyFace.clear();//清空容器

            isLuru = false;//推出学习状态

        }

        else

        {

            Mat face = mid(faces[0]);//截取人脸矩形的部分

            //色彩空间转换

            cvtColor(face,face,CV_BGR2GRAY);

            //统一尺寸

            cv::resize(face,face,Size(100,100));

            //存放在容器

            studyFace.push_back(face);

            qDebug()<<studyFace.size();

        }

    }

    (12)人脸预测模块

    mainwindow.h添加:

    //对应方法完成预测功能

    private:

       void checkFace();

    mainwindow.cpp添加:

    void MainWindow::checkFace()

    {

        //找不到人脸      机械学习状态   人脸识别器为空

        if(faces.size()<=0 || isLuru || recognizer->empty())

        {

            return;

        }

        //1.截取人脸区域

        Mat face = src(faces[0]);

        //色彩空间转换

        cvtColor(face,face,CV_BGR2GRAY);

        //与机械学习时的尺寸同一

        cv::resize(face,face,Size(100,100));

        //给标签 和可信度 设定初始值

        int label = -1;

        double confidence =0;

        //预测人脸

        recognizer->predict(face,label,confidence);

        qDebug()<<confidence;

        //提示打卡信息

        if(label != -1 && confidence < 150)

        {

            //获取下名字

            QString name = ManagerFactory::getIns()->user->selectName(label);

            //拼接显示标题

            QString str = name + "已签到";

            //用消息提示框提示签到成功

    QMessageBox::warning(this,str,QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));

            //往时间记录表中插入数据

            ManagerFactory::getIns()->time->insertTime(name);

        }

    }

    结语

    以上就是人脸识别的主要内容,本次代码分享到此结束,有需要源码的请联系我VX:gfx2503654393 。最后的最后,还请大家点点赞,点点关注,谢谢大家!

  • 相关阅读:
    企业常用Linux三剑客awk及案例/awk底层剖析/淘宝网cdn缓存对象分级存储策略案例/磁盘知识/awk统计与计算-7055字
    21款奔驰EQC350升级原厂360全景影像 感受上帝视野
    一、初识PyQt
    全志R128芯片应用开发案例——ADC驱动烟雾传感器
    人工神经网络技术及应用,人工神经网络应用场景
    基于python知识库管理系统设计(含源码)
    Vue的仓库vuex
    洗地机哪个好用?2023年洗地机推荐指南
    线性表-单链表-C语言实现
    java在线影院系统计算机毕业设计MyBatis+系统+LW文档+源码+调试部署
  • 原文地址:https://blog.csdn.net/m0_74055118/article/details/138154433