基于pyqt+OpenCV设计的用户密码或人脸识别登录GUI程序设计

您所在的位置:网站首页 pyqt设计登录界面 基于pyqt+OpenCV设计的用户密码或人脸识别登录GUI程序设计

基于pyqt+OpenCV设计的用户密码或人脸识别登录GUI程序设计

2024-07-09 16:35| 来源: 网络整理| 查看: 265

开发环境:

Windows7 64位python3.7pyqt5pycharmOpenCV3.4QT DesignerPyUIC

目录

 功能介绍

程序代码

软件截图

 功能介绍

该程序主要在pycharm中开发,导入至pycharm里的外部工具有QT Designer和PyUIC。其中QT Designer用于GUI布局,PyUIC用于将ui文件转换为.py可执行文件。完整的程序包可点击资料包下载。在这里简单介绍程序的执行步骤或功能,并附上相关截图。

首先启动程序,进入登录界面,包括用户名密码登录方式和人脸识别登录方式。关于用户名登录方式,用户名来自人脸识别信息录入的人名,密码是存储在一个password.txt文本中。这种登录方式会有用户名不存在提示、密码错误提示,若登录成功,则会弹出“请编写主程序的对话框”,当然读者也可以编写自定义程序。

而关于人脸识别登录,有两个按钮:“人脸信息录入按钮”和“人脸识别登录”按钮。进入“人脸信息录入按钮”后,要求输入用户名,然后点击“确认”按钮,进行人脸数据采集、人脸模型训练、最后弹出“人脸信息录入成功”消息框。

温馨提示:

输入的用户名将保存在user_names.txt文本中,并以逗号隔开。人脸数据采集,小编设置的为150张图片。

点击“人脸识别登录”按钮,则会弹出人脸识别窗口,并在人脸框的左上角显示识别到的人物所对应的序号(由于OpenCV显示汉字比较麻烦,所以这里选择人名所对应的序号作为识别结果),在人脸框的左下角显示识别结果的置信度。

人脸识别程序设计:

如果识别置信度大于60%,则为识别成功,并退出人脸识别界面,弹出“欢迎您:人名”对话框。如果识别不出来,则等待10秒左右退出识别界面,并弹出“人脸识别失败”对话框。

注意:

登录界面的布局设计是在QT Designer中完成,在转成.py文件后,需要对程序作一些修改和补充,以满足实际开发需求,比如:类申明中,object需要改成QWidget,否则不能弹出QMessageBox消息对话框。

程序代码

下面给出完整的程序,主要由三个程序组成:login.py、faces_input_frame.py和face_recognize.py。

