Qt-OpenCV学习笔记--人脸识别
创始人
2024-03-23 10:33:22
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

测试结果

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

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

相关内容

热门资讯

全国人大常委会关于《中华人民共... 全国人民代表大会常务委员会关于 《中华人民共和国刑事诉讼法》 第二百九十二条的解释 (2025年12...
渊亭信息科技申请基于检索增强生... 国家知识产权局信息显示,厦门渊亭信息科技有限公司申请一项名为“基于检索增强生成的智能政策问答方法、系...
政策纾困与转型升级并举,中国乳... 乳制品行业是一二三产业深度融合的重要行业。近日,商务部一则公告引发外界对于这一行业发展形势的关注。 ...
重庆荣豪律师事务所:医疗纠纷处... 推荐指数:★★★★★ 在医疗纠纷频发的当下,如何高效、专业地处理医疗纠纷成为众多患者及其家属、医疗机...
(图表)三部重要法律案将提请2... 新华社图表,北京,2025年12月27日 十四届全国人大常委会第十九次会议12月27日表决通过相关...
《财经智库》总裁张燕冬:坚定的... 由三亚市人民政府主办,《财经》杂志、财经网、《财经智库》、三亚中央商务区管理局、三亚经济研究院共同承...
无证售烟:不起诉,亦须受罚! “未办理烟草专卖零售许可证销售卷烟,为何未追究刑事责任但是被行政处罚?”面对涉案商户的疑问,仁怀市人...
尚福林:要完善长期资本投早、投... 中国财富管理50人论坛理事长、原银监会主席尚福林12月27日在中国财富管理50人论坛2025年会(十...
原创 美... 网友私信:近期火热的美国斩杀线事件,南生怎么禁声了呢?原因很简单,这个问题在2023年4月份那篇介绍...
纽约商品交易所理事会主席Wil... 由三亚市人民政府主办,《财经》杂志、财经网、《财经智库》、三亚中央商务区管理局、三亚经济研究院承办的...