Qt-OpenCV学习笔记--人脸识别

这篇具有很好参考价值的文章主要介绍了Qt-OpenCV学习笔记--人脸识别。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

本人从事机械设计12年,业余时间自学编程。

2022年4月6日,开始学习C#,

2022年9月7日,开始学习c++和Qt,

2022年10月28日,开始学习OpenCV,

今天终于搞定了传说中的 人脸识别 ,在此,做个记录。

人脸检测,是基于Haar特征的cascade分类器,

人脸识别,是基于LDA理论的Fisherface算法。

话不多说,上视频!(CSDN上传的视频,太清晰!)

人脸识别测试程序

测试代码

FaceRecognition.pro

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    sm.cpp \
    widget.cpp

HEADERS += \
    sm.h \
    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

unix|win32: LIBS += -L$$PWD/../../../../../opencv/install/x64/mingw/lib/ -llibopencv_world460.dll

INCLUDEPATH += $$PWD/../../../../../opencv/install/include
DEPENDPATH += $$PWD/../../../../../opencv/install/include

sm.h

#ifndef SM_H
#define SM_H

#include <iostream>
#include "opencv2/core.hpp"



class sm
{
public:
    sm();

    //读取文件
    static void read_csv(const std::string& filename, std::vector<cv::Mat>& images, std::vector<int>& labels, char separator);

    //图像预处理:检测人脸、裁剪、缩放、保存、生成列表
    static void pretreatment(std::vector<cv::Mat> images, std::vector<int> labels,std::string path,int width,int height);

};

#endif // SM_H

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

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

    void on_pushButton_7_clicked();

    void on_pushButton_2_clicked();

    void on_pushButton_3_clicked();

    void on_pushButton_5_clicked();

    void on_pushButton_6_clicked();

private:
    Ui::Widget *ui;
};
#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();
}

sm.cpp

#include "sm.h"

//引用依赖
#include "opencv2/core.hpp"
#include "opencv2/face.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
#include <fstream>
#include <sstream>

#include <QDebug>

sm::sm()
{

}

void sm::pretreatment(std::vector<cv::Mat> images, std::vector<int> labels, std::string path, int width, int height)
{
    cv::Mat dst_shear;
    cv::Mat dst_resize;

    //创建级联分类器
    cv::CascadeClassifier cascade;
    //载入Haar特征分类器
    cascade.load("C:/opencv/date/haarcascade_frontalface_default.xml");
    //创建矩形容器
    std::vector<cv::Rect> rects;
    //遍历
    int flag=1;
    for(uint i=0;i<images.size();i++)
    {
        //人脸检测
        cascade.detectMultiScale(images[i],rects);
        //裁剪
        dst_shear = images[i](rects[0]).clone();
        //缩放
        resize(dst_shear,dst_resize,cv::Size(width,height),0,0,cv::INTER_AREA);
        //保存路径拼接
        std::string im_path1 = std::to_string(labels[i]);
        std::string im_path2 = std::to_string(flag);
        flag++;
        if(labels[i+1]!=labels[i])
        {
            flag=1;
        }
        std::string im_path3 = ".png";
        std::string im_path = path+im_path1+"-"+im_path2+im_path3;

        //调试
        QString qstr_im = QString::fromStdString(im_path);
        qDebug()<<qstr_im;

        //保存
        imwrite(im_path,dst_resize);
        //显示
        //std::string str = std::to_string(i);
        //imshow(str,dst_resize);
        //生成列表文件
        std::string list_name = "list.txt";
        std::string list_path = path + list_name;

        //调试
        QString qstr_list = QString::fromStdString(list_path);
        qDebug()<<qstr_list;

        std::ofstream list(list_path, std::ios::app);
        if (list.fail())
        {
            qDebug()<<"list文件打开失败,请检查文件路径!";
        }
        else
        {
            list<<im_path;
            list<<";";
            list<<im_path1;
            list<<"\n";
        }
    }
}

void sm::read_csv(const std::string &filename, std::vector<cv::Mat> &images, std::vector<int> &labels, char separator)
{
    //以只读方式读取文件
    std::ifstream file(filename, std::ios::in);
    if (!file)
    {
        qDebug()<<"文件打开失败,请检查文件路径!";        
    }
    else
    {
        //逐行读取文本,分离路径和标签
        std::string line, path, classlabel;
        //逐行读取
        while (getline(file, line))
        {
            //将读取到的文本转为字符串流
            std::stringstream stream(line);
            //分离路径
            getline(stream, path, separator);
            //分离标签
            getline(stream, classlabel);
            //若分离成功,则按照路径载入图像,设置标签
            if(!path.empty() && !classlabel.empty())
            {
                images.push_back(cv::imread(path,0));
                labels.push_back(atoi(classlabel.c_str()));
            }
        }
    }
}

widget.cpp

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

//引用
#include "sm.h"

#include "opencv2/core.hpp"
#include "opencv2/face.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"

#include <iostream>
#include <fstream>
#include <sstream>

#include <QFileDialog>
#include <QDebug>
#include <QMessageBox>
#include <qdatetime.h>

