前言

本人从事机械设计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 <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_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 <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学习笔记--人脸识别相关推荐

  1. QT+opencv学习笔记(5)——霍夫直线检测、圆检测及椭圆检测

    开发环境为:win10+QT5.8+opencv3.2 Hough变换是图像处理中从图像中识别几何形状的基本方法之一,应用很广泛.最基本的Hough变换是从黑白图像中检测直线,还可以经过改进检测圆.椭 ...

  2. OpenCV学习笔记(二十一)——绘图函数core OpenCV学习笔记(二十二)——粒子滤波跟踪方法 OpenCV学习笔记(二十三)——OpenCV的GUI之凤凰涅槃Qt OpenCV学习笔记(二十

    OpenCV学习笔记(二十一)--绘图函数core 在图像中,我们经常想要在图像中做一些标识记号,这就需要绘图函数.OpenCV虽然没有太优秀的GUI,但在绘图方面还是做得很完整的.这里就介绍一下相关 ...

  3. Qt+openCV学习笔记(五)Qt5.15.2+openCV4.5.4+VS2019_64编译动态库

    前言 opencv官方只提供基本的库,若是用到其他库,需要自己编译.通常只要编译自己需要的模块就可以了,本次编译过程可供大家参考 本次编译的,是未带CUDA加速的版本 假设Qt.VS2019已正常安装 ...

  4. Opencv学习1.人脸识别模块

    Modules: 把模块放在一起就变成了一个包或者一个库 在模块内我们可以实现很多功能 比如查找颜色,找到x,y位置等等 在Main Code中,我们调用模块里面的内容 下面进入正题: 重要的函数: ...

  5. python dlib caffe人脸相似度_基于深度学习的人脸识别系统(Caffe+OpenCV+Dlib)【一】如何配置caffe属性表...

    前言 基于深度学习的人脸识别系统,一共用到了5个开源库:OpenCV(计算机视觉库).Caffe(深度学习库).Dlib(机器学习库).libfacedetection(人脸检测库).cudnn(gp ...

  6. 基于深度学习的人脸识别系统(Caffe+OpenCV+Dlib)【三】VGG网络进行特征提取

    前言 基于深度学习的人脸识别系统,一共用到了5个开源库:OpenCV(计算机视觉库).Caffe(深度学习库).Dlib(机器学习库).libfacedetection(人脸检测库).cudnn(gp ...

  7. 基于深度学习的人脸识别系统系列(Caffe+OpenCV+Dlib)——【六】设计人脸识别的识别类...

    前言 基于深度学习的人脸识别系统,一共用到了5个开源库:OpenCV(计算机视觉库).Caffe(深度学习库).Dlib(机器学习库).libfacedetection(人脸检测库).cudnn(gp ...

  8. opencv学习笔记五--文件扫描+OCR文字识别

    opencv学习笔记五--文件扫描+OCR文字识别 文件扫描 定义函数 边缘检测 获取轮廓 变换 OCR文字识别 环境配置 代码 文件扫描 # 导入工具包 import numpy as np imp ...

  9. dlib 使用OpenCV,Python和深度学习进行人脸识别 源代码

    请直接访问原文章 dlib 使用OpenCV,Python和深度学习进行人脸识别 源代码 https://hotdog29.com/?p=595 在 2019年7月7日 上张贴 由 hotdog发表回 ...

最新文章

  1. split join append
  2. UA MATH571A 回归分析 概念与R code总结
  3. java 接口防刷_java轻量级接口限流/防刷插件
  4. python获取服务器文件svn版本信息_如何编程获取SVN版本号?
  5. Spring Data Jpa 审计功能
  6. 运行jar包提示找不到.properties文件的问题
  7. 字节跳动面试官:千峰java培训多少钱
  8. 【One by one系列】一步步部署.net core应用
  9. 模式识别+Matlab 最大似然分类(MLC)【贝叶斯(Bayes)分类法】
  10. cadence17.4 下载安装
  11. c语言的开方程序,详细解析C语言中的开方实现
  12. 实操调试成功 基于NI-VISA的USBTMC接口程控仪器连接
  13. 华为的薪酬体系整体框架,值得收藏
  14. nutch2.3 mysql教程_Nutch2.2.1+MySQL+Solr4.10.3安装部署
  15. Meta-learning algorithms for Few-Shot Computer Vision论文解读(三)
  16. erp系统 服务器配置,erp系统需要服务器配置
  17. 迅雷种子为什么php文件后缀,迅雷BT文件后缀是什么?
  18. 概率论考点之相关系数
  19. 学习自旋电子学的笔记01:微磁模拟软件OOMMF的教程(中文版)10-15章
  20. 最适合物联网LOT的开源数据库

热门文章

  1. 计算机视觉中的算法幻想性视错觉
  2. Unity3D导航网格,矩阵旋转,欧拉旋转
  3. 浅谈Google认证失败项分析
  4. 2015年12月7日
  5. 关于nslookup 网址 一直出现unknown的问题排查
  6. 智能合约BSC添加流动性
  7. 【渝粤教育】国家开放大学2018年秋季 1315T社会调查方法 参考试题
  8. java计算机毕业设计中山乡村文化旅游网络平台源码+数据库+系统+lw文档
  9. Chapter3:DataLinkLayer_LLC:计网笔记
  10. 时序约束之 set_max_delay / set_min_delay