# -*- coding: utf-8 -*- #login.py程序 from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5.QtWidgets import QMessageBox,QWidget from faces_input_frame import Ui_Dialog import os class Ui_Form(QWidget): #将object改为QWidget,才能弹出消息对话框 def __init__(self): super(Ui_Form,self).__init__() #用户添加代码 def setupUi(self, Form): self.form=Form #用户添加代码 Form.setObjectName("Form") Form.setMinimumSize(QtCore.QSize(329, 230)) Form.setMaximumSize(QtCore.QSize(400, 230)) Form.setStyleSheet("") self.label = QtWidgets.QLabel(Form) self.label.setGeometry(QtCore.QRect(63, 43, 64, 16)) font = QtGui.QFont() font.setPointSize(12) self.label.setFont(font) self.label.setObjectName("label") self.label_2 = QtWidgets.QLabel(Form) self.label_2.setGeometry(QtCore.QRect(63, 80, 48, 16)) font = QtGui.QFont() font.setPointSize(12) self.label_2.setFont(font) self.label_2.setObjectName("label_2") self.lineEdit_2 = QtWidgets.QLineEdit(Form) self.lineEdit_2.setGeometry(QtCore.QRect(121, 80, 133, 20)) self.lineEdit_2.setEchoMode(QtWidgets.QLineEdit.Password) self.lineEdit_2.setCursorPosition(0) self.lineEdit_2.setObjectName("lineEdit_2") self.pushButton = QtWidgets.QPushButton(Form) self.pushButton.setGeometry(QtCore.QRect(70, 150, 75, 23)) font = QtGui.QFont() font.setPointSize(12) self.pushButton.setFont(font) self.pushButton.setObjectName("pushButton") self.pushButton_2 = QtWidgets.QPushButton(Form) self.pushButton_2.setGeometry(QtCore.QRect(170, 150, 75, 23)) font = QtGui.QFont() font.setPointSize(12) self.pushButton_2.setFont(font) self.pushButton_2.setObjectName("pushButton_2") self.checkBox = QtWidgets.QCheckBox(Form) self.checkBox.setGeometry(QtCore.QRect(63, 110, 151, 20)) font = QtGui.QFont() font.setPointSize(12) self.checkBox.setFont(font) self.checkBox.setObjectName("checkBox") self.lineEdit_3 = QtWidgets.QLineEdit(Form) self.lineEdit_3.setGeometry(QtCore.QRect(121, 41, 133, 20)) self.lineEdit_3.setObjectName("lineEdit_3") self.pushButton_face_pass = QtWidgets.QPushButton(Form) self.pushButton_face_pass.setGeometry(QtCore.QRect(279, 100, 104, 41)) self.pushButton_face_pass.setMaximumSize(QtCore.QSize(16777215, 16777213)) font = QtGui.QFont() font.setPointSize(12) self.pushButton_face_pass.setFont(font) self.pushButton_face_pass.setObjectName("pushButton_face_pass") self.pushButton_face_input = QtWidgets.QPushButton(Form) self.pushButton_face_input.setGeometry(QtCore.QRect(280, 31, 104, 41)) self.pushButton_face_input.setMaximumSize(QtCore.QSize(16777215, 16777213)) font = QtGui.QFont() font.setPointSize(12) self.pushButton_face_input.setFont(font) self.pushButton_face_input.setObjectName("pushButton_face_input") self.retranslateUi(Form) self.pushButton.clicked.connect(self.close) self.pushButton_2.clicked.connect(self.open) self.pushButton_face_input.clicked.connect(self.faceinput) self.pushButton_face_pass.clicked.connect(self.facepass) def retranslateUi(self, Form): _translate = QtCore.QCoreApplication.translate Form.setWindowTitle(_translate("Form", "Form")) self.label.setText(_translate("Form", "用户名:")) self.label_2.setText(_translate("Form", "密码:")) self.pushButton.setText(_translate("Form", "取消")) self.pushButton_2.setText(_translate("Form", "确认")) self.checkBox.setText(_translate("Form", "记住用户名和密码")) self.pushButton_face_pass.setText(_translate("Form", "人脸识别登录")) self.pushButton_face_input.setText(_translate("Form", "人脸信息录入")) def open(self): #--------判断用户是否存在-------------- fl = open('user_names.txt', 'r+') pre_name = fl.read() names = pre_name.split(',') fl.close() if self.lineEdit_3.text() in names: fl = open('password.txt', 'r+') password= fl.read() if self.lineEdit_2.text() ==password: reply=QMessageBox.information(self,'提示','请编写主程序',QMessageBox.Close) else: reply=QMessageBox.information(self,'提示','密码错误',QMessageBox.Close) else: reply=QMessageBox.information(self,'提示','用户不存在',QMessageBox.Close) def close(self, event): self.close() def faceinput(self,event): self.form.hide() Form1=QtWidgets.QDialog() ui=Ui_Dialog() ui.setupUi(Form1) Form1.show() Form1.exec_() self.form.show() #子窗口关闭后,主窗口显示 def facepass(self,event): import face_recognize get_name=face_recognize.recognize_face()#返回识别的人名 if get_name=="unknown": reply = QMessageBox.information(self, '提示', '人脸识别失败', QMessageBox.Close) else: reply = QMessageBox.information(self, '提示', "欢迎您:"+get_name, QMessageBox.Ok) print("编写其他程序") if __name__=="__main__": import sys app=QtWidgets.QApplication(sys.argv) widget=QtWidgets.QWidget() ui=Ui_Form() ui.setupUi(widget) widget.show() sys.exit(app.exec_()) # -*- coding: utf-8 -*- #faces_input_frame.py程序 # Form implementation generated from reading ui file 'faces_input_frame.ui' # # Created by: PyQt5 UI code generator 5.12.2 # # WARNING! All changes made in this file will be lost! import face_recognize from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5.QtWidgets import QMessageBox,QWidget class Ui_Dialog(QWidget): def setupUi(self, Dialog): self.form=Dialog #用户添加代码 Dialog.setObjectName("Dialog") Dialog.resize(315, 104) Dialog.setMinimumSize(QtCore.QSize(315, 104)) Dialog.setMaximumSize(QtCore.QSize(315, 104)) Dialog.setAutoFillBackground(False) self.Button_Enter = QtWidgets.QPushButton(Dialog) self.Button_Enter.setGeometry(QtCore.QRect(221, 21, 75, 27)) font = QtGui.QFont() font.setPointSize(14) self.Button_Enter.setFont(font) self.Button_Enter.setObjectName("Button_Enter") self.Button_Exit=QtWidgets.QPushButton(Dialog) self.Button_Exit.setGeometry(QtCore.QRect(221, 54, 75, 27)) font = QtGui.QFont() font.setPointSize(14) self.Button_Exit.setFont(font) self.Button_Exit.setObjectName("Button_Exit") self.face_name=QtWidgets.QLabel(Dialog) self.face_name.setGeometry(QtCore.QRect(40, 20, 131, 16)) font = QtGui.QFont() font.setPointSize(12) self.face_name.setFont(font) self.face_name.setObjectName("face_name") self.face_name_frame=QtWidgets.QLineEdit(Dialog) self.face_name_frame.setGeometry(QtCore.QRect(30, 40, 167, 31)) font = QtGui.QFont() font.setPointSize(12) self.face_name_frame.setFont(font) self.face_name_frame.setText("") self.face_name_frame.setObjectName("face_name_frame") self.retranslateUi(Dialog) self.Button_Enter.clicked.connect(self.Enter) self.Button_Exit.clicked.connect(self.ext) def retranslateUi(self, Dialog): _translate = QtCore.QCoreApplication.translate Dialog.setWindowTitle(_translate("Dialog", "Dialog")) self.Button_Enter.setText(_translate("Dialog", "确认")) self.Button_Exit.setText(_translate("Dialog", "退出")) self.face_name.setText(_translate("Dialog", "请输入您的姓名:")) def Enter(self): fl = open('user_names.txt','a+') if self.face_name_frame.text()=="": #输入为空时 reply = QMessageBox.information(self, '提示', '请输入有效用户名', QMessageBox.Ok) else: fl.write(self.face_name_frame.text()+',') fl.close() reply = QMessageBox.information(self, '提示', '正在采集人脸数据', QMessageBox.Ok) face_recognize.Collect_faces() reply = QMessageBox.information(self, '提示', '正在训练数据', QMessageBox.Ok) face_recognize.Training_faces() reply = QMessageBox.information(self, '提示', '人脸信息录入成功', QMessageBox.Ok) def ext(self,event): self.form.close() if __name__ == "__main__": import sys app=QtWidgets.QApplication(sys.argv) Dialog=QtWidgets.QDialog() ui = Ui_Dialog() ui.setupUi(Dialog) Dialog.show() sys.exit(app.exec_()) # -*- coding: utf-8 -*- #face_recognize.py程序 def Collect_faces(): import cv2 import os # 调用笔记本内置摄像头,所以参数为0,如果有其他的摄像头可以调整参数为1,2 cap = cv2.VideoCapture(0) face_detector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') fl = open('user_names.txt', 'r+') pre_name=fl.read() name = pre_name.split(',') face_id=len(name) - 2#去掉逗号及以零开始的序号,表示某人的一些列照片 fl.close() #face_id = input('\n enter user id:') #输入序号,表示某人的一些列照片 print('\n Initializing face capture. Look at the camera and wait ...') count = 0 while True: # 从摄像头读取图片 sucess, img = cap.read() # 转为灰度图片 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 检测人脸 faces = face_detector.detectMultiScale(gray, 1.3, 5) for (x, y, w, h) in faces: cv2.rectangle(img, (x, y), (x + w, y + w), (255, 0, 0)) count += 1 # 保存图像,从原始照片中截取人脸尺寸 cv2.imwrite("Facedata/User." +str(face_id) + '.' + str(count) + '.jpg', gray[y: y + h, x: x + w]) cv2.imshow('image', img) # 保持画面的持续。 k = cv2.waitKey(1) if k == 27: # 通过esc键退出摄像 break elif count >=150: # 得到150个样本后退出摄像 break # 关闭摄像头 cap.release() cv2.destroyAllWindows() def Training_faces(): import numpy as np from PIL import Image import os import cv2 # 人脸数据路径 path = 'Facedata' 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)] # join函数的作用? faceSamples = [] ids = [] for imagePath in imagePaths: PIL_img = Image.open(imagePath).convert('L') # convert it to grayscale 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('Training faces. It will take a few seconds. Wait ...') faces, ids = getImagesAndLabels(path) recognizer.train(faces, np.array(ids)) recognizer.write(r'face_trainer\trainer.yml') print("{0} faces trained. Exiting Program".format(len(np.unique(ids)))) def recognize_face(): #识别时间10秒;如果置信度大于60%,则识别成功并退出界面;否则至10秒后识别失败并退出 import cv2 recognizer = cv2.face.LBPHFaceRecognizer_create() recognizer.read('face_trainer/trainer.yml') cascadePath = "haarcascade_frontalface_default.xml" faceCascade = cv2.CascadeClassifier(cascadePath) font = cv2.FONT_HERSHEY_SIMPLEX idnum =None #初始化识别序号 fl = open('user_names.txt', 'r+') pre_name = fl.read() names = pre_name.split(',') cam = cv2.VideoCapture(0) minW = 0.1 * cam.get(3) minH = 0.1 * cam.get(4) time=0 while True: result = "unknown" #初始化识别失败 time+=1 ret, img = cam.read() gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) faces = faceCascade.detectMultiScale( gray, scaleFactor=1.2, minNeighbors=5, minSize=(int(minW), int(minH)) ) face_num=None #初始化人脸序号 for (x, y, w, h) in faces: cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2) idnum, confidence = recognizer.predict(gray[y:y + h, x:x + w]) if confidence>60: #60%的识别置信度 face_num=idnum result= names[idnum] confidence = "{0}%".format(round(100 - confidence)) cam.release() cv2.destroyAllWindows() #退出摄像头 return result else: confidence = "{0}%".format(round(100 - confidence)) cv2.putText(img, str(face_num), (x + 5, y - 5), font, 1, (0, 0, 255), 1) cv2.putText(img, str(confidence), (x + 5, y + h - 5), font, 1, (0, 0, 0), 1) cv2.imshow('camera', img)#弹出摄像头与否 k = cv2.waitKey(1) if k == 27: break elif time>100: # 大约10秒识别时间 break cam.release() cv2.destroyAllWindows() return result #返回识别结果:人名或“unknown” 软件截图

 欢迎关注微信公众号“Py生活”,学知识,享生活!

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3