人脸识别|使用Opencv+树莓派实现人脸识别(二)人脸识别和PyQt界面整合

人脸识别模型训练 简单了解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, idsprint("\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)
人脸识别|使用Opencv+树莓派实现人脸识别(二)人脸识别和PyQt界面整合
文章图片

人脸识别|使用Opencv+树莓派实现人脸识别(二)人脸识别和PyQt界面整合
文章图片

输入学号,开始录入 将学号存储在文件中,用于人脸识别时的id和人脸匹配
人脸识别|使用Opencv+树莓派实现人脸识别(二)人脸识别和PyQt界面整合
文章图片
人脸识别|使用Opencv+树莓派实现人脸识别(二)人脸识别和PyQt界面整合
文章图片

录入结束会弹出对话框,点击OK,继续进行模型的训练,模型训练结束弹出训练结束对话框人脸识别|使用Opencv+树莓派实现人脸识别(二)人脸识别和PyQt界面整合
文章图片

(2)人脸识别开锁 点击按钮,调用摄像头运行识别代码
识别成功,跳出成功和欢迎某某学号的对话框
设置一个超时时间(10s左右),超过就跳出是被失败的对话框,
人脸识别|使用Opencv+树莓派实现人脸识别(二)人脸识别和PyQt界面整合
文章图片

识别成功:弹出对话框显示欢迎某某学号学生
【人脸识别|使用Opencv+树莓派实现人脸识别(二)人脸识别和PyQt界面整合】人脸识别|使用Opencv+树莓派实现人脸识别(二)人脸识别和PyQt界面整合
文章图片

(3)密码锁 输入密码开锁(考虑人脸识别的精度问题)
直接使用一个LineEdit控件
取得输入内容后和已存在密码做一个对比(密码预设为12345678)
![image-20211213200205680](image-人脸识别|使用Opencv+树莓派实现人脸识别(二)人脸识别和PyQt界面整合
文章图片

.png)
人脸识别|使用Opencv+树莓派实现人脸识别(二)人脸识别和PyQt界面整合
文章图片

(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 sqlite3from 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_())

    推荐阅读