python opencv5

五、PySimpleGUI

pip install pysimplegui

PySimpleGUI 包含了大量的控件(也称为小部件或组件),这些控件可以快速构建用户界面。

1、窗口布局

layout 为一个列表,列表第一行代表窗口主界面的第一行内容

Window 方法创建一个窗口,第一个参数为窗口名字,第二个参数为窗口布局

常用布局方法:

Text :参数为文本内容,在指定位置显示文本

InputText:默认空文本(可用引号后输入默认内容),生成输入框

Button:默认空文本(可用引号后输入按钮名称),生成按钮

key:组合,指定当前控件的关键字,不重复

size:组合,指定当前控件的大小

text_color='red':指定当前控件文本字体为红色

案例:

import PySimpleGUI as sg

定义布局

layout = [[sg.Text('你好'), sg.InputText('在这儿输入内容', text_color='red')],

sg.Button('提交', size=(5, 2))

]

创建窗口

window = sg.Window('我的窗口', layout)

事件循环

while True:

event, values = window.read()

点击X和退出按钮,关闭窗口

if event in (None, "关闭"):

break

关闭窗口

window.close()

2、窗口数据

2.1、获取数据

event, values = window.read() 获取窗口的事件和输入数据

event 代表事件,按钮点击后返回该按钮的文本信息

values 返回所有输入内容,一般使用values['key值']来指定获取输入的内容

import PySimpleGUI as sg

定义布局

layout = [[sg.Text('你好'), sg.InputText('在这儿输入内容', text_color='red', key='nr')],

sg.Button('提交', size=(5, 2))

]

创建窗口

window = sg.Window('我的窗口', layout)

while True:

event, values = window.read()

id = values['nr']

if event == '提交': # 判断按钮

print(f'id={id}')

break

关闭窗口

window.close()

2.2、更新数据

import PySimpleGUI as sg

layout = [[sg.Text('你好'), sg.InputText('在这儿输入内容', text_color='red', key='nr')],

sg.Text('更新内容', key="text")\], \[sg.Button('提交', size=(5, 2))

]

window = sg.Window('我的窗口', layout)

while True:

event, values = window.read()

if event is None:

break

id = values['nr']

if event == '提交': # 判断按钮

window['text'].Update(id)

关闭窗口

window.close()

六、pymysql

连接mysql的工具

pip install pymysql

pymysql.Connect(host="localhost",

user="root", # 用户账户

passwd="1234", # 用户密码

database="demo01", # 数据库

charset="utf8"

)

完整案例:

import pymysql

import datetime

连接数据库

def conn():

创建数据库连接

con = pymysql.connect(host="localhost",

user="",

passwd="",

port=,

database="",

charset=""

)

return con

创建游标

def curs(conn1):

cur = conn1.cursor()

return cur

提交并释放资源

def turn_down(conn1, cur1):

提交操作

conn1.commit()

释放资源

cur1.close()

conn1.close()

新增用户信息

def info_add(num1, name1):

conn_add = conn()

curs_add = curs(conn_add)

定义sql

sql = "insert into user_info (user_name, user_num) value (%s, %s)"

运行sql

curs_add.execute(sql, (name1, num1))

执行增删改函数,返回一个受影响的行数数值

num = curs_add.rowcount

turn_down(conn_add, curs_add)

if num > 0:

return "添加成功"

else:

return "添加失败了,请重新尝试"

新增打卡信息

def work_add(num1, type1):

conn_add = conn()

curs_add = curs(conn_add)

date1 = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")

定义sql

sql = "insert into user_work (user_num, user_type, user_date) value (%s, %s, %s)"

运行sql

curs_add.execute(sql, (num1, type1, date1))

执行增删改函数,返回一个受影响的行数数值

num = curs_add.rowcount

turn_down(conn_add, curs_add)

if num > 0:

if type1 == 1 or type1 == '1':

return "上班打卡成功"

else:

return "下班打卡成功"

else:

return "打卡失败了"

删用户信息,通过编号或 all 删除数据

def delete(num1=None):

conn_delete = conn()

