Qt-OpenCV学习笔记--人脸识别
创始人
2024-03-23 11:59:41
0

前言

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

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

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

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

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

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

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

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

人脸识别测试程序

测试代码

FaceRecognition.pro

QT       += core guigreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsCONFIG += 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.0SOURCES += \main.cpp \sm.cpp \widget.cppHEADERS += \sm.h \widget.hFORMS += \widget.ui# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += targetunix|win32: LIBS += -L$$PWD/../../../../../opencv/install/x64/mingw/lib/ -llibopencv_world460.dllINCLUDEPATH += $$PWD/../../../../../opencv/install/include
DEPENDPATH += $$PWD/../../../../../opencv/install/include

sm.h

#ifndef SM_H
#define SM_H#include 
#include "opencv2/core.hpp"class sm
{
public:sm();//读取文件static void read_csv(const std::string& filename, std::vector& images, std::vector& labels, char separator);//图像预处理:检测人脸、裁剪、缩放、保存、生成列表static void pretreatment(std::vector images, std::vector labels,std::string path,int width,int height);};#endif // SM_H

widget.h

#ifndef WIDGET_H
#define WIDGET_H#include QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic: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 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 
#include 
#include #include sm::sm()
{}void sm::pretreatment(std::vector images, std::vector 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 rects;//遍历int flag=1;for(uint i=0;i &images, std::vector &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 
#include 
#include #include 
#include 
#include 
#include //进行人脸识别的路径
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 src_images;//标签集合std::vector 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()<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 dst_images;//新标签集合std::vector dst_labels;//重新加载文件sm::read_csv(dst_filename,dst_images,dst_labels,';');// 创建模型cv::Ptr 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 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 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

测试结果

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

        代码经过修改,可以用于 门禁系统 或者 人脸打卡

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...
【Ctfer训练计划】——(三... 作者名:Demo不是emo  主页面链接:主页传送门 创作初心ÿ...