//进行人脸识别的路径
QString face_path;

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
}

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

//选择文件
void Widget::on_pushButton_clicked()
{
    QString filename = QFileDialog::getOpenFileName(this,"请选择列表文件",".","*.txt");
    if(!filename.isEmpty())
        {
            ui->lineEdit->setText(filename);

        }
}

//选择保存目录
void Widget::on_pushButton_7_clicked()
{
    QString dir = QFileDialog::getExistingDirectory(this,"请选择保存目录",".");
    if(!dir.isEmpty())
        {
            QString str = dir + "/";
            ui->lineEdit_3->setText(str);

        }
}

//训练模型
void Widget::on_pushButton_2_clicked()
{
    //获取文件路径
    std::string src_filename = ui->lineEdit->text().toStdString();
    if(src_filename.empty())
    {
        QMessageBox::warning(this,"警告","图像载入失败,请检查文件路径!");
        return;
    }
    //图像集合
    std::vector<cv::Mat> src_images;
    //标签集合
    std::vector<int> src_labels;
    //加载文件
    sm::read_csv(src_filename,src_images,src_labels,';');
    //判断读取是否成功
    if(src_images.size()<=1||src_labels.size()<=1)
    {        
        QMessageBox::warning(this,"警告","数据量不足,请检查数据列表!");
        return;
    }

    //调试
    qDebug()<<src_images.size();
    qDebug()<<src_labels.size();

    //获取图像保存路径
    std::string dst_path = ui->lineEdit_3->text().toStdString();
    if(dst_path.empty())
    {
        QMessageBox::warning(this,"警告","请检查文件保存路径!");
        return;
    }
    //图像预处理,生成新文件
    sm::pretreatment(src_images,src_labels,dst_path,100,100);

    //获取新文件路径
    std::string dst_filename = dst_path+"list.txt";
    //新图像集合
    std::vector<cv::Mat> dst_images;
    //新标签集合
    std::vector<int> dst_labels;
    //重新加载文件
    sm::read_csv(dst_filename,dst_images,dst_labels,';');

    // 创建模型
    cv::Ptr<cv::face::FisherFaceRecognizer> model = cv::face::FisherFaceRecognizer::create();
    // 训练模型
    model->train(dst_images, dst_labels);
    //保存模型
    model->write(dst_path+"model.xml");

    //提示
    QMessageBox::information(this,"消息","模型训练完成!");

}

//选择模型路径
void Widget::on_pushButton_3_clicked()
{
    QString filename = QFileDialog::getOpenFileName(this,"请选择模型",".","*.xml");
    if(!filename.isEmpty())
        {
            ui->lineEdit_2->setText(filename);

        }
}

//选择需要识别的图像,缩放,保持比例,显示
void Widget::on_pushButton_5_clicked()
{
    face_path = QFileDialog::getOpenFileName(this,"选择一个图片",".","*.jpg *.png *.bmp");
    if(!face_path.isEmpty())
    {
        //加载图像
        QPixmap* pix= new QPixmap;
        pix->load(face_path);
        //图像缩放
        QPixmap* npix= new QPixmap;
        *npix = pix->scaled(ui->label_4->size(),Qt::KeepAspectRatio);
        //显示
        ui->label_4->setPixmap(*npix);

    }

}

//人脸识别
void Widget::on_pushButton_6_clicked()
{
    cv::Mat src,
            dst_shear,
            dst_resize;


    //创建级联分类器
    cv::CascadeClassifier cascade;
    //载入Haar特征分类器
    cascade.load("C:/opencv/date/haarcascade_frontalface_default.xml");

    //加载图像
    if(face_path.isEmpty())
    {
        QMessageBox::warning(this,"警告","请先选择一个图像!");
        return;
    }
    else
    {
        src = cv::imread(face_path.QString::toStdString(),0);
    }

    //创建矩形容器
    std::vector<cv::Rect> rects;
    //识别人脸
    cascade.detectMultiScale(src,rects);

    //裁剪图像
    dst_shear = src(rects[0]).clone();

    //缩放
    cv::resize(dst_shear,dst_resize,cv::Size(100,100),0,0,cv::INTER_AREA);

    if(ui->lineEdit_2->text().isEmpty())
    {
        QMessageBox::warning(this,"警告","请检查模型加载路径!");
    }
    else
    {
        // 创建模型
        cv::Ptr<cv::face::FisherFaceRecognizer> model = cv::face::FisherFaceRecognizer::create();
        //载入训练好的模型
        model->read(ui->lineEdit_2->text().QString::toStdString());

        //进行识别
        int predictedLabel;
        double confidence;
        model->predict(dst_resize,predictedLabel,confidence);

        //打印结果
        QDateTime cur = QDateTime::currentDateTime();

        QString str;
        switch (predictedLabel)
        {
            case 1:
                str = "周敏慧";
                break;
            case 2:
                str = "林志玲";
                break;
            case 3:
                str = "黄渤";
                break;
            case 4:
                str = "单大伟";
                break;
            default:
                str = "这个人我不认识!";
        }

        ui->textBrowser->append(cur.toString("yyyy-MM-dd hh:mm:ss"));
        ui->textBrowser->append(str);
    }
}