curs_delete = curs(conn_delete)

if num1 is None:

print("请检查需要删除 num 后在使用")

return

elif num1 == 'all':

sql = "delete from user_info where user_num not in ('1', 1) "

curs_delete.execute(sql)

else:

定义sql

sql = "delete from user_info where user_num = %s"

运行sql

curs_delete.execute(sql, (num1,))

执行增删改函数,返回一个受影响的行数数值

num = curs_delete.rowcount

if num > 0:

print(f"删除成功,{num}行")

else:

print("删除失败了")

turn_down(conn_delete, curs_delete)

更新数据,通过编号更新姓名,编号不可变更

def update(num1=None, name1=None):

conn_update = conn()

curs_update = curs(conn_update)

if name1 is None or num1 is None:

print("请检查需要更改内容后在使用")

else:

定义sql

sql = "update user_info set user_name = %s where user_num= %s"

curs_update.execute(sql, (name1, num1))

num = curs_update.rowcount

if num > 0:

print("更新成功")

else:

print("更新失败了")

turn_down(conn_update, curs_update)

通过编号查询用户信息

def info_query(num=None, name=None):

conn_query = conn()

curs_query = curs(conn_query)

if name is None and num is None:

定义sql

sql = "select * from user_info"

curs_query.execute(sql)

elif name is None:

定义sql

sql = "select * from user_info where user_num = %s"

curs_query.execute(sql, (num,))

elif name is not None:

sql = "select * from user_info where user_name = %s"

curs_query.execute(sql, (name,))

else:

sql = "select * from user_info where user_name = %s and user_num = %s"

curs_query.execute(sql, (name, num))

rs = curs_query.fetchall()

curs_query.close()

conn_query.close()

return rs

查询打卡信息()

def work_query(num1=None, type1=None):

conn_query = conn()

curs_query = curs(conn_query)

date2 = datetime.datetime.now().strftime("%Y-%m-%d")

if num1 is None or num1 == 'all':

定义sql

sql = "select * from user_work where DATE_format(user_date,'%%Y-%%m-%%d') = %s"

curs_query.execute(sql, (date2,))

else:

if type1 is None:

sql = "select * from user_work where user_num = %s and DATE_format(user_date,'%%Y-%%m-%%d') = %s"

curs_query.execute(sql, (num1, date2))

else:

sql = "select * from user_work where user_num = %s and user_type = %s and DATE_format(user_date,'%%Y-%%m-%%d') = %s"

curs_query.execute(sql, (num1, type1, date2))

rs = curs_query.fetchall()

七、结合使用案例

两个文件

复制代码
databaselink.py  连接数据库

同六案例

复制代码
mainfile.py  主代码

from guiitemwork.databaselink import *

import PySimpleGUI as sg

import cv2

import face_recognition

import os

import numpy as np

import pandas as pd

将视频窗口缩小

def resized_frame(frame_image):

resized_frame_image = cv2.resize(frame_image, (400, 300))

img_type = cv2.imencode(".png", resized_frame_image)[1].tobytes()

return img_type

判断编号是否存在

def data_warehouse(get_num):

a = info_query(get_num)

if a in (None, ()):

return False

else:

return True

生成一个存放所有脸部数据的列表,元素为元组

known_face_encodings = []

,图片名称,

def load_known_faces():

directory = "datasource"

遍历查找图片

for filename in os.listdir(directory):

图片路径

image_path = os.path.join(directory, filename)

image = face_recognition.load_image_file(image_path)

根据图片识别人脸信息存放到列表

face_encodings = face_recognition.face_encodings(image)

if face_encodings:

以元组形式存放(图片名称, 图片人脸信息)

known_face_encodings.append((filename, face_encodings[0]))

判断识别人脸是否存在列表,列表无数据返回字符串,未匹配返回 False,匹配返回元组(图片名称,图片完整名称)

识别条件,相似度高于百分之起始

def image_warehouse(get_face):

if len(known_face_encodings) > 0:

for face1name, face1 in known_face_encodings:

rs = np.linalg.norm(get_face - face1)

判断图片是否存在,存在返回图片的编号名称和图片完整名称

