Qt-OpenCV学习笔记--人脸识别
创始人
2024-03-23 10:07:33

前言

本人从事机械设计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

测试结果

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

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

相关内容

热门资讯

计划投放KOL遭粉丝抵制,小米... 1月6日,小米公司发言人昨天关于团队与相关KOL接触一事,公司立刻启动了专项调查,有了初步结论,公关...
亚洲最大室内儿童主题乐园今年开... (来源:千龙网)记者昨天(6日)从正在召开的北京通州区两会上了解到,副中心今年将加快文化旅游区优质资...
今日视点:三力齐发 助中国科技...   ■ 贾 丽  1月6日,被誉为“科技春晚”的国际消费电子展(CES)在美国拉斯维加斯拉开帷幕,中...
美国染指委石油资源的心机与困境 (来源:辽宁日报)转自:辽宁日报 这是1月3日在委内瑞拉首都加拉加斯拍摄的空旷街头。 ...
“潮汐工作法”应对节后上牌高峰 (来源:河北日报)转自:河北日报石家庄车管所“潮汐工作法”应对节后上牌高峰 本报讯(记者桑珊...