widget.ui

Qt-OpenCV学习笔记--人脸识别

测试结果

Qt-OpenCV学习笔记--人脸识别

        综上,将导入的图像进行裁剪和缩放,仅保存人脸部分,用于训练模型;然后加载训练好的模型,进行人脸识别,最后将识别的信息予以显示。

        代码经过修改,可以用于 门禁系统 或者 人脸打卡文章来源地址https://www.toymoban.com/news/detail-484898.html

到了这里,关于Qt-OpenCV学习笔记--人脸识别的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 简易版人脸识别qt opencv

    1、配置文件.pro 2、头文件 3、源文件 main.app widget.cpp 4、ui界面

    2024年02月09日
    浏览(40)
  • QT连接OpenCV库实现人脸识别

    图像容器: Mat类 读取图像:   命名展示图像的窗口: 展示图像: 示例: 视频流类: VideoCapture 打开视频: 若想要打开摄像头只需在构造时,调用构造函数参数传递0即可 读取视频流中图像:  图像翻转: 休眠阻塞函数: 示例: 灰度处理: 均衡化处理: 示例: opencv级联

    2024年02月09日
    浏览(44)
  • OpenCV+ Qt Designer 开发人脸识别考勤系统

    本系统是一个基于OpenCV和 Qt Designer 的人脸识别考勤系统,主要功能是自动识别摄像头中的人脸,并把人脸对应的姓名和打卡时间存储到数据库中,方便管理人员进行考勤管理。本系统使用 face_recognition 库进行人脸识别,使用 PyQt5 开发界面,然后把界面与代码进行整合。 系统

    2024年02月06日
    浏览(51)
  • OpenCV+Ubuntu+QT实现人脸检测/识别(考勤管理)

    下载完成后在下载目录打开终端,赋予可执行权限,再执行即可安装qt sudo chmod +x qt-opensource-linux-x64-5.12.8.run 可参考文章 若按照上述方法安装好opencv,创建测试项目,在pro文件中加入: 测试: (若出现警告 “VIDEOIO(V4L2:/dev/video0): select() timeout”,在虚拟机-设置-USB控制器,更

    2024年01月22日
    浏览(44)
  • (项目笔记)opencv人脸识别

    Haar级联: Haar特征:边缘特征,线性特征,中心环绕特征,对角线特征 这些特征组合为特征模板,特征模板里有白色和黑色矩形,模板特征即为白色矩形像素和减去黑色矩形像素和。 Haar 特征的提取简单说就是通过不断改变模版的大小、位置和类型,白色矩形区域像素和‘减

    2024年02月05日
    浏览(42)
  • opencv系列(1)--使用opencv和Qt6做一个视频监控器人脸识别

    这个程序是自己的下班之后,看看那个坏东西想来偷看我的电脑。我就随手做的一个程序。 1.能都显示摄像头的内容。 2.如果有人进入摄像头。 3.利用opencv的模型识别人脸,识别到了就保存到自己的电脑里面。 4.并把他的照片显示到界面上一段时间,告诉他,偷窥有罪。 5.程

    2024年02月11日
    浏览(34)
  • 嵌入式Linux:ARM驱动+QT应用+OpenCV人脸识别项目实现

            这个项目主要分为两部分,客户端(ARM板端)负责利用OpenCV采集人脸数据,利用TCP将人脸数据发送给服务器,然后服务器根据人脸数据进行人脸识别,将识别后的结果返还给客户端,客户端对人脸数据进行解析,得到正确的人脸数据后,打开门锁。门锁涉及硬件操作

    2024年02月10日
    浏览(44)
  • 【深度学习】基于Qt的人脸识别系统,门禁人脸识别系统,Python人脸识别流程,树莓派

    在深度学习领域做人脸识别的识别准确率已经高到超出人类识别,但综合考虑模型复杂度(推理速度)和模型的识别效果,这个地方还是有做一些工作的需求的。 人脸识别的过程基本由下面的流程组成。 yolov5-face、yolov7-face等github项目都可以做到这一点,在公开数据集上训练

    2024年02月09日
    浏览(50)
  • 人脸识别实战:使用Python OpenCV 和深度学习进行人脸识别

    首先简要讨论基于深度学习的面部识别的工作原理,包括“深度度量学习”的概念。 然后,我将帮助您安装实际执行人脸识别所需的库。 最后,我们将为静止图像和视频流实现人脸识别。 安装人脸识别库 ================================================================== 为了使用 Python 和

    2024年04月09日
    浏览(91)
  • 竞赛选题 基于深度学习的人脸性别年龄识别 - 图像识别 opencv

    🔥 优质竞赛项目系列,今天要分享的是 🚩 毕业设计 人脸性别年龄识别系统 - 图像识别 opencv 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🥇学长这里给一个题目综合评分(每项满分5分) 难度系数:3分 工作量:3分 创新点:3分 🧿 更多资料, 项目分享: https

    2024年02月07日
    浏览(66)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包