if rs < 0.3:

imag_name = face1name.split('.')[0]

return imag_name, face1name

elif rs > 0.3 and face1name != known_face_encodings[-1][0]:

continue

else:

return False

else:

return "图片仓库没有数据,请先采集"

信息采集窗口

def collection_platform(window_name):

窗口布局

layout = [

sg.Text("编号"), sg.InputText(key="num", size=(10, 1))\], \[sg.Text("姓名"), sg.InputText(key="name", size=(10, 1))\], \[sg.Button("确定", size=(5, 1)), sg.Button("重置输入信息", size=(15, 1))\], \[sg.Text("视频窗口")\], \[sg.Image(key="video", size=(400, 300))\],

创建窗口,包含layout 信息

window_collection = sg.Window("信息采集窗口", layout)

关闭上一个窗口

window_name.close()

打开摄像头

cap = cv2.VideoCapture(0)

判断摄像头开启状态,是否能获取信息

if cap.isOpened() is False:

sg.popup("摄像头未开启")

return

打开摄像头

while True:

分析摄像头获取到的信息

ret, frame = cap.read()

img_type = resized_frame(frame)

分析窗口返回数据,每次间隔10毫秒

event, values = window_collection.read(timeout=10)

判断执行操作为关闭窗口,则直接结束程序

if event in (None, sg.sgprint_close):

break

window_collection['video'].update(data=img_type)

重置信息按钮

if event == '重置输入信息':

window_collection['num'].update('')

window_collection['name'].update('')

continue

if event == '确定':

获取编号和姓名

num = values["num"]

name = values["name"]

判断是否输入编号和姓名

if num in (None, '') or name in (None, ''):

sg.popup("请输入编号和姓名")

continue

判断输入的编号是否已存在,不存在则添加,存在则无需录入

else:

user_data = data_warehouse(num)

user_date 存在返回 True

判断不存在则进行收集

if user_data is False:

获取脸部信息

face_list = face_recognition.face_locations(frame, model='hog')

脸部照片获取成功

if face_list not in (None, []):

face0 = face_recognition.face_encodings(frame, num_jitters=3)[0]

判断脸部信息是否存在于内部,不存在则收集

user_image = image_warehouse(face0)

图片仓库返回是否存在等信息

if user_image is False or '没有数据' in user_image:

写入照片仓库

x = cv2.imwrite(f"datasource\\{num}.png", frame)

保存成功则在数据库添加信息,否则不添加

if x is not None:

sg.popup("采集成功")

info_add(num, name)

continue

else:

sg.popup("采集失败,请重新采集")

continue

else:

sg.popup(f"脸部信息已存在,编号为{user_image[0]}")

continue

else:

sg.popup("未检测到脸部信息")

continue

else:

sg.popup(f"({num},{name})的信息已存在,无需重复录入")

continue

cap.release()

manage_platform()

window_collection.close()

信息更新窗口

def update_platform(window_name):

layout = [

sg.Text("姓名"), sg.InputText(key="name", size=(10, 2))\], \[sg.Button("更新姓名信息", size=(10, 1)), sg.Button("更新脸部信息", size=(10, 1))\], \[sg.Image(key="video", size=(400, 300))

]

创建窗口,包含layout 信息和cap信息

window_update = sg.Window("信息更新窗口", layout)

关闭老窗口

window_name.close()

打开摄像头

cap = cv2.VideoCapture(0)

判断摄像头开启状态,是否能获取信息

if cap.isOpened() is False:

sg.popup("摄像头未开启")

return

while True:

分析摄像头获取到的信息

ret, frame = cap.read()

img_type = resized_frame(frame)

分析窗口返回数据,每次间隔10毫秒

event, values = window_update.read(timeout=10)

判断执行操作为关闭窗口,则直接结束程序

if event in (None, sg.sgprint_close):

break

window_update['video'].update(data=img_type)

if event == '更新姓名信息':

name = values["name"]

判断是否输入编号和姓名

if name in (None, ''):

sg.popup("请输入姓名")

continue

else:

