Qt 基于opencv的人脸识别

.pro文件

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    widget.cpp

HEADERS += \
    widget.h

FORMS += \
    widget.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

INCLUDEPATH += D:/opencv/opencv3.4-qt-intall/install/include
INCLUDEPATH += D:/opencv/opencv3.4-qt-intall/install/include/opencv
INCLUDEPATH += D:/opencv/opencv3.4-qt-intall/install/include/opencv2
LIBS += D:/opencv/opencv3.4-qt-intall/install/x86/mingw/lib/libopencv_*.a

.h文件 

#ifndef WIDGET_H
#define WIDGET_H

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

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void on_openBtn_clicked();

    void on_closeBtn_clicked();

    void on_faceBtn_clicked();

private:
    Ui::Widget *ui;

    //=========摄像头相关成员设置===============//
    VideoCapture v;  //摄像头容器
    Mat src; //存放原图的容器
    Mat gray; //存放灰度图容器
    Mat dst; //存放直方图容器
    Mat rgb; //存放rgb图容器
    CascadeClassifier c; //定义级联分级容器  ---- 获取图像上的矩形框
    vector<Rect> faces; //定义一个数组存放人脸矩形框
    int camera_id ; //启动摄像头的定时器 id
    void timerEvent(QTimerEvent *e); //定时器事件 重写函数事件
    //===============人脸信息录入相关成员的设置============//
    Ptr<LBPHFaceRecognizer> recognizer;  //人脸 识别器指针
    vector<Mat> study_faces;    //定义一个存放录入人脸的数组
    vector<int> study_labels;   //定义一个存放人脸对应的标签数组
    int count = 0;    //记录录入人脸的次数
    int flag;     //用来区别是人脸录入还是人脸识别
    int face_id;   //人脸录入定时器id  ---- study_timer_id
    //===============================================//

    int check_id; //人脸检测定时器的id


};
#endif // WIDGET_H

main.cpp

#include "widget.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}

 widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    ui->wchatBtn->setEnabled(false);
    //打开系统摄像头
    if(!v.open(0))
    {
        QMessageBox::information(this,"","打开系统摄像头失败");
        return;
    }
    //配置级联分类器
    if(!c.load("D:\\opencv\\image\\haarcascade_frontalface_alt.xml"))
    {
        QMessageBox::information(this,"","配置级联分类器失败");
        return;
    }
    //将摄像头捕获的图像一帧一帧的放入到label中去

    //判断是否录入过人脸
    QFile file("D:\\opencv\\image\\m_face.xml");
    //判断文件是否存在
    if(file.exists())
    {
        //表示之前录入过人脸  则下载文件
        recognizer = LBPHFaceRecognizer::load<LBPHFaceRecognizer>("D:\\opencv\\image\\my_face.xml");
    }
    else
    {
        //表示之前没有录入过人脸,则创建
        recognizer = LBPHFaceRecognizer::create();
    }

    //启动人脸识别开始的定时器
    check_id = startTimer(3000);
    flag = 1; //表示可以人脸检测
    recognizer->setThreshold(100);

}

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


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

//定时器重写的函数
void Widget::timerEvent(QTimerEvent *e)
{
    //判断是否摄像头定时器超时
    if(e->timerId() == camera_id)    //camera_id 20 ms 一个
    {
        //读取系统摄像头中的图像
        v.read(src);
        //翻转图像
        flip(src,src,1); //1 表示沿y轴反转
        //将bgr图转换成rgb图
        cvtColor(src,rgb,CV_BGR2RGB);  //最后一个参数是枚举
        //重新设置图像的大小,以便适应label
        cv::resize(rgb,rgb,Size(300,200)); //最后一个参数是匿名对象
        cvtColor(rgb,gray,CV_RGB2GRAY);
        //均衡化处理
        equalizeHist(gray,dst);

        //锁定人脸矩形框位置---锁定人脸矩形框之前,灰度处理
        c.detectMultiScale(dst,faces);
        //将矩形框绘制到人脸上
        for(uint i=0; i<faces.size(); i++)
        {
            rectangle(rgb,faces[i],Scalar(255,0,0),2);
        }
        //将图像放入label中
        //rgb图像转换成pixmap
        QImage img(rgb.data,rgb.cols,rgb.rows,rgb.cols*rgb.channels(),QImage::Format_RGB888);
        ui->label->setPixmap(QPixmap::fromImage(img));

    }
    //判断是否是人脸录入 定时器超时
    if(e->timerId() == face_id )   // face_id  50 ms 一次人脸检测
    {
        if(0 == flag)
        {
            qDebug() << "人脸录入中,请正视摄像头";
            Mat face = src(faces[0]);  //将摄像头当前的一帧图像上的人脸给face
            //灰度处理
            cvtColor(face,face,CV_BGR2GRAY);
            //均衡化处理得到直方图
            equalizeHist(face,face);
            //将当前采集的人脸信息,放入study_face容器里
            study_faces.push_back(face);
            study_labels.push_back(1);
            count++;
            if(50 == count)
            {
                qDebug() << "count == 50";
                //将图像模型转换成数据模型
                recognizer->update(study_faces,study_labels);
                recognizer->save("D:\\opencv\\image\\my_face.xml");
                QMessageBox::information(this,"","录入人脸成功!");
                //关闭定时器
                killTimer(face_id);
                //可以录入人脸
                flag = 1;  //表示可以进行人脸检测了
                study_faces.clear();
                study_labels.clear();
                count = 0;

            }
        }
    }
    if(check_id == e->timerId())
    {
        if(1 == flag)
        {
            QFile file("D:\\opencv\\image\\my_face.xml");
            if(file.exists())
            {
                if(recognizer->empty() || faces.empty())
                {
                    return;
                }
                Mat face = src(faces[0]);
                //灰度处理
                cvtColor(face,face,CV_BGR2GRAY);
                equalizeHist(face,face);

                int lab = -1;
                double cof = 0.0;
                recognizer->predict(face,lab,cof);
                //根据lab判断是否识别成功
                if(-1 != lab)
                {
                    QMessageBox::information(this,"","Welcome!!");
                    ui->wchatBtn->setEnabled(true);
                    killTimer(check_id);
                }
            }


        }

    }

}





//关闭摄像头按钮对应的槽函数
void Widget::on_closeBtn_clicked()
{
    killTimer(camera_id);
}








//录入人脸信息按钮对应的槽函数
void Widget::on_faceBtn_clicked()
{
    count = 0;   //将录入人脸的次数 置为0
    flag = 0;    //表示只能做人脸录入,不能做人脸检测
    face_id = startTimer(50);  //50 ms 启动一个人脸检测器
}












  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值