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

相关推荐
娅娅梨26 分钟前
C++ 错题本--not found for architecture x86_64 问题
开发语言·c++
汤米粥32 分钟前
小皮PHP连接数据库提示could not find driver
开发语言·php
冰淇淋烤布蕾35 分钟前
EasyExcel使用
java·开发语言·excel
拾荒的小海螺41 分钟前
JAVA:探索 EasyExcel 的技术指南
java·开发语言
秀儿还能再秀1 小时前
机器学习——简单线性回归、逻辑回归
笔记·python·学习·机器学习
马剑威(威哥爱编程)1 小时前
哇喔!20种单例模式的实现与变异总结
java·开发语言·单例模式
白-胖-子1 小时前
【蓝桥等考C++真题】蓝桥杯等级考试C++组第13级L13真题原题(含答案)-统计数字
开发语言·c++·算法·蓝桥杯·等考·13级
好睡凯1 小时前
c++写一个死锁并且自己解锁
开发语言·c++·算法
java—大象1 小时前
基于java+springboot+layui的流浪动物交流信息平台设计实现
java·开发语言·spring boot·layui·课程设计
yyqzjw1 小时前
【qt】控件篇(Enable|geometry)
开发语言·qt