face_list = face_recognition.face_locations(frame, model='hog')

脸部照片获取成功

if face_list not in (None, []):

face0 = face_recognition.face_encodings(frame, num_jitters=3)[0]

print('-------', face0)

判断脸部信息是否存在于内部,不存在则收集

user_image = image_warehouse(face0)

图片仓库返回是否存在等信息

if user_image is False or '没有数据' in user_image:

sg.popup("无脸部数据,请先采集")

continue

else:

update(user_image[0], name)

sg.popup(f"编号:{user_image[0]} 的姓名已更新为{name}")

continue

else:

sg.popup("未检测到脸部信息")

continue

if event == '更新脸部信息':

face_list = face_recognition.face_locations(frame, model='hog')

脸部照片获取成功

if face_list in (None, []):

sg.popup("未检测到脸部信息")

continue

else:

face0 = face_recognition.face_encodings(frame, num_jitters=3)[0]

user_image = image_warehouse(face0)

if user_image is False or '没有数据' in user_image:

sg.popup("无脸部数据,请先采集")

continue

else:

x = cv2.imwrite(f"datasource\\{user_image[1]}", frame)

if x is not None:

load_known_faces()

sg.popup(f"编号:{user_image[0]} 的脸部信息更新成功")

continue

else:

sg.popup("更新失败,请重新识别")

continue

cap.release()

window_update.close()

manage_platform()

信息删除窗口

def delete_platform(window_name):

layout = [

sg.Button("清除该脸部信息", size=(15, 1)), sg.Push(), sg.Button("清除所有脸部信息", size=(15, 1))\], \[sg.Image(key="video", size=(400, 300))

]

创建窗口,包含layout 信息和cap信息

window_delete = sg.Window("信息删除窗口", layout)

window_name.close()

打开摄像头

cap = cv2.VideoCapture(0)

判断摄像头开启状态,是否能获取信息

if cap.isOpened() is False:

sg.popup("摄像头未开启")

return

while True:

分析摄像头获取到的信息

ret, frame = cap.read()

face_list = face_recognition.face_locations(frame, model='hog')

for face_list1 in face_list:

y, w, h, x = face_list1

cv2.rectangle(frame, (x, y), (w, h), (0, 255, 0), 2)

img_type = resized_frame(frame)

分析窗口返回数据,每次间隔10毫秒

event, values = window_delete.read(timeout=10)

判断执行操作为关闭窗口,则直接结束程序

if event in (None, sg.sgprint_close):

break

window_delete['video'].update(data=img_type)

if event == '清除该脸部信息':

if face_list in (None, []):

sg.popup("未检测到脸部信息")

continue

face0 = face_recognition.face_encodings(frame, num_jitters=1)

if face0 in (None, []):

sg.popup("请正面摄像头")

continue

else:

face0 = face0[0]

将脸部信息和仓库信息对比

user_image = image_warehouse(face0)

if len(known_face_encodings) < 1:

sg.popup("没有数据,无需删除")

continue

elif user_image is not False and user_image not in (None, ()):

a4 = info_query(user_image[0])

if a4[0][1] == '101':

sg.popup("管理员不能被删除")

continue

else:

os.remove(f"datasource\\{user_image[1]}")

delete(user_image[0])

sg.popup(f"编号 {a4[0][1]},姓名 {a4[0][2]} 已删除")

load_known_faces()

continue

else:

sg.popup("无该脸部信息,无需删除")

continue

if event == '清除所有脸部信息':

face_list = face_recognition.face_locations(frame, model='hog')

if face_list in (None, []):

sg.popup("请联系管理员操作")

continue

face0 = face_recognition.face_encodings(frame, num_jitters=3)[0]

将脸部信息和仓库信息对比

user_image = image_warehouse(face0)

if user_image is not False:

user_info = info_query(user_image[0])

if user_info[0][1] == '101':

delete('all')

dir_list = os.listdir(f"datasource")

if len(dir_list) == 1:

sg.popup("无额外数据,无需清理")

elif len(dir_list) > 1:

for b in dir_list:

除去管理员脸部信息

