人脸识别模型训练
简单了解LBPH算法
(在OpenCV使用的三种识别算法中是精度比较高的)
cv2.face.LBPHFaceRecognizer_create()#使用LBPH算法训练模型(注意OpenCV3中是createLBPHFaceRecognizer,这里因为树莓派和Window使用的版本不一样,所以到树莓派上还会改代码)
开始训练模型
这里还是先训练,毕竟真正的人脸识别开锁,人脸的录入并不是在要开锁的时候当场录入的,所以没必要在开锁的时候训练模型,提前用单独的代码将模型训练好,训练好的数据存储到trained`数据集中
检测时直接读取此文件夹中的数据
import numpy as np
from PIL import Image
import os
import cv2
def recon():
path = 'dataset'
recognizer = cv2.face.LBPHFaceRecognizer_create()
detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml");
def getImagesAndLabels(path):
imagePaths = [os.path.join(path, f) for f in os.listdir(path)]
faceSamples = []
ids = []
for imagePath in imagePaths:
PIL_img = Image.open(imagePath).convert('L')
img_numpy = np.array(PIL_img, 'uint8')
id = int(os.path.split(imagePath)[-1].split("_")[1])
faces = detector.detectMultiScale(img_numpy)
for (x, y, w, h) in faces:
faceSamples.append(img_numpy[y:y + h, x:x + w])
ids.append(id)
return faceSamples, ids
print("\n [INFO] Training faces. It will take a few seconds. Wait ...")
faces, ids = getImagesAndLabels(path)
recognizer.train(faces, np.array(ids))
recognizer.write('trained/trainer.yml')
print("\n [INFO] {0} faces trained. Exiting Program".format(len(np.unique(ids))))
人脸识别
import cv2
import numpy as np
import os
def recon_faces():
recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.read('trained/trainer.yml')
cascadePath = "haarcascade_frontalface_default.xml"
faceCascade = cv2.CascadeClassifier(cascadePath);
font = cv2.FONT_HERSHEY_SIMPLEX
id = 0
t = 0
fp2 = open('names.txt','r+')
str2 = fp2.read()
names = str2.split(',')
print(names)
cam = cv2.VideoCapture(0)
minW = 0.1 * cam.get(3)
minH = 0.1 * cam.get(4)
while True:
t+=1
ret, img = cam.read()
img = cv2.flip(img, 1)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = faceCascade.detectMultiScale(
gray,
scaleFactor=1.2,
minNeighbors=5,
minSize=(int(minW), int(minH)),
)
for (x, y, w, h) in faces:
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
id, confidence = recognizer.predict(gray[y:y + h, x:x + w])
if (confidence <45):
id = names[id]
confidence = " {0}%".format(round(100 - confidence))
else:
id = "unknown"
confidence = " {0}%".format(round(100 - confidence))
cv2.putText(img, str(id), (x + 5, y - 5), font, 1, (255, 255, 255), 2)
cv2.putText(img, str(confidence), (x + 5, y + h - 5), font, 1, (255, 255, 0), 1)
cv2.imshow('camera', img)
k = cv2.waitKey(10) & 0xff
if k == 27:
break
elif t>200:
break
cam.release()
cv2.destroyAllWindows()
return id
#id = recon_faces()
#print(id)
置信度评分用来 衡量所识别人脸与原模型的差距,0 表示完全匹配。
整合进界面
使用Qt designer设计界面
拖控件,针对每个控件(比如Button)
写信号槽函数(对应的响应事件)
界面布局
(1)使用容器container布局
使用verticallayout
进行竖式按键布局
(2)使用堆叠布局来实现不同界面的切换
QStackedWidget
使用QtDesigner进行界面的创建和布局
界面功能
(1)人脸录入()
这里就只设置一个管理员(比如某个宿舍的舍管)
所以只需要一对账号密码(admin,fjnupass)
输入学号,开始录入
将学号存储在文件中,用于人脸识别时的id和人脸匹配
录入结束会弹出对话框,点击OK,继续进行模型的训练,模型训练结束弹出训练结束对话框
(2)人脸识别开锁
点击按钮,调用摄像头运行识别代码
识别成功,跳出成功和欢迎某某学号的对话框
设置一个超时时间(10s左右),超过就跳出是被失败的对话框,
识别成功:弹出对话框显示欢迎某某学号学生
(3)密码锁
输入密码开锁(考虑人脸识别的精度问题)
直接使用一个LineEdit控件
取得输入内容后和已存在密码做一个对比(密码预设为12345678)
![image-20211213200205680](image-
.png)
(4)退出系统
self.exit.clicked.connect(self.click_exit)
def click_exit(self):
sys.exit(app.exec_())
界面代码:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'face.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
import sqlite3
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QMessageBox,QWidget
from input_face_data import *
from train import *
from test import *
class Ui_MainWindow(QWidget):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(913, 684)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.frameheader = QtWidgets.QFrame(self.centralwidget)
self.frameheader.setGeometry(QtCore.QRect(120, 0, 521, 61))
self.frameheader.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frameheader.setFrameShadow(QtWidgets.QFrame.Raised)
self.frameheader.setObjectName("frameheader")
self.stackedWidget = QtWidgets.QStackedWidget(self.centralwidget)
self.stackedWidget.setGeometry(QtCore.QRect(230, 70, 641, 541))
self.stackedWidget.setObjectName("stackedWidget")
self.page_4 = QtWidgets.QWidget()
self.page_4.setObjectName("page_4")
self.id = QtWidgets.QLineEdit(self.page_4)
self.id.setGeometry(QtCore.QRect(202, 200, 231, 31))
self.id.setObjectName("id")
self.pushButton = QtWidgets.QPushButton(self.page_4)
self.pushButton.setGeometry(QtCore.QRect(260, 270, 111, 41))
self.pushButton.setObjectName("pushButton")
self.label_4 = QtWidgets.QLabel(self.page_4)
self.label_4.setGeometry(QtCore.QRect(200, 160, 111, 21))
self.label_4.setObjectName("label_4")
self.stackedWidget.addWidget(self.page_4)
self.page = QtWidgets.QWidget()
self.page.setObjectName("page")
self.verticalLayoutWidget = QtWidgets.QWidget(self.page)
self.verticalLayoutWidget.setGeometry(QtCore.QRect(20, 40, 118, 361))
self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget)
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.verticalLayout.setObjectName("verticalLayout")
self.admin = QtWidgets.QPushButton(self.verticalLayoutWidget)
self.admin.setObjectName("admin")
self.verticalLayout.addWidget(self.admin)
self.passwd = QtWidgets.QPushButton(self.verticalLayoutWidget)
self.passwd.setObjectName("passwd")
self.verticalLayout.addWidget(self.passwd)
self.face = QtWidgets.QPushButton(self.verticalLayoutWidget)
self.face.setObjectName("face")
self.verticalLayout.addWidget(self.face)
self.exit = QtWidgets.QPushButton(self.verticalLayoutWidget)
self.exit.setObjectName("exit")
self.verticalLayout.addWidget(self.exit)
self.admin_pass = QtWidgets.QLabel(self.page)
self.admin_pass.setGeometry(QtCore.QRect(270, 210, 161, 21))
font = QtGui.QFont()
font.setPointSize(15)
self.admin_pass.setFont(font)
self.admin_pass.setObjectName("admin_pass")
self.admin_line_pass = QtWidgets.QLineEdit(self.page)
self.admin_line_pass.setGeometry(QtCore.QRect(270, 250, 351, 31))
self.admin_line_pass.setObjectName("admin_line_pass")
self.admin_name = QtWidgets.QLabel(self.page)
self.admin_name.setGeometry(QtCore.QRect(270, 120, 161, 21))
font = QtGui.QFont()
font.setPointSize(15)
self.admin_name.setFont(font)
self.admin_name.setObjectName("admin_name")
self.admin_line_name = QtWidgets.QLineEdit(self.page)
self.admin_line_name.setGeometry(QtCore.QRect(270, 160, 351, 31))
self.admin_line_name.setObjectName("admin_line_name")
self.login = QtWidgets.QPushButton(self.page)
self.login.setGeometry(QtCore.QRect(380, 320, 101, 41))
self.login.setObjectName("login")
self.stackedWidget.addWidget(self.page)
self.page_2 = QtWidgets.QWidget()
self.page_2.setObjectName("page_2")
self.open = QtWidgets.QPushButton(self.page_2)
self.open.setGeometry(QtCore.QRect(230, 300, 291, 41))
self.open.setObjectName("open")
self.lineEdit = QtWidgets.QLineEdit(self.page_2)
self.lineEdit.setGeometry(QtCore.QRect(230, 220, 291, 31))
self.lineEdit.setObjectName("lin eEdit")
self.label_2 = QtWidgets.QLabel(self.page_2)
self.label_2.setGeometry(QtCore.QRect(230, 180, 131, 21))
self.label_2.setObjectName("label_2")
self.stackedWidget.addWidget(self.page_2)
self.page_3 = QtWidgets.QWidget()
self.page_3.setObjectName("page_3")
self.label_3 = QtWidgets.QLabel(self.page_3)
self.label_3.setGeometry(QtCore.QRect(60, 120, 541, 271))
font = QtGui.QFont()
font.setPointSize(25)
self.label_3.setFont(font)
self.label_3.setObjectName("label_3")
self.stackedWidget.addWidget(self.page_3)
self.return_2 = QtWidgets.QPushButton(self.centralwidget)
self.return_2.setGeometry(QtCore.QRect(90, 230, 75, 23))
self.return_2.setObjectName("return_2")
self.exit2 = QtWidgets.QPushButton(self.centralwidget)
self.exit2.setGeometry(QtCore.QRect(90, 320, 75, 23))
self.exit2.setObjectName("exit2")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(330, 10, 411, 41))
font = QtGui.QFont()
font.setPointSize(23)
font.setBold(True)
font.setItalic(False)
font.setWeight(75)
self.label.setFont(font)
self.label.setObjectName("label")
self.door = QtWidgets.QPushButton(self.centralwidget)
self.door.setGeometry(QtCore.QRect(90, 170, 75, 23))
self.door.setObjectName("door")
self.exit.clicked.connect(self.click_exit)
self.exit2.clicked.connect(self.click_exit)
self.door.clicked.connect(self.click_door)
self.return_2.clicked.connect(self.click_return_2)
self.passwd.clicked.connect(self.click_passwd)
self.pushButton.clicked.connect(self.click_pass)
self.admin.clicked.connect(self.click_admin)
self.login.clicked.connect(self.click_login)
self.open.clicked.connect(self.click_open)
self.face.clicked.connect(self.click_face)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 913, 23))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
self.stackedWidget.setCurrentIndex(3)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton.setText(_translate("MainWindow", "开锁"))
self.label_4.setText(_translate("MainWindow", "请输入密码"))
self.admin.setText(_translate("MainWindow", "管理员(人脸录入)"))
self.passwd.setText(_translate("MainWindow", "密码开锁"))
self.face.setText(_translate("MainWindow", "人脸识别开锁"))
self.exit.setText(_translate("MainWindow", "退出系统"))
self.admin_pass.setText(_translate("MainWindow", "管理员密码"))
self.admin_name.setText(_translate("MainWindow", "管理员名"))
self.login.setText(_translate("MainWindow", "登录"))
self.open.setText(_translate("MainWindow", "录入"))
self.label_2.setText(_translate("MainWindow", "请输入要录入的学号"))
self.label_3.setText(_translate("MainWindow", "欢迎,请点击左侧按钮进入菜单页面"))
self.return_2.setText(_translate("MainWindow", "返回首页"))
self.exit2.setText(_translate("MainWindow", "退出"))
self.label.setText(_translate("MainWindow", "智能门禁人脸识别系统"))
self.door.setText(_translate("MainWindow", "进入菜单"))
def click_admin(self):
self.stackedWidget.setCurrentIndex(4)
def click_login(self):
if self.admin_line_name.text()=='admin' or self.admin_line_pass.text()=='fjnupass':
self.stackedWidget.setCurrentIndex(2)
r = QMessageBox.information(self, 'welcome', '请输入学号,录入对应人脸', QMessageBox.Ok)
else:
r = QMessageBox.information(self, 'warning', '用户名或密码错误', QMessageBox.Ok)
def click_door(self):
self.stackedWidget.setCurrentIndex(1)
def click_return_2(self):
self.stackedWidget.setCurrentIndex(3)
def click_exit(self):
sys.exit(app.exec_())
def click_passwd(self):
self.stackedWidget.setCurrentIndex(0)
def click_face(self):
s = recon_faces()
if(s!='unknown'):
QMessageBox.information(self,"Welcome","已经开门",QMessageBox.Ok)
else:
QMessageBox.information(self, "Warning", "未识别出", QMessageBox.Ok)
def click_open(self):
name = self.lineEdit.text()
fp = open('names.txt','a+')
# 将学号存储到文件中
fp.write(name+',')
fp.close()
fp2 = open('names.txt','r+')
str = fp2.read()
names = str.split(',')
id = len(names)-2
QMessageBox.information(self, "!!", '开始录入,请正式摄像头,摘下眼睛', QMessageBox.Ok)
input_face_data(id)
QMessageBox.information(self,"!!",'人脸录入结束,开始训练',QMessageBox.Ok)
recon()
QMessageBox.information(self, "!!", '人脸识别模型训练结束', QMessageBox.Ok)
# video_detc()
# def click_enterButton(self):
# pswd = "12345678"
# if self.admin_passwd.text()==pswd:
def click_pass(self):
if self.id.text()=='12345678':
r = QMessageBox.information(self, 'welcome', '欢迎回宿舍',QMessageBox.Ok)
self.stackedWidget.setCurrentIndex(3)
else:
r = QMessageBox.information(self, 'warning', '宿舍密码错误', QMessageBox.Ok)
if __name__ == '__main__':
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBox
# import pics_ui_rc # 导入添加的资源(根据实际情况填写文件名)
app = QApplication(sys.argv)
MainWindow = QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())