• QT人脸识别知识


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

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

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

    创建LBPHFaceRecognizer识别器对象

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

    机器学习并更新模型

    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

    保存模型

    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();

    预测目标

    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

    设置可信度

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

    实例:

    头文件

    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. using namespace cv;
    19. using namespace cv::face;
    20. using namespace std;
    21. namespace Ui {
    22. class Widget;
    23. }
    24. class Widget : public QWidget
    25. {
    26. Q_OBJECT
    27. public:
    28. explicit Widget(QWidget *parent = 0);
    29. ~Widget();
    30. private slots:
    31. void on_openCameraBtn_clicked();
    32. void on_closeCameraBtn_clicked();
    33. void on_inputFaceBtn_clicked();
    34. private:
    35. Ui::Widget *ui;
    36. /***********************第一模块:关于摄像头的相关组件**********************/
    37. VideoCapture v; //视频流对象
    38. Mat src; //原图像
    39. Mat rgb; //存放rgb图像,因为qt能识别的图像色彩空间为rgb
    40. Mat gray; //灰度图
    41. Mat dst; //均衡化图像
    42. CascadeClassifier c; //级联分类器
    43. vector faces; //存储人脸矩形区域的容器
    44. int cameraId; //摄像头的定时器
    45. void timerEvent(QTimerEvent *event); //定时器事件处理函数
    46. /**********************第二模块:录入人脸的相关组件************************/
    47. Ptr recognizer; //人脸识别器
    48. vector study_face; //要录入的人脸容器
    49. vector<int> study_lab; //要录入的人脸的标签
    50. int studyId; //人脸录入的定时器
    51. int flag; //标识是否正在录入人脸
    52. int count; //记录学习的次数
    53. /**********************第三模块:人脸检测相关组件*************************/
    54. int checkId; //人脸检测的定时器
    55. };
    56. #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("D:/opencv/resource/haarcascade_frontalface_alt2.xml"))
    18. {
    19. QMessageBox::information(this,"失败", "人脸识别模型装载失败");
    20. return ;
    21. }
    22. //配置人脸识别器
    23. QFile file("D:/opencv/resource/myFace.xml");
    24. //判断文件是否存在,如果存在,则直接下载,如果不存在,则创建一个人脸识别器
    25. if(file.exists())
    26. {
    27. //人脸模型存在,直接下载即可
    28. recognizer = FaceRecognizer::load("D:/opencv/resource/myFace.xml");
    29. }else
    30. {
    31. //人脸模型不存在,需要进行创建
    32. recognizer = LBPHFaceRecognizer::create();
    33. }
    34. //启动人脸检测的定时器
    35. checkId = this->startTimer(3000);
    36. //设置人脸识别的可信度
    37. recognizer->setThreshold(100);
    38. flag = 0; //表明开始时就处于检测
    39. }
    40. Widget::~Widget()
    41. {
    42. delete ui;
    43. }
    44. //打开摄像头按钮对应的槽函数
    45. void Widget::on_openCameraBtn_clicked()
    46. {
    47. //启动定时器
    48. cameraId = this->startTimer(20);
    49. ui->cameraLab->show();
    50. }
    51. //关闭摄像头
    52. void Widget::on_closeCameraBtn_clicked()
    53. {
    54. //关闭定时器
    55. this->killTimer(cameraId);
    56. ui->cameraLab->hide();
    57. }
    58. //定时器事件处理函数
    59. void Widget::timerEvent(QTimerEvent *event)
    60. {
    61. //判断是哪个定时器到位
    62. if(event->timerId() == cameraId)
    63. {
    64. //1、从摄像头中读取一张图像
    65. v.read(src); //得到原图
    66. //2、将图像翻转
    67. flip(src, src, 1);
    68. //3、将src的bgr图像转换为rgb图像
    69. cvtColor(src, rgb, CV_BGR2RGB);
    70. //4、重新设置大小
    71. cv::resize(rgb, rgb, Size(300,300));
    72. //5、灰度处理
    73. cvtColor(rgb, gray, CV_RGB2GRAY);
    74. //6、均衡化处理
    75. equalizeHist(gray, dst);
    76. //7、使用级联分类器获取人脸矩形区域
    77. c.detectMultiScale(dst, faces);
    78. //8、将矩形框绘制到rgb图像上
    79. for(int i=0; isize(); i++)
    80. {
    81. rectangle(rgb, faces[i], Scalar(255,0,0), 2);
    82. }
    83. //9、使用rgb图像,将Mat图,构造出一个qt能识别的图像
    84. QImage img(rgb.data, rgb.cols, rgb.rows, rgb.cols*rgb.channels(), QImage::Format_RGB888);
    85. //功能:通过其他图像构造出一个QImage图像
    86. //参数1:其他图像的数据
    87. //参数2:图像的宽度
    88. //参数3:图像的高度
    89. //参数4:每一行的字节数
    90. //参数5:图像格式,24位图,每一种颜色使用8位表示
    91. //10、将图像展示到lab中
    92. ui->cameraLab->setPixmap(QPixmap::fromImage(img));
    93. }
    94. //判断是否是人脸录入定时器到位
    95. if(event->timerId() == studyId)
    96. {
    97. //判断ui界面是否有矩形框
    98. if(faces.empty())return;
    99. //判断人脸识别器是否存在
    100. if(recognizer.empty()) return;
    101. //提示正在录入人脸
    102. qDebug()<<"正在录入,请稍后...";
    103. //获取ui界面中矩形框框起来的人脸区域
    104. Mat face = src(faces[0]);
    105. //将该图像进行重新设置大小
    106. cv::resize(face,face,Size(100,100));
    107. //灰度处理
    108. cvtColor(face,face,CV_BGR2GRAY);
    109. //均衡化处理
    110. equalizeHist(face,face);
    111. //将人脸放入学习容器中
    112. study_face.push_back(face);
    113. study_lab.push_back(1);
    114. count++; //表明完成一次人脸的存放
    115. if(count == 50) //已经收集50张人脸进行学习
    116. {
    117. count = 0; //以便于下一次录入
    118. //更新人脸模型,将图像模型转换为数据模型
    119. //函数原型:void update(InputArrayOfArrays src, InputArray labels);
    120. //参数1:要进行更新的人脸数组
    121. //参数2:要跟新的人脸标签数组
    122. //返回值:无
    123. recognizer->update(study_face, study_lab);
    124. //将数据模型保存到本地磁盘中
    125. recognizer->save("D:/opencv/resource/myFace.xml");
    126. //殿后工作
    127. study_face.clear(); //清空人脸数组
    128. study_lab.clear(); //清空标签数组
    129. flag = 0; //表明录入已经结束,可以进行人脸检测了
    130. ui->inputFaceBtn->setEnabled(true); //按钮设置成可用状态
    131. this->killTimer(studyId); //关闭人脸录入的定时器
    132. QMessageBox::information(this,"成功","人脸录入成功");
    133. }
    134. }
    135. //判断是否是人脸检测的定时器到位
    136. if(event->timerId() == checkId)
    137. {
    138. qDebug()<<"正在检测...";
    139. //判断是否处于检测
    140. if(flag == 0)
    141. {
    142. QFile file("D:/opencv/resource/myFace.xml");
    143. if(file.exists()) //表明人脸模型存在的基础上进行识别
    144. {
    145. if(faces.empty() || recognizer->empty()) return; //ui界面无矩形框或者没有人脸识别器
    146. //到此表明可以进行检测
    147. Mat face = src(faces[0]);
    148. //重新设置大小,保持跟保存人脸时一致
    149. cv::resize(face,face,Size(100,100));
    150. //灰度处理
    151. cvtColor(face,face,CV_BGR2GRAY);
    152. //均衡化处理
    153. equalizeHist(face,face);
    154. //定义记录检测后返回的结果的变量
    155. int lab = -1; //返回的图像的标签
    156. double conf = 0.0; //返回图像的可信度
    157. //将该人脸进行预测
    158. recognizer->predict(face, lab, conf);
    159. qDebug()<<"lab = "<" conf = "<
    160. //对人脸识别后的结果进行判断
    161. if(lab != -1)
    162. {
    163. ui->loginBtn->setEnabled(true);
    164. }
    165. }
    166. }
    167. }
    168. }
    169. //录入人脸按钮对应的槽函数
    170. void Widget::on_inputFaceBtn_clicked()
    171. {
    172. //启动人脸录入的定时器
    173. qDebug()<<"开始进行人脸录入...";
    174. studyId = this->startTimer(60);
    175. //将按钮设置成不可用状态
    176. ui->inputFaceBtn->setEnabled(false);
    177. //将flag设置成1,表示正在录入人脸,不要进行人脸检测了
    178. flag = 1;
    179. count = 0; //清空计数器
    180. }

  • 相关阅读:
    图像检测:医疗影像分割
    【C++】C语言可变函数参数 | C++11可变参数模板
    开发QQ官方机器人
    用友BIP产品矩阵亮相首届中小企业数字化转型大会,数智创新驱动企业高效成长
    Linux 权限
    Django 路由配置(二)
    回到数字化之前、回到ERP之前
    关于组织开展2022年广东省技术先进型服务企业认定工作的通知
    Day130.MySQL高级:Liunx安装、三大范式、InnoDB、数据结构、B+树
    Android 读取联系人列表
  • 原文地址:https://blog.csdn.net/weixin_53478812/article/details/132702336