if b.split('')[0] == '101':

continue

else:

os.remove(f"datasource\\{b}")

sg.popup("数据清理完毕")

known_face_encodings.clear()

load_known_faces()

continue

else:

sg.popup("请联系管理员操作")

continue

else:

sg.popup("请联系管理员操作")

continue

cap.release()

window_delete.close()

manage_platform()

def clock_platform(window_name, type1):

layout = [[sg.Image(key="video", size=(400, 300))]]

创建窗口,包含layout 信息

window_clock = sg.Window("打卡平台", layout)

关闭老窗口

window_name.close()

打开摄像头

cap = cv2.VideoCapture(0)

判断摄像头开启状态,是否能获取信息

if cap.isOpened() is False:

sg.popup("摄像头未开启")

return

num_time = 0

while True:

ret, frame = cap.read()

face_list = face_recognition.face_locations(frame, model='hog')

for face_list1 in face_list:

y, w, h, x = face_list1

cv2.rectangle(frame, (x, y), (w, h), (0, 255, 0), 2)

img_type = resized_frame(frame)

分析窗口返回数据,每次间隔10毫秒

event, values = window_clock.read(timeout=10)

判断执行操作为关闭窗口,则直接结束程序

if event in (None, sg.sgprint_close):

break

window_clock['video'].update(data=img_type)

num_time += 10

if num_time <= 100:

window_clock.bring_to_front()

continue

else:

if face_list in (None, []):

num_time = 0

continue

else:

face0 = face_recognition.face_encodings(frame, num_jitters=2)

if face0 in (None, []):

sg.popup(f"未识别")

num_time = -100

window_clock.bring_to_front()

continue

else:

face0 = face0[0]

user_image = image_warehouse(face0)

if user_image is not False:

user_info = info_query(user_image[0])

if user_info[0][1] == '101':

sg.popup(f"管理员无需打卡")

num_time = -100

window_clock.bring_to_front()

continue

else:

a5 = work_query(user_info[0][1], type1)

if a5 not in (None, ()):

sg.popup(f"编号 {user_info[0][1]},姓名 {user_info[0][2]} 无需重复打卡")

else:

a4 = work_add(user_info[0][1], type1)

sg.popup(f"编号 {user_info[0][1]},姓名 {user_info[0][2]} {a4}")

num_time = -100

window_clock.bring_to_front()

continue

window_clock.bring_to_front()

cap.release()

window_clock.close()

manage_platform()

def clock_date(window_name):

layout = [[sg.Image(key="video", size=(500, 300))]]

创建窗口,包含layout 信息和cap信息

window_clock = sg.Window("权限校验", layout)

关闭老窗口

window_name.close()

打开摄像头

cap = cv2.VideoCapture(0)

判断摄像头开启状态,是否能获取信息

if cap.isOpened() is False:

sg.popup("摄像头未开启")

return

num_time = 0

while True:

ret, frame = cap.read()

face_list = face_recognition.face_locations(frame, model='hog')

for face_list1 in face_list:

y, w, h, x = face_list1

cv2.rectangle(frame, (x, y), (w, h), (0, 255, 0), 2)

img_type = resized_frame(frame)

分析窗口返回数据,每次间隔10毫秒

event, values = window_clock.read(timeout=10)

if event in (None, sg.sgprint_close):

break

分析摄像头获取到的信息

window_clock['video'].update(data=img_type)

num_time += 10

if num_time <= 100:

continue

else:

face_list = face_recognition.face_locations(frame, model='hog')

if face_list in (None, []):

num_time = 0

continue

else:

face0 = face_recognition.face_encodings(frame, num_jitters=1)[0]

user_image = image_warehouse(face0)

if user_image is not False:

user_info = info_query(user_image[0])

if user_info[0][1] == '101':

rt_data = work_query()

else:

rt_data = work_query(user_info[0][1])

rt_data1 = pd.DataFrame(data=rt_data, columns=['索引', '编号', '打卡类型', '打卡时间'])

rt_data1.drop(columns='索引', inplace=True)

添加打卡姓名

