代码拉取完成,页面将自动刷新
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2021/2/8 21:01
# @Author : WangHongfei
# @File : Face_Management.py
# @Software: win10 python3.9.1 opencv4.5.1 PyQt5.15.2
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PIL import Image
import numpy as np
import sys
import os
import cv2
import threading
# 导入OpenCV自带的数据集,定义多个是因为在后面有多次调用,用一个的话会报错
faceCascade = cv2.CascadeClassifier('/home/pi/Downloads/opencv-3.4.0/data/haarcascades/haarcascade_frontalface_default.xml')
faceCascade2 = cv2.CascadeClassifier('/home/pi/Downloads/opencv-3.4.0/data/haarcascades/haarcascade_frontalface_default.xml')
faceCascade3 = cv2.CascadeClassifier('/home/pi/Downloads/opencv-3.4.0/data/haarcascades/haarcascade_frontalface_default.xml')
# 定义人脸标签和初始化标签对应的人物名称
id = 0
names = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
class Ui_Face_ManageWin(QWidget):
def __init__(self):
super().__init__()
# 初始化 ID
self.ID_num = ""
self.lab_face = QLabel(self)
# 初始化进度条定时器
self.timer = QBasicTimer()
self.step = 0
# 创建数字按键
self.btn_1 = QPushButton('1', self)
self.btn_2 = QPushButton('2', self)
self.btn_3 = QPushButton('3', self)
self.btn_4 = QPushButton('4', self)
self.btn_5 = QPushButton('5', self)
self.btn_6 = QPushButton('6', self)
self.btn_7 = QPushButton('7', self)
self.btn_8 = QPushButton('8', self)
self.btn_9 = QPushButton('9', self)
self.btn_0 = QPushButton('0', self)
self.btn_del = QPushButton('del', self)
# 创建容器存放数字键,使用栅格布局
self.layoutWidget = QWidget(self)
self.gridLayout = QGridLayout(self.layoutWidget)
# 创建groupBox控件
self.groupBox = QtWidgets.QGroupBox(self)
# 创建lab_ID控件
self.lab_ID = QLabel(self.groupBox)
self.Edit_ID = QLineEdit(self.groupBox) # ID输入栏
self.btn_enter = QPushButton(self.groupBox) # 录入按钮
self.progressBar = QtWidgets.QProgressBar(self) # 进度条
self.btn_back = QPushButton(self)
# 创建定时器
self.timer_camera = QtCore.QTimer()
# 初始化摄像头数据
self.camera_init()
# 显示人脸识别视频界面
self.face_rec()
# 初始化界面
self.face_management_init()
# 定时器函数
self.timer_camera.timeout.connect(self.show_camera)
# 点击按钮开启线程
self.btn_enter.clicked.connect(self.slot_btn_enter)
# 初始化摄像头数据
def camera_init(self):
# 打开设置摄像头对象
self.cap = cv2.VideoCapture()
self.CAM_NUM = 0
self.__flag_work = 0
self.x = 0
self.count = 0
self.cap.set(4, 951) # set Width
self.cap.set(3, 761) # set Height
# 初始化界面
def face_management_ui(self):
self.setGeometry(0, 0, 1024, 600)
self.setWindowFlags(Qt.FramelessWindowHint) # 无边框
# self.show()
self.lab_face.setGeometry(12, 14, 768, 576)
# self.lab_face.setFrameShape(QtWidgets.QFrame.Box)
self.lab_face.setText("")
self.lab_ID.setGeometry(10, 40, 31, 41)
# 设置容器位置
self.layoutWidget.setGeometry(790, 320, 231, 200)
# 设置数字键高度
self.btn_0.setFixedHeight(30)
self.btn_1.setFixedHeight(30)
self.btn_2.setFixedHeight(30)
self.btn_3.setFixedHeight(30)
self.btn_4.setFixedHeight(30)
self.btn_5.setFixedHeight(30)
self.btn_6.setFixedHeight(30)
self.btn_7.setFixedHeight(30)
self.btn_8.setFixedHeight(30)
self.btn_9.setFixedHeight(30)
self.btn_del.setFixedHeight(30)
# 对数字按键字体大小进行设置
self.btn_1.setStyleSheet(
"QPushButton{color:rgb(0,0,0,255);" # 字体颜色为黑色
"font-size:30px;" # 大小为30
"font-family:Roman times;}") # Roman times字体
self.btn_2.setStyleSheet(
"QPushButton{color:rgb(0,0,0,255);" # 字体颜色为黑色
"font-size:30px;" # 大小为30
"font-family:Roman times;}") # Roman times字体
self.btn_3.setStyleSheet(
"QPushButton{color:rgb(0,0,0,255);" # 字体颜色为黑色
"font-size:30px;" # 大小为30
"font-family:Roman times;}") # Roman times字体
self.btn_4.setStyleSheet(
"QPushButton{color:rgb(0,0,0,255);" # 字体颜色为黑色
"font-size:30px;" # 大小为30
"font-family:Roman times;}") # Roman times字体
self.btn_5.setStyleSheet(
"QPushButton{color:rgb(0,0,0,255);" # 字体颜色为黑色
"font-size:30px;" # 大小为30
"font-family:Roman times;}") # Roman times字体
self.btn_6.setStyleSheet(
"QPushButton{color:rgb(0,0,0,255);" # 字体颜色为黑色
"font-size:30px;" # 大小为30
"font-family:Roman times;}") # Roman times字体
self.btn_7.setStyleSheet(
"QPushButton{color:rgb(0,0,0,255);" # 字体颜色为黑色
"font-size:30px;" # 大小为30
"font-family:Roman times;}") # Roman times字体
self.btn_8.setStyleSheet(
"QPushButton{color:rgb(0,0,0,255);" # 字体颜色为黑色
"font-size:30px;" # 大小为30
"font-family:Roman times;}") # Roman times字体
self.btn_9.setStyleSheet(
"QPushButton{color:rgb(0,0,0,255);" # 字体颜色为黑色
"font-size:30px;" # 大小为30
"font-family:Roman times;}") # Roman times字体
self.btn_0.setStyleSheet(
"QPushButton{color:rgb(0,0,0,255);" # 字体颜色为黑色
"font-size:30px;" # 大小为30
"font-family:Roman times;}") # Roman times字体
self.btn_del.setStyleSheet(
"QPushButton{color:rgb(0,0,0,255);" # 字体颜色为黑色
"font-size:30px;" # 大小为30
"font-family:Roman times;}") # Roman times字体
# 将数字存放进容器
self.gridLayout.addWidget(self.btn_1, 0, 0, 1, 1)
self.gridLayout.addWidget(self.btn_2, 0, 1, 1, 1)
self.gridLayout.addWidget(self.btn_3, 0, 2, 1, 1)
self.gridLayout.addWidget(self.btn_4, 1, 0, 1, 1)
self.gridLayout.addWidget(self.btn_5, 1, 1, 1, 1)
self.gridLayout.addWidget(self.btn_6, 1, 2, 1, 1)
self.gridLayout.addWidget(self.btn_7, 2, 0, 1, 1)
self.gridLayout.addWidget(self.btn_8, 2, 1, 1, 1)
self.gridLayout.addWidget(self.btn_9, 2, 2, 1, 1)
self.gridLayout.addWidget(self.btn_0, 3, 0, 1, 1)
self.gridLayout.addWidget(self.btn_del, 3, 1, 1, 2)
# 对groupBox进行设置
self.groupBox.setTitle("录入人脸")
self.groupBox.setGeometry(787, 80, 230, 150)
self.groupBox.setStyleSheet(
"QGroupBox {\n"
"border-width:2px;\n"
"border-style:solid;\n"
"border-color:lightGray;\n"
"font: 75 20pt \"Aharoni\";\n"
"margin-top: 0.5ex;\n"
"}\n"
"QGroupBox::title {\n"
"subcontrol-origin: margin;\n"
"subcontrol-position: top left;\n"
"left:10px;\n"
"margin-left: 0px;\n"
"padding:0px;\n"
"}")
# 设置groupBox里面的控件
self.lab_ID.setText("ID")
self.lab_ID.setGeometry(10, 45, 31, 41)
self.lab_ID.setStyleSheet("font: 18pt;")
self.Edit_ID.setGeometry(45, 45, 170, 41)
self.Edit_ID.setStyleSheet("font: 18pt;")
self.btn_enter.setText("开始录入")
self.btn_enter.setGeometry(55, 100, 120, 40)
self.btn_enter.setStyleSheet("font: 75 16pt;")
self.progressBar.setGeometry(800, 260, 210, 20)
# self.progressBar.setProperty("value", 0)
self.btn_back.setText("返回")
self.btn_back.setGeometry(870, 540, 70, 40)
self.btn_back.setStyleSheet("font: 75 16pt;")
# 点击数字按钮输入用户名和密码
self.btn_0.clicked.connect(self.slot_btn_0)
self.btn_1.clicked.connect(self.slot_btn_1)
self.btn_2.clicked.connect(self.slot_btn_2)
self.btn_3.clicked.connect(self.slot_btn_3)
self.btn_4.clicked.connect(self.slot_btn_4)
self.btn_5.clicked.connect(self.slot_btn_5)
self.btn_6.clicked.connect(self.slot_btn_6)
self.btn_7.clicked.connect(self.slot_btn_7)
self.btn_8.clicked.connect(self.slot_btn_8)
self.btn_9.clicked.connect(self.slot_btn_9)
self.btn_del.clicked.connect(self.slot_btn_del)
# # 点击返回按键返回上一界面___________________________________________________________________________关联上一窗口
# self.btn_back.clicked.connect(Ui)
# 点击数字按钮输入用户名和密码
def slot_btn_0(self):
ID_num0 = self.btn_0.text()
self.ID_num = self.ID_num + ID_num0
self.Edit_ID.setText(self.ID_num)
def slot_btn_1(self):
ID_num1 = self.btn_1.text()
self.ID_num = self.ID_num + ID_num1
self.Edit_ID.setText(self.ID_num)
def slot_btn_2(self):
ID_num2 = self.btn_2.text()
self.ID_num = self.ID_num + ID_num2
self.Edit_ID.setText(self.ID_num)
def slot_btn_3(self):
ID_num3 = self.btn_3.text()
self.ID_num = self.ID_num + ID_num3
self.Edit_ID.setText(self.ID_num)
def slot_btn_4(self):
ID_num4 = self.btn_4.text()
self.ID_num = self.ID_num + ID_num4
self.Edit_ID.setText(self.ID_num)
def slot_btn_5(self):
ID_num5 = self.btn_5.text()
self.ID_num = self.ID_num + ID_num5
self.Edit_ID.setText(self.ID_num)
def slot_btn_6(self):
ID_num6 = self.btn_6.text()
self.ID_num = self.ID_num + ID_num6
self.Edit_ID.setText(self.ID_num)
def slot_btn_7(self):
ID_num7 = self.btn_7.text()
self.ID_num = self.ID_num + ID_num7
self.Edit_ID.setText(self.ID_num)
def slot_btn_8(self):
ID_num8 = self.btn_8.text()
self.ID_num = self.ID_num + ID_num8
self.Edit_ID.setText(self.ID_num)
def slot_btn_9(self):
ID_num9 = self.btn_9.text()
self.ID_num = self.ID_num + ID_num9
self.Edit_ID.setText(self.ID_num)
# 将字符串从最后一位开始删除
def slot_btn_del(self):
self.ID_num = self.ID_num[:-1]
self.Edit_ID.setText(self.ID_num)
# 显示人脸识别视频界面
def face_rec(self):
if self.timer_camera.isActive() == False:
flag = self.cap.open(self.CAM_NUM)
if flag == False:
msg = QtWidgets.QMessageBox.warning(self, u"Warning", u"请检查相机与电脑是否连接正确!!!",
buttons=QtWidgets.QMessageBox.Ok,
defaultButton=QtWidgets.QMessageBox.Ok)
else:
self.timer_camera.start(50)
else:
self.timer_camera.stop()
self.cap.release()
def show_camera(self):
flag, self.image = self.cap.read()
self.image = cv2.flip(self.image, -1)
gray = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
faces = faceCascade.detectMultiScale(
gray,
scaleFactor=1.2,
minNeighbors=5,
minSize=(20, 20)
)
for (x, y, w, h) in faces:
cv2.rectangle(self.image, (x, y), (x + w, y + h), (255, 0, 0), 2)
roi_gray = gray[y:y + h, x:x + w]
roi_color = self.image[y:y + h, x:x + w]
# 将视频显示在了label上
show = cv2.resize(self.image, (768, 576))
show = cv2.cvtColor(show, cv2.COLOR_BGR2RGB)
showVideo = QtGui.QImage(show.data, show.shape[1], show.shape[0], QtGui.QImage.Format_RGB888)
self.lab_face.setPixmap(QtGui.QPixmap.fromImage(showVideo))
# 点击按钮开启线程
def slot_btn_enter(self):
self.count = 0
self.step = 0
# 创建线程并开启
self.thread = threading.Thread(target=self.thread_pic)
self.thread.start()
# 开启进度条定时器
self.timer.start(100, self)
# 加载进度条
def timerEvent(self, e):
if self.step > 58:
self.timer.stop()
return
self.step = self.count + 1
self.progressBar.setValue(self.count)
# 录入人脸线程
def thread_pic(self):
print("线程出没!!!")
print(self.Edit_ID.text())
# 创建目录,将获取的人脸照片放入指定的文件夹
self.file = "./Face_data/"
while (True):
ret, self.img = self.cap.read()
# 垂直翻转视频图像
self.img = cv2.flip(self.img, -1)
# 灰度化处理
gray = cv2.cvtColor(self.img, cv2.COLOR_BGR2GRAY)
faces = faceCascade2.detectMultiScale(gray, 1.3, 5)
# 判断是否存在文件夹如果不存在则创建为文件夹
self.folder = os.path.exists(self.file)
if not self.folder:
# makedirs 满权限创建文件时如果路径不存在会创建这个路径
os.makedirs(self.file)
os.chmod(self.file, 0o777)
for (x, y, w, h) in faces:
cv2.rectangle(self.img, (x, y), (x + w, y + h), (255, 0, 0), 2)
self.count += 1
# 将捕获的图像保存到指定的文件夹中
bool = cv2.imwrite(self.file + "/User." + str(self.Edit_ID.text()) + '.' + str(self.count) + ".png",
gray[y:y + h, x:x + w])
# 取60张人脸样本,停止录像
if self.count >= 60:
print("OK!")
break
self.recognizer = cv2.face.LBPHFaceRecognizer_create()
# 函数获取图像和标签数据
def getImagesAndLabels(path):
imagePaths = [os.path.join(path, f) for f in os.listdir(path)]
faceSamples = []
ids = []
self.progressBar.setProperty("value", 65)
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 = faceCascade3.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
self.progressBar.setProperty("value", 75)
print("\n [INFO] Training faces. It will take a few seconds. Wait ...")
# 调用函数,传递文件夹路径参数
faces, ids = getImagesAndLabels(self.file)
self.recognizer.train(faces, np.array(ids))
self.progressBar.setProperty("value", 85)
# 创建文件夹
self.triningfile = "./Face_training/"
self.folder1 = os.path.exists(self.triningfile)
if not self.folder1:
os.makedirs(self.triningfile)
os.chmod(self.triningfile, 0o777)
# 将训练好的数据保存到指定文件夹中
self.recognizer.write(self.triningfile + "/trainer.yml")
# 打印经过训练的人脸编号和结束程序
print("\n [INFO] {0} faces trained. Exiting Program".format(len(np.unique(ids))))
self.progressBar.setProperty("value", 100)
# if __name__ == '__main__':
# app = QApplication(sys.argv)
# ex = Ui_Face_ManageWin()
# sys.exit(app.exec_())
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。