• QT连接OpenCV库完成人脸识别


    1.相关的配置

    1> 该项目所用环境:qt-opensource-windows-x86-mingw491_opengl-5.4.0

    2> 配置opencv库路径:

    1、在D盘下创建一个opencv的文件夹,用于存放所需材料

    2、在opencv的文件夹下创建一个名为:opencv3.4-qt-intall 文件夹

    3、将资料中的opencv_library的install文件,复制到opencv3.4-qt-intall 文件夹中

    4、将路径:D:\opencv\opencv3.4-qt-intall\install\x86\mingw\bin 放入电脑的系统路径中

    3> 测试是否配置好

    创建一个新的qt工程,将对应配置文件和头文件放入后,不报错就说明配置成功

    2.关于图像处理的相关类和函数 

    1> Mat类,图像容器
    2> 读取图像
    1. Mat imread( const String& filename, int flags = IMREAD_COLOR );
    2. //功能:读取出图像
    3. //参数:图像路径
    4. //返回值:读取的图像
    3> 命名展示图像的窗口 
    1. void namedWindow(const String& winname, int flags = WINDOW_AUTOSIZE);
    2. 功能:命名一个图像窗口
    3. 参数1:窗口名称
    4. 参数2:窗体尺寸,默认为自适应大小
    5. 返回值:无
    4> 展示图像 
    1. void imshow(const String& winname, const ogl::Texture2D& tex);
    2. //功能:展示图像
    3. //参数1:要展示图像的窗口名称
    4. //参数2:要展示的二维图像
    5. //返回值:无
    1. #include "widget.h"
    2. #include
    3. int main(int argc, char *argv[])
    4. {
    5. QApplication a(argc, argv);
    6. Widget w;
    7. w.show();
    8. //1、定义一个图像容器
    9. Mat src;
    10. //2、将图像加载进来
    11. //函数原型:Mat imread( const String& filename, int flags = IMREAD_COLOR );
    12. //参数:图像的路径
    13. //返回值:图像容器
    14. src = imread("D:/opencv/resource/age.jpg");
    15. //4、命名一个展示图像的窗口
    16. //namedWindow("Test");
    17. //5、展示图像
    18. //函数原型:void imshow(const String& winname, const ogl::Texture2D& tex);
    19. //参数1:要展示图像的窗口名称
    20. //参数2:要展示的图像
    21. //返回值:无
    22. imshow("Test", src);
    23. return a.exec();
    24. }

     3.视频流相关类和函数

    1> 视频流类:VideoCapture
    2> 打开视频:
    1. virtual bool open(const String& filename);
    2. //参数:要打开视频的路径
    3. //返回值:成功返回true失败返回false
    3> 打开摄像头只需在构造时,调用构造函数参数传递0即可
    4> 读取视频流中图像
    1. virtual bool read(OutputArray image);
    2. 功能:读取视频流中的图像
    3. 参数:图像容器
    4. 返回值:成功读取返回true,失败或者视频结束返回false
     5> 图像翻转
    1. void flip(InputArray src, OutputArray dst, int flipCode);
    2. //将图像进行旋转
    3. //参数1:要处理的图像
    4. //参数2:处理后的图像容器
    5. //参数3:处理规则:0:表示沿x翻转,1表示沿y轴翻转,-1表示沿xy轴翻转
    6> 休眠阻塞函数
    1. int waitKey(int delay = 0);
    2. 功能:阻塞等待用户输入数据,如果delay=0,则一直等待
    3. 参数:毫秒数
    4. 返回值:在等待过程中用户按下键的值
    1. #include "widget.h"
    2. #include
    3. int main(int argc, char *argv[])
    4. {
    5. QApplication a(argc, argv);
    6. Widget w;
    7. w.show();
    8. //1、定义视频流对象
    9. VideoCapture v(0); //表明使用摄像头构造一个视频流对象
    10. //2、读取摄像头中的图像
    11. Mat src; //用于存放读取出来的图像
    12. //函数原型:virtual bool read(OutputArray image);
    13. //功能:从视频流中读取一张图像放入参数中
    14. //参数:图像容器
    15. //返回值:成功返回真,失败或者读取视频结束返回假
    16. while(v.read(src))
    17. {
    18. //将图像进行翻转
    19. //函数原型:void flip(InputArray src, OutputArray dst, int flipCode);
    20. //参数1:要翻转的图像
    21. //参数2:翻转后的图像容器
    22. //参数3:翻转规则:正数表示按y轴翻转,0表示按x轴翻转,负数表示按xy轴翻转
    23. flip(src, src, 1);
    24. //展示图像
    25. imshow("Test1", src);
    26. //加延时函数
    27. //函数原型:int waitKey(int delay = 0);
    28. //参数:等待时间
    29. //返回值:在等待期间用户按下的键盘的ascii值 ESC键对应的值为27
    30. if(waitKey(20)==27)
    31. {
    32. break;
    33. }
    34. }
    35. return a.exec();
    36. }

    4.图像处理

    1> 灰度处理
    1. void cvtColor( InputArray src, OutputArray dst, int code, int dstCn = 0 );
    2. 功能:转换图像色彩空间
    3. //参数1:要转换的图像
    4. //参数2:转变后图像容器
    5. //参数3:转换规则:BGR to gray
    6. 返回值:无
    2> 均衡化处理
    1. void equalizeHist( InputArray src, OutputArray dst );
    2. 参数1:输入的灰度图像,必须是8-bit的单通道图像
    3. 参数2:输出的图像
    4. 图像直方图:对整个图像在灰度范围内的像素值(0-255)统计出现的频率,据此生成直方图,直 方图反应了图像的灰度分布情况。
    1. #include "widget.h"
    2. #include
    3. int main(int argc, char *argv[])
    4. {
    5. QApplication a(argc, argv);
    6. Widget w;
    7. w.show();
    8. //1、定义视频流对象
    9. VideoCapture v(0); //表明使用摄像头构造一个视频流对象
    10. //2、读取摄像头中的图像
    11. Mat src; //用于存放读取出来的图像
    12. Mat gray; //用于存储灰度图的图像容器
    13. Mat dst; //用于存储均衡化处理后的图像容器
    14. //函数原型:virtual bool read(OutputArray image);
    15. //功能:从视频流中读取一张图像放入参数中
    16. //参数:图像容器
    17. //返回值:成功返回真,失败或者读取视频结束返回假
    18. while(v.read(src))
    19. {
    20. //将图像进行翻转
    21. //函数原型:void flip(InputArray src, OutputArray dst, int flipCode);
    22. //参数1:要翻转的图像
    23. //参数2:翻转后的图像容器
    24. //参数3:翻转规则:正数表示按y轴翻转,0表示按x轴翻转,负数表示按xy轴翻转
    25. flip(src, src, 1);
    26. //3、将图像灰度处理
    27. //函数原型:void cvtColor( InputArray src, OutputArray dst, int code, int dstCn = 0 );
    28. //参数1:要转换的图像
    29. //参数2:转换后的图像容器
    30. //参数3:转换规则 CV_BGR2GRAY表示将bgr彩色图转换为gray灰度图
    31. //返回值:无
    32. cvtColor(src, gray, CV_BGR2GRAY);
    33. //4、对图像进行均衡化处理
    34. //函数原型:void equalizeHist( InputArray src, OutputArray dst );
    35. //参数1:要进行均衡化处理的图像,必须是单通道灰度图
    36. //参数2:均衡化处理后的图像容器
    37. //返回值:无
    38. equalizeHist(gray, dst);
    39. //展示彩色图像
    40. imshow("Test1", src);
    41. //展示灰度图像
    42. imshow("Test2", gray);
    43. //展示均衡化处理后的图像
    44. imshow("Test3", dst);
    45. //加延时函数
    46. //函数原型:int waitKey(int delay = 0);
    47. //参数:等待时间
    48. //返回值:在等待期间用户按下的键盘的ascii值 ESC键对应的值为27
    49. if(waitKey(20)==27)
    50. {
    51. break;
    52. }
    53. }
    54. return a.exec();
    55. }

    5.级联分类器 

    1> opencv级联分类器工具类 : CascadeClassifier //struct Student
    2> 加载级联分类器配置文件 : bool load( const String& filename )
    参数1:分类器数据文件的名字
    返回值:成功true,失败false
    3> 找到人脸所在位置的矩形区域
    1. void detectMultiScale(
    2. const Mat& image,
    3. CV_OUT vector& objects, //int arr[4];
    4. double scaleFactor = 1.1,
    5. int minNeighbors = 3,
    6. int flags = 0,
    7. Size ize = Size(24,24))
    8. 参数1:待检测灰度图像(数据少处理起来简单)
    9. 参数2:被检测物体的矩形框向量( 人脸Rect矩形区域,其中objects.size()是人脸个数 )
    10. 参数3:前后两次相继的扫描中搜索窗口的比例系数,默认为1.1 即每次搜索窗口扩大10%
    11. 参数4:构成检测目标的相邻矩形的最小个数 如果组成检测目标的小矩形的个数和小于 minneighbors - 1 都会被除
    12. 参数5:若设置为CV_HAAR_DO_CANNY_PRUNING 函数将会使用Canny边缘检测来排除边缘过多 或过少的区域,,一般采用默认值0
    13. 参数6:用来限制得到的目标区域的范围,一般检测人脸使用Size(24, 24)
    4> 人脸部分的矩形区域显示出来
    1. void rectangle(CV_IN_OUT Mat& img, Rect rec,
    2. const Scalar& color, int thickness = 1,
    3. int lineType = LINE_8, int shift = 0);
    4. img:图像。
    5. rec:表征矩形的位置和长宽。
    6. color:线条颜色 (RGB) 。
    7. thickness:组成矩形的线条的粗细程度。
    8. line_type:线条的类型。
    9. shift:坐标点的小数点位数,0表示没有小数点。
    1. #include "widget.h"
    2. #include
    3. int main(int argc, char *argv[])
    4. {
    5. QApplication a(argc, argv);
    6. Widget w;
    7. w.show();
    8. //1、定义视频流对象
    9. VideoCapture v(0); //表明使用摄像头构造一个视频流对象
    10. //2、读取摄像头中的图像
    11. Mat src; //用于存放读取出来的图像
    12. Mat gray; //用于存储灰度图的图像容器
    13. Mat dst; //用于存储均衡化处理后的图像容器
    14. //5、实例化一个级联分类器的对象,用于找到图像中的人脸矩形区域
    15. CascadeClassifier c;
    16. //给类对象装载人脸识别模型
    17. //函数原型:bool load( const String& filename );
    18. //功能:给级联分类器对象,下载一个识别模型
    19. //参数:人脸识别模型的文件路径
    20. //返回值:成功下载返回真,失败返回假
    21. if(!c.load("D:/opencv/resource/haarcascade_frontalface_alt2.xml"))
    22. {
    23. QMessageBox::information(NULL,"失败", "人脸识别模型装载失败");
    24. return -1;
    25. }
    26. //定义容器存放人脸分类后的矩形框
    27. vector faces;
    28. //函数原型:virtual bool read(OutputArray image);
    29. //功能:从视频流中读取一张图像放入参数中
    30. //参数:图像容器
    31. //返回值:成功返回真,失败或者读取视频结束返回假
    32. while(v.read(src))
    33. {
    34. //将图像进行翻转
    35. //函数原型:void flip(InputArray src, OutputArray dst, int flipCode);
    36. //参数1:要翻转的图像
    37. //参数2:翻转后的图像容器
    38. //参数3:翻转规则:正数表示按y轴翻转,0表示按x轴翻转,负数表示按xy轴翻转
    39. flip(src, src, 1);
    40. //3、将图像灰度处理
    41. //函数原型:void cvtColor( InputArray src, OutputArray dst, int code, int dstCn = 0 );
    42. //参数1:要转换的图像
    43. //参数2:转换后的图像容器
    44. //参数3:转换规则 CV_BGR2GRAY表示将bgr彩色图转换为gray灰度图
    45. //返回值:无
    46. cvtColor(src, gray, CV_BGR2GRAY);
    47. //4、对图像进行均衡化处理
    48. //函数原型:void equalizeHist( InputArray src, OutputArray dst );
    49. //参数1:要进行均衡化处理的图像,必须是单通道灰度图
    50. //参数2:均衡化处理后的图像容器
    51. //返回值:无
    52. equalizeHist(gray, dst);
    53. //6、使用级联分类器对象,获取人脸矩形区域
    54. //函数原型:void detectMultiScale( InputArray image,CV_OUT std::vector& objects)
    55. //参数1:要进行识别的图像
    56. //参数2:对该图像识别后,的矩形框存放的数组容器
    57. c.detectMultiScale(dst, faces);
    58. //7、将上述得到的矩形框,全部都绘制到图像上
    59. for(int i=0; isize(); i++)
    60. {
    61. //将任意一个矩形框,全部都绘制到图像上
    62. //函数原型:void rectangle(CV_IN_OUT Mat& img, Rect rec,const Scalar& color, int thickness = 1)
    63. //参数1:要被绘制的图像
    64. //参数2:要绘制的矩形框
    65. //参数3:矩形框的颜色
    66. //参数4:矩形框的粗细
    67. //返回值:无
    68. rectangle(src, faces[i], Scalar(0,0,255), 2);
    69. }
    70. //8、像素反差
    71. for(int i=0; i//外层循环控制行数
    72. {
    73. for(int j=0; j//内层循环控制列数
    74. {
    75. //找到任意一个像素:src.at(i,j)
    76. //找到任意一个像素中的通道中的值src.at(i,j)[k]
    77. for(int k=0; k<3; k++)
    78. {
    79. src.at(i,j)[k] = 255 - src.at(i,j)[k]; //对像素进行反差
    80. }
    81. }
    82. }
    83. //展示彩色图像
    84. imshow("Test1", src);
    85. //展示灰度图像
    86. imshow("Test2", gray);
    87. //展示均衡化处理后的图像
    88. imshow("Test3", dst);
    89. //加延时函数
    90. //函数原型:int waitKey(int delay = 0);
    91. //参数:等待时间
    92. //返回值:在等待期间用户按下的键盘的ascii值 ESC键对应的值为27
    93. if(waitKey(20)==27)
    94. {
    95. break;
    96. }
    97. }
    98. return a.exec();
    99. }

    6. 介绍 

    机器学习的作用:根据提供的图片模型通过算法生成数据模型,从而在其它图片中查找相关的目 标。

    级联分类器:是用来人脸识别。 在判断之前,我们要先进行学习,生成人脸的模型以便后续识别使用。

    人脸识别器:判断是谁的面部。 FaceRecognizer类是opencv提供的人脸识别器基类,LBPHFaceRecognizer是根据LBPH算法实 现的识别器类,其中LBPHFaceRecognizer识别器支持在原有模型基础上继续学习(模型数据可以累 计)。

    7.创建LBPHFaceRecognizer识别器对象

    1. 所需的头文件:#include 、using namespace cv::face;
    2. 创建空的人脸识别器对象:Ptr recognizer =
    3. LBPHFaceRecognizer::create();
    4. 根据已有的模型创建人脸识别器对象,在创建人脸识别器的时候,需要一个已经学习好的模型文件:
    5. Ptr recognizer = FaceRecognizer::load("模型文
    6. 件.xml");

    8.机器学习并更新模型

    1. 容器:容器中装了n张人脸Mat对象,先采集脸,装到容器中,存储标签,人的身份证,每一张脸
    2. 给一个编号:1 张三脸 2 李四脸 3 王五脸。
    3. 功能函数1void update(InputArrayOfArray src,InputArray labels)//机器学习并更新模型
    4. 功能函数2:void train(InputArrayOfArrays src,InputArray labels);//只是学习,不更新
    5. //参数1src:图片模型数组 vector
    6. //参数2labels:标签数组,每个模型识别后的标签vector

    9.保存模型

    1. 功能函数:void save(const String& filename);//参数1:模型文件的名字
    2. 例如:
    3. recognizer->update(study_faces,study_label);//学习
    4. recognizer->save("face.xml");//将学习的成果,保存到face.xml模型文件中,生成模型:
    5. study_faces.clear();、study_labels.clear();

    10.预测目标

    1. 判断这个人脸到底是谁。
    2. 功能函数:
    3. void predict(InputArray src, int &label, double &confidence)
    4. //参数1:预测图形 Mat src
    5. //参数2::预测后的标签,学习时对应的标签
    6. //参数3:预测出结果的可信度,数值越小可信度越高
    7. 例如:
    8. int label = -1;//预测后的标签,学习时对应的标签
    9. double confidence = 0;//可信度
    10. Mat face = frame(faces[0]);//人脸区域
    11. cvtColor(face,face,CV_BGR2GRAY);//更改色彩空间
    12. cv::resize(face,face,Size(90,90));//设置人脸的大小
    13. recognizer->predict(face,label,confidence); //预测,相当于识别人脸,预测出人脸是谁的
    14. 面部,label的值就那张脸对应的标签,如果预测不到,label的值是-1

    11.设置可信度

    1. 功能函数:void setThreshold(double val);
    2. //参数1:预测可信度极值,预测可信度超出极值则预测失败。

    12.完整项目代码 

    .pro文件:
    1. #-------------------------------------------------
    2. #
    3. # Project created by QtCreator 2023-09-04T19:10:16
    4. #
    5. #-------------------------------------------------
    6. QT += core gui
    7. greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    8. TARGET = 01_demo
    9. TEMPLATE = app
    10. SOURCES += main.cpp\
    11. widget.cpp
    12. HEADERS += widget.h
    13. FORMS += widget.ui
    14. INCLUDEPATH += C:/opencv/opencv3.4-qt-install/install/include
    15. INCLUDEPATH += C:/opencv/opencv3.4-qt-install/install/include/opencv
    16. INCLUDEPATH += C:/opencv/opencv3.4-qt-install/install/include/opencv2
    17. LIBS += C:/opencv/opencv3.4-qt-install/install/x86/mingw/lib/libopencv_*.a

    头文件:
    1. #ifndef WIDGET_H
    2. #define WIDGET_H
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include
    9. #include
    10. #include
    11. #include
    12. #include
    13. #include
    14. #include
    15. #include
    16. #include
    17. #include
    18. #include
    19. using namespace cv;
    20. using namespace cv::face;
    21. using namespace std;
    22. namespace Ui {
    23. class Widget;
    24. }
    25. class Widget : public QWidget
    26. {
    27. Q_OBJECT
    28. public:
    29. explicit Widget(QWidget *parent = 0);
    30. ~Widget();
    31. private slots:
    32. void on_openCameraBtn_clicked();
    33. void on_closeCameraBtn_clicked();
    34. void on_inputFaceBtn_clicked();
    35. private:
    36. Ui::Widget *ui;
    37. /***************************第一模块:关于摄像头的相关组件*****************************/
    38. VideoCapture v; //视频流对象
    39. Mat src; //原图像
    40. Mat rgb; //存放rgb图像,因为qt能识别的图像色彩空间为rgb
    41. Mat gray; //灰度图
    42. Mat dst; //均衡化图像
    43. CascadeClassifier c; //级联分类器
    44. vector faces; //存储人脸举行的容器
    45. int cameraId; //摄像头的定时器
    46. void timerEvent(QTimerEvent *event); //定时器事件处理函数
    47. /***************************第二模块:录入人脸的相关组件*****************************/
    48. Ptr recognizer; //人脸识别器
    49. vector study_face; //要录入的人脸容器
    50. vector<int> study_lab; //要录入的人脸的标签
    51. int studyId; //人脸录入的定时器
    52. int flag; //表示是否正在录入人脸
    53. int count; //记录学习的次数
    54. /***************************第三模块:人脸检测的相关组件*****************************/
    55. int checkId; //人脸检测的定时器
    56. };
    57. #endif // WIDGET_H
    源文件: 
    1. #include "widget.h"
    2. #include "ui_widget.h"
    3. Widget::Widget(QWidget *parent) :
    4. QWidget(parent),
    5. ui(new Ui::Widget)
    6. {
    7. ui->setupUi(this);
    8. //将登录按钮设置成不可用
    9. ui->loginBtn->setEnabled(false);
    10. //启动摄像头
    11. if(!v.open(0))
    12. {
    13. QMessageBox::information(this,"错误","打开摄像头失败");
    14. return;
    15. }
    16. //将级联分类器加载进来
    17. if(!c.load("C:/opencv/resource/haarcascade_frontalface_alt.xml"))
    18. {
    19. QMessageBox::information(this,"失败","人脸识别模型装载失败");
    20. return;
    21. }
    22. //配置人脸识别器
    23. QFile file("C:/opencv/resource/myFace.xml");
    24. //判断文件是否存在,如果存在,则直接下载,如果不存在,则创建一个人脸识别器
    25. if(file.exists())
    26. {
    27. //人脸模型存在,直接下载即可
    28. recognizer = FaceRecognizer::load("C:/opencv/resource/myFace.xml");
    29. }
    30. else
    31. {
    32. //人脸模型不存在,则需要创建
    33. recognizer = LBPHFaceRecognizer::create();
    34. }
    35. //启动人脸检测到的定时器
    36. checkId = this->startTimer(3000);
    37. //设置人脸识别的可信度
    38. recognizer->setThreshold(100);
    39. flag = 0; //表明开始时就处于检测
    40. }
    41. Widget::~Widget()
    42. {
    43. delete ui;
    44. }
    45. //打开摄像头按钮对应的槽函数
    46. void Widget::on_openCameraBtn_clicked()
    47. {
    48. //启动定时器
    49. cameraId = this->startTimer(20);
    50. ui->cameraLab->show();
    51. }
    52. //关闭摄像头按钮对应的槽函数
    53. void Widget::on_closeCameraBtn_clicked()
    54. {
    55. //关闭定时器
    56. this->killTimer(cameraId);
    57. ui->cameraLab->hide();
    58. }
    59. //定时器事件处理函数
    60. void Widget::timerEvent(QTimerEvent *event)
    61. {
    62. //判断是哪个定时器到位
    63. if(event->timerId() == cameraId)
    64. {
    65. //1.从摄像头中读取一张图像
    66. v.read(src); //得到原图
    67. //2.将图像翻转
    68. flip(src,src,1);
    69. //3.将src的bgr图像转换为rgb图像
    70. cvtColor(src,rgb,CV_BGR2RGB);
    71. //4.重新设置大小
    72. cv::resize(rgb,rgb,Size(300,300));
    73. //5.灰度处理
    74. cvtColor(rgb,gray,CV_RGB2GRAY);
    75. //6.均衡化处理
    76. equalizeHist(gray,dst);
    77. //7.使用级联分类器获取人脸矩形区域
    78. c.detectMultiScale(dst,faces);
    79. //8.将矩形框绘制到rgb图像上
    80. for(int i=0; isize(); i++)
    81. {
    82. rectangle(rgb,faces[i],Scalar(255,0,0),2);
    83. }
    84. //9.使用rgb图像,将Mat图,构造出一个qt能识别的图像
    85. QImage img(rgb.data,rgb.cols,rgb.rows,rgb.cols*rgb.channels(),QImage::Format_RGB888);
    86. //功能:通过其他图像构造出一个QImage图像
    87. //参数1:其他图像的数据
    88. //参数2:图像的宽度
    89. //参数3:图像的高度
    90. //参数4:每一行的字节数
    91. //参数5:图像格式,24位图,每一种颜色使用8位表示
    92. //10.将图像展示到lab中
    93. ui->cameraLab->setPixmap(QPixmap::fromImage(img));
    94. }
    95. //判断是否是人脸录入定时器到位
    96. if(event->timerId() == studyId)
    97. {
    98. //判断ui界面是否有矩形框
    99. if(faces.empty())return;
    100. //判断人脸识别器是否存在
    101. if(recognizer.empty())return;
    102. //提示正在录入人脸
    103. qDebug() << "正在录入人脸...";
    104. //获取ui界面中矩形框框起来的人脸区域
    105. Mat face = src(faces[0]);
    106. //将该图像进行重新设置大小
    107. cv::resize(face,face,Size(100,100));
    108. //灰度处理
    109. cvtColor(face,face,CV_BGR2GRAY);
    110. //均衡化处理
    111. equalizeHist(face,face);
    112. //将人脸放入学习容器中
    113. study_face.push_back(face);
    114. study_lab.push_back(1);
    115. count++; //表明完成一次人脸的存放
    116. if(count == 50) //已经收集50张人脸进行学习
    117. {
    118. count = 0; //以便于下一次录入
    119. //更新人脸模型
    120. //函数原型:CV_WRAP virtual void update(InputArrayOfArrays src, InputArray labels);
    121. //参数1:要进行更新的人脸数组
    122. //参数2:要更新的人脸标签数组
    123. //返回值:无
    124. recognizer->update(study_face,study_lab);
    125. //将数据模型保存到本地磁盘中
    126. recognizer->save("C:/opencv/resource/myFace.xml");
    127. //殿后工作
    128. study_face.clear(); //清空人脸数组
    129. study_lab.clear(); //清空标签数组
    130. flag = 0; //表明录入已经结束,可以进行人脸检测了
    131. ui->inputFaceBtn->setEnabled(true); //按钮设置成可用状态
    132. this->killTimer(studyId); //关闭人脸录入的定时器
    133. QMessageBox::information(this,"成功","人脸录入成功");
    134. }
    135. }
    136. //判断是否是人脸检测的定时器到位
    137. if(event->timerId() == checkId)
    138. {
    139. qDebug() << "正在检测...";
    140. //判断是否处于检测
    141. if(flag == 0)
    142. {
    143. QFile file("C:/opencv/resource/myFace.xml");
    144. if(file.exists()) //表明人脸模型存在的基础上进行识别
    145. {
    146. if(faces.empty() || recognizer.empty()) return; //ui界面无矩形框或者没有人脸识别器
    147. //到此表明可以进行检测
    148. Mat face = src(faces[0]);
    149. //重新设置大小,保持跟保存人脸时一致
    150. cv::resize(face,face,Size(100,100));
    151. //灰度处理
    152. cvtColor(face,face,CV_BGR2GRAY);
    153. //均衡化处理
    154. equalizeHist(face,face);
    155. //定义记录检测后返回的结果的变量
    156. int lab = -1; //返回的图像的标签
    157. double conf = 0.0; //返回图像的可信度
    158. //将该人脸进行预测
    159. recognizer->predict(face,lab,conf);
    160. qDebug() << "lab = " << lab << " conf = " << conf;
    161. //对人脸识别后的结果进行判断
    162. if(lab != -1)
    163. {
    164. ui->loginBtn->setEnabled(true);
    165. }
    166. }
    167. }
    168. }
    169. }
    170. //录入人脸按钮对应的槽函数
    171. void Widget::on_inputFaceBtn_clicked()
    172. {
    173. //启动人脸录入的定时器
    174. qDebug() << "开始进行人脸录入...";
    175. studyId = this->startTimer(60);
    176. //将按钮设置成不可用状态
    177. ui->inputFaceBtn->setEnabled(false);
    178. //将flag设置成1,表示正在录入人脸,不要进行人脸检测了
    179. flag = 1;
    180. count = 0; //清空计数器
    181. }
  • 相关阅读:
    力扣刷题-数组-螺旋矩阵
    如何保证用户重试操作的幂等性
    C语言--判断年月日是否合理
    钉钉老单据改造-前端操作手册(以保证金登记为例)
    Django 中admin页面的css样式无法加载的终极解决方案
    verdi显示OVM/UVM Hierarchy View
    ​P1190 [NOIP2010 普及组] 接水问题 【贪心】​
    园子周边第3季-博客园T恤:设计初稿第3版预览(补充2款)
    Redis篇---第九篇
    Health Kit申请验证有问题?解决方案全解析
  • 原文地址:https://blog.csdn.net/m0_68542867/article/details/132700043