rt_data1['姓名1'] = rt_data1['编号'].apply(lambda x: info_query(x)[0][2])

rt_data1.insert(1, '姓名', rt_data1['姓名1'])

rt_data1.drop(columns='姓名1', inplace=True)

添加打卡类型

rt_data1['打卡类型1'] = np.where(rt_data1['打卡类型'] == 1, '上班打卡', '下班打卡')

rt_data1.drop(columns='打卡类型', inplace=True)

rt_data1.insert(2, '打卡类型', rt_data1['打卡类型1'])

rt_data1.drop(columns='打卡类型1', inplace=True)

cap.release()

work_data_display(window_clock, rt_data1)

break

else:

continue

cap.release()

window_clock.close()

manage_platform()

def work_data_display(window_name, rt_data):

table_data = []

for row in rt_data.itertuples(index=False):

table_data.append([str(row.编号), str(row.姓名), str(row.打卡类型), row.打卡时间.strftime('%Y-%m-%d %H:%M:%S')])

layout_display = [

sg.Table(values=table_data, headings=\['编号', '姓名', '打卡类型', '打卡时间'\], auto_size_columns=True, expand_x=True, expand_y=True, justification='center', num_rows=min(25, len(table_data)))

]

window_display = sg.Window("打卡数据展示", layout_display, size=(500, 300))

window_name.close()

while True:

event, values = window_display.read(timeout=10)

判断执行操作为关闭,则直接结束程序

if event in (None, sg.sgprint_close):

break

window_display.close()

manage_platform()

def manage_platform():

创建视频窗口

layout = [

sg.Button("采集", size=(10, 2)), sg.Button("更新", size=(10, 2)), sg.Button("删除", size=(10, 2)),\], \[sg.Button("上班打卡", size=(10, 2)), sg.Button("下班打卡", size=(10, 2)), sg.Button("打卡数据", size=(10, 2))\], \[sg.Button("加载图片信息", size=(10, 2)), sg.Button("关闭", size=(10, 2))

]

创建窗口,包含layout 信息和cap信息

window_manage = sg.Window("打卡管理平台平台", layout)

while True:

分析窗口返回数据,每次间隔10毫秒

event, values = window_manage.read(timeout=10)

判断执行操作为关闭,则直接结束程序

if event in (None, '关闭', sg.sgprint_close):

break

if event == '采集':

load_known_faces()

collection_platform(window_manage)

continue

if event == '更新':

if len(known_face_encodings) == 0:

load_known_faces()

update_platform(window_manage)

continue

if event == '删除':

if len(known_face_encodings) == 0:

load_known_faces()

delete_platform(window_manage)

continue

if event == '上班打卡':

if len(known_face_encodings) == 0:

load_known_faces()

clock_platform(window_manage, 1)

continue

if event == '下班打卡':

if len(known_face_encodings) == 0:

load_known_faces()

clock_platform(window_manage, 2)

continue

if event == '打卡数据':

if len(known_face_encodings) == 0:

load_known_faces()

clock_date(window_manage)

continue

if event == '加载图片信息':

load_known_faces()

sg.popup("加载完毕")

continue

window_manage.close()

if name == 'main':

manage_platform()

相关推荐
databook6 小时前
Manim实现闪光轨迹特效
后端·python·动效
Juchecar7 小时前
解惑:NumPy 中 ndarray.ndim 到底是什么?
python
用户8356290780517 小时前
Python 删除 Excel 工作表中的空白行列
后端·python
Json_7 小时前
使用python-fastApi框架开发一个学校宿舍管理系统-前后端分离项目
后端·python·fastapi
数据智能老司机14 小时前
精通 Python 设计模式——分布式系统模式
python·设计模式·架构
数据智能老司机15 小时前
精通 Python 设计模式——并发与异步模式
python·设计模式·编程语言
数据智能老司机15 小时前
精通 Python 设计模式——测试模式
python·设计模式·架构
数据智能老司机15 小时前
精通 Python 设计模式——性能模式
python·设计模式·架构
c8i15 小时前
drf初步梳理
python·django
每日AI新事件15 小时前
python的异步函数
python