使用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, 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)

使用Opencv+树莓派实现人脸识别(二)人脸识别和PyQt界面整合_第1张图片

使用Opencv+树莓派实现人脸识别(二)人脸识别和PyQt界面整合_第2张图片

输入学号,开始录入

将学号存储在文件中,用于人脸识别时的id和人脸匹配

使用Opencv+树莓派实现人脸识别(二)人脸识别和PyQt界面整合_第3张图片使用Opencv+树莓派实现人脸识别(二)人脸识别和PyQt界面整合_第4张图片

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

(2)人脸识别开锁

点击按钮,调用摄像头运行识别代码

识别成功,跳出成功和欢迎某某学号的对话框

设置一个超时时间(10s左右),超过就跳出是被失败的对话框,

使用Opencv+树莓派实现人脸识别(二)人脸识别和PyQt界面整合_第6张图片

识别成功:弹出对话框显示欢迎某某学号学生

使用Opencv+树莓派实现人脸识别(二)人脸识别和PyQt界面整合_第7张图片

(3)密码锁

输入密码开锁(考虑人脸识别的精度问题)

直接使用一个LineEdit控件

取得输入内容后和已存在密码做一个对比(密码预设为12345678)

![image-20211213200205680](image-使用Opencv+树莓派实现人脸识别(二)人脸识别和PyQt界面整合_第8张图片
.png)

使用Opencv+树莓派实现人脸识别(二)人脸识别和PyQt界面整合_第9张图片

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

你可能感兴趣的:(人脸识别,python,语音识别,pyqt,opencv)