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

image

image

輸入學號,開始錄入

將學號存儲在文件中,用於人臉識別時的id和人臉匹配

image
image

錄入結束會彈出對話框,點擊OK,繼續進行模型的訓練,模型訓練結束彈出訓練結束對話框
image

(2)人臉識別開鎖

點擊按鈕,調用攝像頭運行識別代碼

識別成功,跳出成功和歡迎某某學號的對話框

設置一個超時時間(10s左右),超過就跳出是被失敗的對話框,

image

識別成功:彈出對話框顯示歡迎某某學號學生

image

(3)密碼鎖

輸入密碼開鎖(考慮人臉識別的精度問題)

直接使用一個LineEdit控件

取得輸入內容后和已存在密碼做一個對比(密碼預設為12345678)

![image-20211213200205680](image-image
.png)

image

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM