一、利用PySimpleGUI构建窗口界面
1.1、 PySimpleGUI 的安装
pip install pysimplegui
1.2、构建主界面
import PySimpleGUI as psg
from face_gui.face_gather import face_gather
from face_gui.face_videos import face_video
from face_gui.face_tuopens import face_tuopen
def face_gui():
layout = [
[psg.Text('员工编号', size=(6, 1), font=('微软雅黑', 12)), psg.InputText(key='num', size=(20, 1))],
[psg.Text('员工姓名', size=(6, 1), font=('微软雅黑', 12)), psg.InputText(key='name', size=(20, 1))],
[psg.Text(key='nsg')],
[psg.Text(key='msg')],
[psg.Button('人脸采集'), psg.Button('打卡'), psg.Button('选择图片'), psg.Button('退出')],
[psg.Image(key='video', size=(640, 480))]
]
window = psg.Window('人脸识别系统', layout, icon='../images/hq.ico')
while True:
event, values = window.read()
if event == psg.WIN_CLOSED or event == '退出':
break
if event == "人脸采集":
ygid = values['num']
name = values['name']
window['msg'].update(f'编号:{ygid},姓名:{name}')
face_video(values)
if event == "打卡":
face_gather()
if event == "选择图片":
face_tuopen()
window.close()
1.3、实现人脸信息采集
import cv2
import PySimpleGUI as psg
from face_gui.face_mysql import add
def face_video(values):
cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)
if not cap.isOpened():
print("摄像头打开失败")
return
camera_layout = [
[psg.Image(key='video', size=(640, 480))],
[psg.Button('识别'), psg.Button('关闭摄像头')]
]
camera_window = psg.Window('信息采集', camera_layout, icon='../images/hq.ico')
while True:
event, _ = camera_window.read(timeout=10)
if event == psg.WIN_CLOSED or event == '关闭摄像头':
break
ret, frame = cap.read()
if ret:
imgbytes = cv2.imencode('.png', frame)[1].tobytes()
camera_window['video'].update(data=imgbytes)
if event == '识别':
num = values['num']
name = values['name']
iss = cv2.imwrite(f"../face_train_images/{num}.png", frame)
if iss:
isadd = add(name, num)
if isadd:
psg.popup('添加成功')
else:
psg.popup('添加失败')
camera_window.close()
cap.release()
1.4、实现人脸识别
import os
import cv2
import PySimpleGUI as psg
import face_recognition
import numpy as np
from face_gui.face_mysql import select
def face_gather():
cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)
if not cap.isOpened():
print("摄像头没有开启")
return
layout = [
[psg.Image(key="video")],
[psg.Button("验证"), psg.Button("关闭")]
]
camera_window = psg.Window("验证", layout)
while True:
event, value = camera_window.read(timeout=10)
ret, frame = cap.read()
if event in (None, "关闭"):
break
if ret:
imttype = cv2.imencode(".png", frame)[1].tobytes()
camera_window["video"].update(imttype)
if event == "验证":
list_dir = os.listdir("../face_train_images")
if len(list_dir) > 0:
for i in list_dir:
print(i)
img = cv2.imread(f"../face_train_images/{i}")
if img is None:
print("没有读取图片")
break
else:
en1 = face_recognition.face_encodings(img)[0]
en2 = face_recognition.face_encodings(frame)[0]
rs = np.linalg.norm(en1 - en2)
print(rs)
if rs < 0.6:
b = i.split(".")[0]
select(b)
psg.popup("打卡成功")
break
else:
psg.popup("人脸库没有此人")
break
cap.release()
camera_window.close()
1.5、文件上传
import io
import PySimpleGUI as psg
from PIL import Image
def face_tuopen():
layout = [
[psg.Text('请选择一张图片或视频:')],
[psg.Input(key='-FILE-', enable_events=True),
psg.FileBrowse(
file_types=(("Image and Video Files", "*.png;*.jpg;*.jpeg;*.gif;*.bmp;*.mp4;*.avi;*.mov;*.mkv"),))],
[psg.Button('退出')],
[psg.Image(key='-IMAGE-', size=(640, 480))]
]
window = psg.Window('文件处理', layout, size=(640, 480))
while True:
event, values = window.read()
if event in (psg.WINDOW_CLOSED, '退出'):
break
elif event == '-FILE-':
image_path = values['-FILE-']
print(image_path)
if image_path:
try:
image = Image.open(image_path)
image.thumbnail((640, 480))
bio = io.BytesIO()
image.save(bio, format='PNG')
window['-IMAGE-'].update(data=bio.getvalue())
except Exception as e:
print(f"Error loading image: {e}")
psg.popup_error(f"无法加载图像: {e}")
window.close()
1.6、数据库操作
import pymysql
def add(name, num):
con = pymysql.connect(
host='localhost',
port=3306,
user='root',
password='123456',
database='face',
charset='utf8'
)
cur = con.cursor()
sql = "insert into user(user_name,user_num) value (%s,%s)"
cur.execute(sql, (name, num))
num = cur.rowcount
con.commit()
cur.close()
con.close()
if num > 0:
print("新增成功")
return True
else:
print("新增失败")
return False
def select(num):
with pymysql.connect(
host='localhost',
port=3306,
user='root',
password='123456',
database='face',
charset='utf8'
) as db:
with db.cursor() as cursor:
sql = "select * from user where user_num=%s"
try:
cursor.execute(sql, (num,))
results = cursor.fetchall()
if results:
for row in results:
uesr_id = row[0]
uesr_name = row[1]
uesr_num = row[2]
print(f"uesr_id:{uesr_id}, uesr_name:{uesr_name}, uesr_num:{uesr_num}")
else:
print("未找到匹配的记录")
except Exception as e:
print(f"Error: {e}")
def delete(num):
with pymysql.connect(
host='localhost',
port=3306,
user='root',
password='123456',
database='face',
charset='utf8'
) as db:
with db.cursor() as cursor:
sql = "DELETE FROM user WHERE uesr_num=%s"
try:
cursor.execute(sql, (num,))
db.commit()
print("删除成功")
except Exception as e:
print(f"Error: {e}")
db.rollback()
print("删除失败")
def update(name, num, new_name=None, new_num=None):
with pymysql.connect(
host='localhost',
port=3306,
user='root',
password='123456',
database='face',
charset='utf8'
) as db:
with db.cursor() as cursor:
updates = []
params = []
if new_name is not None:
updates.append("uesr_name=%s")
params.append(new_name)
if new_num is not None:
updates.append("uesr_num=%s")
params.append(new_num)
if not updates:
print("未提供任何更新内容")
return
sql = f"UPDATE user SET {', '.join(updates)} WHERE user_name=%s AND user_num=%s"
params.extend([name, num])
try:
cursor.execute(sql, params)
db.commit()
print("更新成功")
except Exception as e:
print(f"Error: {e}")
db.rollback()
print("更新失败")
1.7、主函数调用
from face_gui.face_gui_windows import face_gui
if __name__ == '__main__':
face_gui()