打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
python+opencv+dlib+pyqt5人脸识别实践

版权声明:本文为博主原创文章。 https://blog.csdn.net/esting_tang/article/details/81134268

关于

本项目基于python,用到了opencv、dlib等开发包,实现了单张训练样本的人脸识别,有较为友好的UI界面,识别速度经优化后尚可。

实现上思路与这篇博客一致,解决了这篇博客中存在的几个问题:

  • 每次识别都需要把每个人的人脸样本的特征向量计算一遍,人脸库小的时候看不出差距,但人脸库很大时就显得非常不方便(实测的时候用的400人的人脸库,提取特征就要耗费1分多钟)。
  • 用dlib中的方法进行人脸检测的时候速度很慢。
  • 没有友好的UI界面。

基于以上问题,采取的解决方案如下:

  • 把人脸识别过程分为两阶段:1、提取人脸特征 2、人脸检测+计算欧氏距离;两个阶段分别单独执行,即可加快人脸识别时候的速度。
  • 换人脸检测的方法,用opencv中自带的人脸检测器进行人脸检测。
  • 用pyqt5绘制界面。

准备工作

  • python 3.6.5
  • opencv 3.3.1
  • numpy 1.14.3
  • dlib 19.7.0 (配置方法可见这篇文章
  • pycharm+pyqt5 (配置方法可见这篇文章

工程目录结构

  • E:\ 
    • candidate_face 
      • liuyifei.jpg
      • tangyan.jpg
      • yangmi.jpg
      • yangzi.jpg
      • zhoudongyu.jpg
    • pyproject 
      • shape_predictor_68_face_landmarks.dat
      • dlib_face_recognition_resnet_model_v1.dat
      • lbpcascade_frontalface_improved.xml(用于人脸检测,在opencv目录opencv-3.3.1-py36h20b85fd_1\Library\etc\lbpcascades下)
      • FaceRecognition.py
      • main.py
    • test.jpg

人脸识别过程

首先运行FaceRecognition.py,会经历:读取人脸集、人脸检测、提取人脸特征向量、存储人脸特征向量、对单张测试人脸图进行识别、打印识别结果 的过程。 
然后运行main.py,会经历:初始化界面、加载各种参数模型、手动选择单张人脸测试图、基于opencv人脸检测器检测人脸、提取该人脸特征向量、计算欧氏距离、找出距离最小的人脸标签、输出人脸识别结果 这么几个过程。

识别结果

 

闲话

这个项目目前bug多多,准确率也还有很大提高空间,欢迎各位多多交流,这个项目的更多详情请见这里,如果对你也有所帮助,请轻轻点个star(别太重了,怕疼(⊙o⊙)…)。

源码怎会少

  • FaceRecognition.py
  1. import os,dlib,numpy,cv2
  2. predictor_path = 'shape_predictor_68_face_landmarks.dat'
  3. face_rc_model_path = 'dlib_face_recognition_resnet_model_v1.dat'
  4. face_folder_path = 'E:\candidate_face'
  5. test_img_path = 'E:\\test.jpg'
  6. # 读取人脸集、人脸标签
  7. def read_data(path):
  8. try:
  9. pic_name_list = os.listdir(path)
  10. pic_list = []
  11. for i in pic_name_list:
  12. whole_path = os.path.join(path, i)
  13. img = cv2.imread(whole_path)
  14. pic_list.append(img)
  15. except IOError:
  16. print('read error')
  17. return False
  18. else:
  19. print('read successfully')
  20. return pic_name_list, pic_list
  21. # 人脸检测器
  22. detector = dlib.get_frontal_face_detector()
  23. # 关键点检测器
  24. feature_point = dlib.shape_predictor(predictor_path)
  25. # 人脸参数模型
  26. feature_model = dlib.face_recognition_model_v1(face_rc_model_path)
  27. # 候选人特征向量列表
  28. descriptors = []
  29. if __name__ == '__main__':
  30. name_list, pic_list = read_data(face_folder_path)
  31. num = 1
  32. for i in pic_list:
  33. # 人脸检测
  34. dets = detector(i, 1)
  35. for k, d in enumerate(dets):
  36. # 关键点检测
  37. shape = feature_point(i, d)
  38. # 提取特征,128维
  39. face_feature = feature_model.compute_face_descriptor(i, shape)
  40. v = numpy.array(face_feature)
  41. descriptors.append(v)
  42. print('人脸特征提取,第 %d 个人' % num)
  43. num += 1
  44. # 特征向量列表存入文件
  45. numpy.save('vectors.npy', descriptors)
  46. '''
  47. 对单张人脸进行识别
  48. '''
  49. test_img = cv2.imread(test_img_path)
  50. dets = detector(test_img, 1)
  51. for k, d in enumerate(dets):
  52. shape = feature_point(test_img, d)
  53. test_feature = feature_model.compute_face_descriptor(test_img, shape)
  54. test_feature = numpy.array(test_feature)
  55. dist = []
  56. count = 0
  57. for i in descriptors:
  58. dist_ = numpy.linalg.norm(i-test_feature)
  59. print('%s : %f' % (name_list[count], dist_))
  60. dist.append(dist_)
  61. count += 1
  62. min_dist = numpy.argmin(dist)
  63. result = name_list[min_dist][:-4]
  64. print(result)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • main.py
  1. # -*- coding: utf-8 -*-
  2. import sys, os, numpy, cv2, dlib
  3. from PyQt5 import QtCore, QtGui, QtWidgets
  4. class Ui_Dialog(object):
  5. def setupUi(self, Dialog):
  6. Dialog.setObjectName("Dialog")
  7. Dialog.resize(699, 300)
  8. self.toolButton = QtWidgets.QToolButton(Dialog)
  9. self.toolButton.setGeometry(QtCore.QRect(390, 10, 31, 21))
  10. self.toolButton.setObjectName("toolButton")
  11. self.pushButton = QtWidgets.QPushButton(Dialog)
  12. self.pushButton.setGeometry(QtCore.QRect(460, 10, 75, 23))
  13. self.pushButton.setObjectName("pushButton")
  14. self.lineEdit = QtWidgets.QLineEdit(Dialog)
  15. self.lineEdit.setGeometry(QtCore.QRect(130, 10, 251, 20))
  16. self.lineEdit.setObjectName("lineEdit")
  17. self.graphicsView = QtWidgets.QGraphicsView(Dialog)
  18. self.graphicsView.setGeometry(QtCore.QRect(290, 41, 251, 241))
  19. self.graphicsView.setObjectName("graphicsView")
  20. self.label = QtWidgets.QLabel(Dialog)
  21. self.label.setGeometry(QtCore.QRect(290, 41, 251, 241))
  22. self.label.setObjectName("label")
  23. self.label.setScaledContents(True) #label自适应图片大小
  24. self.graphicsView_2 = QtWidgets.QGraphicsView(Dialog)
  25. self.graphicsView_2.setGeometry(QtCore.QRect(10, 40, 256, 241))
  26. self.graphicsView_2.setObjectName("graphicsView_2")
  27. self.label_2 = QtWidgets.QLabel(Dialog)
  28. self.label_2.setGeometry(QtCore.QRect(13, 41, 251, 241))
  29. self.label_2.setObjectName("label_2")
  30. self.label_2.setScaledContents(True) #label自适应图片大小
  31. self.label_3 = QtWidgets.QLabel(Dialog)
  32. self.label_3.setGeometry(QtCore.QRect(10, 10, 111, 21))
  33. font = QtGui.QFont()
  34. font.setFamily("Agency FB")
  35. font.setPointSize(11)
  36. self.label_3.setFont(font)
  37. self.label_3.setObjectName("label_3")
  38. self.label_4 = QtWidgets.QLabel(Dialog)
  39. self.label_4.setGeometry(QtCore.QRect(550, 210, 81, 21))
  40. font = QtGui.QFont()
  41. font.setFamily("Agency FB")
  42. font.setPointSize(11)
  43. self.label_4.setFont(font)
  44. self.label_4.setObjectName("label_4")
  45. self.lineEdit_2 = QtWidgets.QLineEdit(Dialog)
  46. self.lineEdit_2.setGeometry(QtCore.QRect(550, 240, 141, 20))
  47. font = QtGui.QFont()
  48. font.setFamily("Agency FB")
  49. font.setPointSize(11)
  50. self.lineEdit_2.setFont(font)
  51. self.lineEdit_2.setObjectName("lineEdit_2")
  52. self.retranslateUi(Dialog)
  53. QtCore.QMetaObject.connectSlotsByName(Dialog)
  54. def retranslateUi(self, Dialog):
  55. _translate = QtCore.QCoreApplication.translate
  56. Dialog.setWindowTitle(_translate("Dialog", "龟速人脸识别demo"))
  57. self.toolButton.setText(_translate("Dialog", "..."))
  58. self.pushButton.setText(_translate("Dialog", "开始识别"))
  59. self.lineEdit.setText(_translate("Dialog", "E:/"))
  60. self.label.setText(_translate("Dialog", "识别结果"))
  61. self.label_2.setText(_translate("Dialog", "待测人脸"))
  62. self.label_3.setText(_translate("Dialog", "待测人照片路径:"))
  63. self.label_4.setText(_translate("Dialog", "识别结果:"))
  64. class Myshow(QtWidgets.QWidget, Ui_Dialog):
  65. def __init__(self):
  66. super(Myshow, self).__init__()
  67. self.setupUi(self)
  68. self.pushButton.clicked.connect(self.Recognition)
  69. self.toolButton.clicked.connect(self.ChoosePath)
  70. self.predictor_path = 'shape_predictor_68_face_landmarks.dat'
  71. self.face_rc_model_path = 'dlib_face_recognition_resnet_model_v1.dat'
  72. self.face_folder_path = 'E:\candidate_face'
  73. self.name_list = os.listdir(self.face_folder_path)
  74. self.descriptors = numpy.load('vectors.npy')
  75. # dlib方法检测人脸
  76. # self.detector = dlib.get_frontal_face_detector()
  77. # opencv方法检测人脸
  78. self.face_cascade = cv2.CascadeClassifier('lbpcascade_frontalface_improved.xml')
  79. self.feature_point = dlib.shape_predictor(self.predictor_path)
  80. self.feature_model = dlib.face_recognition_model_v1(self.face_rc_model_path)
  81. self.test_path = 'E:/'
  82. def ChoosePath(self):
  83. file_name = QtWidgets.QFileDialog.getOpenFileName(self, "open file dialog", self.test_path, "图片(*.jpg)")
  84. print(file_name[0])
  85. self.test_path = file_name[0]
  86. self.lineEdit.setText(self.test_path)
  87. self.label_2.setPixmap(QtGui.QPixmap(self.test_path)) #显示待测人脸图
  88. # 清空不相关内容
  89. self.label.clear()
  90. self.lineEdit_2.clear()
  91. def Recognition(self):
  92. test_img = cv2.imread(self.test_path)
  93. # dlib方法检测人脸
  94. # dets = self.detector(test_img, 1)
  95. # for k, d in enumerate(dets):
  96. # shape = self.feature_point(test_img, d)
  97. # test_feature = self.feature_model.compute_face_descriptor(test_img, shape)
  98. # test_feature = numpy.array(test_feature)
  99. # opencv方法检测人脸
  100. gray = cv2.cvtColor(test_img, cv2.COLOR_BGR2GRAY)
  101. dets = self.face_cascade.detectMultiScale(gray, 1.1, 6)
  102. mark = 0
  103. for (x, y, w, h) in dets:
  104. mark = 1
  105. d = dlib.rectangle(numpy.long(x),numpy.long(y),numpy.long(x+w),numpy.long(y+h))
  106. shape = self.feature_point(test_img, d)
  107. test_feature = self.feature_model.compute_face_descriptor(test_img, shape)
  108. test_feature = numpy.array(test_feature)
  109. if mark == 1:
  110. dist = []
  111. count = 0
  112. for i in self.descriptors:
  113. dist_ = numpy.linalg.norm(i - test_feature)
  114. print('%s : %f' % (self.name_list[count], dist_))
  115. dist.append(dist_)
  116. count += 1
  117. min_dist = numpy.argmin(dist)
  118. print('%s' % self.name_list[min_dist][:-4])
  119. show_img_path = os.path.join(self.face_folder_path, self.name_list[min_dist])
  120. self.label.setPixmap(QtGui.QPixmap(show_img_path)) #显示人脸识别结果图
  121. self.lineEdit_2.setText(self.name_list[min_dist][:-4])
  122. else :
  123. self.lineEdit_2.setText('haven\'t find any people')
  124. if __name__ == '__main__':
  125. app = QtWidgets.QApplication(sys.argv)
  126. w = Myshow()
  127. w.show()
  128. sys.exit(app.exec_())
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
用Python实现一个简单的——人脸相似度对比
【CV实战】年轻人的第一个深度学习CV项目应该是什么样的?(支持13大深度学习开源框架)
50行代码实现人脸检测
今天程序员的每一行代码都是未来高达身上的一颗螺丝
开发一个完整的眼动追踪应用-Python版
干货 | 训练一个神经网络 让她能认得我
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服