IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 【物联网树莓派毕设05】给人脸识别门禁做个tkinter可登录可控制界面并显示结果,超详细 -> 正文阅读

[嵌入式]【物联网树莓派毕设05】给人脸识别门禁做个tkinter可登录可控制界面并显示结果,超详细

一、前期准备

? ? ? ? 1、这次是结合前面的做个阶段性总结,在硬件端加个简单的tkinter界面,管理员登录并可以控制人脸识别门禁的开关,以及实时显示视频流,显示人脸识别结果,记忆日志记录。具体如何在树莓派上做的一些准备,可参考前几期:

???? ? ?【物联网树莓派毕设01】树莓派4B快速实现VNC连接

????????【物联网树莓派毕设02】树莓派4B安装Pyhton3及opencv

????????【物联网树莓派毕设03】树莓派4B调用百度API快速实现人脸识别

? ? ? ? 【物联网树莓派毕设04】Arduino实现电梯及人脸识别门禁

????????2、安装必要的库,如已安装可跳过

python -m pip install --upgrade pip //先更新pip
pip install opencv-python //摄像头
pip install pillow //图像控件
pip install baidu-aip //百度api
pip install pyserial //串口

????????3、效果展示

?

?二、具体实现

? ? ? ? 1、实现tkinter界面跳转,有2个方法

? ? ? ? (1)设置1个根窗口,2个frame,利用destory方法,实现登录frame跳转至首页frame,缺点是跳转之后不可回到登录frame,即只能实现一次跳转,如需继续跳转,需要新建frame,如法炮制

top = tk.Tk()#新建tk根窗口
top.title("人脸识别门禁系统")
top.geometry("300x300+350+180")#设置窗口位置
top.resizable(width=False, height=False) #设置窗口不可改变

login = login(top)#进入login frame
try:
   top.wait_window(window=login)#直到login窗口销毁,login界面跳转index界面
   index(top)#进入index frame
except Exception as e:
   print("erro:",e)#异常捕获处理
   pass

top.mainloop()  #窗口消息循环     

? ? ? ? (2)设置2个根窗口,利用lambda表达式即可,可以实现两个窗口来回切换

def login():
    root1=tk.Tk()
    root1.geometry("300x300+450+200")#设置窗口位置
    bu1=tk.Button(root1,text="登录",command=lambda:[root1.destroy(),index()])
    bu1.pack()
    root1.mainloop()

def index():
    root2=tk.Tk()
    root2.geometry("300x300+450+200")#设置窗口位置
    bu1=tk.Button(root2,text="登陆成功,回到登录",command=lambda:[root2.destroy(),login()])
    bu1.pack()
    root2.mainloop()

login()

? ? ? ? 2、放置各组件在容器内的位置的3个方法

? ? ? ? (1)pack():默认先使用的放到上面,然后依次向下排,它会给我们的组件一个自认为合适的位置 和大小,这是默认方式。【进入学习pack】

? ? ? ? (2)grid():类比多维数组,会根据组件自动计算。【进入学习grid】

? ? ? ? (3)place():设置控件在窗体或窗口内的绝对地址或相对地址。【进入学习place】

? ? ? ? 3、tk的Frame、Toplevel、Button、Label、Entry、Canvas创建

? ? ? ? (1)Frame:作为一种容器,可以把其他组件放在frame上。

import tkinter as tk #tk界面

master = tk.Tk()#新建tk根窗口
index_frame =tk.Frame(master)
index_frame.grid() #设置参数,可以调整大小,位置等

master.mainloop()  #窗口消息循环

????????(2)Toplevel:作为顶级窗口,在原有窗口上弹出的窗口,一般可用于信息确认,密码验证等等

import tkinter as tk #tk界面

check_frame = tk.Toplevel() #新建顶级窗口
#布局
check_frame.title("验证管理员权限")
check_frame.geometry("300x200+580+300")

? ? ? ? (3)Button:按钮控件,不过tk的按钮太丑了,可以引入ttk,好看一点。button的第一个参数是放在的容器,command是绑定按钮处理函数

from tkinter import ttk #tk子部件,更加美观
import tkinter as tk #tk界面

master = tk.Tk()#新建tk根窗口
login_frame = tk.Frame(master)#新建frame
login_frame.grid() #展示frame

def cert():
    #弹出顶级窗口
    check_frame = tk.Toplevel() #新建顶级窗口
    check_frame.title("登录验证")
    check_frame.geometry("300x200+580+300")
    print("登录处理")

button1 = ttk.Button(login_frame, text = '立即登录',width = 28,command = cert)
button1.pack()

master.mainloop()

? ? ? ? (4)??Label及Entry:标签和输入框,标签可以放文字,也可以放图片,输入框获取输入。

给出登录界面代码

import tkinter as tk
import  tkinter.messagebox
import  pickle
from PIL import Image, ImageTk

window = tk.Tk()
window.title('login')
window.geometry('300x200')

# 登陆界面
tk.Label(window, text='账户:').place(x=50,y=60) #标签
tk.Label(window, text='密码:').place(x=50, y=100)

var_usr_name = tk.StringVar() #定义字符串输入变量
enter_usr_name = tk.Entry(window, textvariable=var_usr_name).place(x=100, y=60) #输入框

var_usr_pwd = tk.StringVar()
enter_usr_pwd = tk.Entry(window, textvariable=var_usr_pwd, show='*').place(x=100, y=100)

#登陆
def usr_login():
    #输入框内容
    usr_name = var_usr_name.get()
    usr_pwd = var_usr_pwd.get()
    print("用户名:",usr_name)
    print("密码:",usr_pwd)

#退出
def usr_quit():
    window.destroy()

#登录 退出按钮
bt_login = tk.Button(window,text='登录',command=usr_login).place(x=100,y=130)

bt_logquit = tk.Button(window,text='退出',command=usr_quit).place(x=160,y=130)

window.mainloop()

? ? ? ? (5)Canvas:画布,一般用来放图片或者视频,视频就是一帧帧刷新进行显示。【进入学习Canvas】

import tkinter as tk #tk界面

master = tk.Tk()#新建tk根窗口
index_frame =tk.Frame(master)
index_frame.grid() #设置参数,可以调整大小,位置等

#新建画布
canvas = tk.Canvas(index_frame,height = 463, width = 895)
canvas.pack(side = 'top')

master.mainloop()  #窗口消息循环

? ? ? ? 4、tk界面插入背景图片

import tkinter as tk #tk界面

master = tk.Tk()#新建tk根窗口
index_frame =tk.Frame(master)
index_frame.grid() #设置参数,可以调整大小,位置等

#新建画布
canvas = tk.Canvas(index_frame,height = 463, width = 895)
canvas.pack(side = 'top')

#创建画布背景图
global photo #设置全局变量,解决图片不显示的问题
photo = tk.PhotoImage(file = 'bg_img.gif') #gif图片的路径,不支持jpg,png
canvas.create_image(449, 233, image=photo)#前面为偏移参数

master.mainloop()  #窗口消息循环

若遇到问题,可参考Python tkinter之PhotoImage图片显示问题

? ? ? ? 5、动态更新人脸识别结果

? ? ? ? 用label显示人脸识别结果,才用循环创建label覆盖,即可实现动态显示,直接点击右上角关闭会报错,需要处理

import tkinter as tk
import time

index=tk.Tk()
index.wm_title("测试")
index.geometry('500x300+450+200')

var = tk.StringVar()  #设置string类型的变量
var.set("0")        #设置初始值
tk.Label(index, text= "动态显示" , font = ("微软雅黑",24)).grid(row=1,column=0)

while(True):
    var.set(chr(ord(var.get())+ 1))#设置显示的内容,如人脸识别返回的结果
    tk.Label(index, text= var.get() , font = ("微软雅黑",24)).grid(row=1,column=1) #每次显示的位置要一致,覆盖效果
    time.sleep(1)
    index.update()  #不断更新
index.mainloop() 

? ? ? ? 6、在画布Canvas实时显示视频流

? ? ? ? 跟上面动态显示结果类似,也是采用循环1帧帧更新摄像头获取的图像,实现动态显示视频,直接点击右上角关闭会报错,需要处理

import tkinter as tk
from PIL import Image, ImageTk#图像控件
import cv2

cap = cv2.VideoCapture(0)#创建摄像头对象

top = tk.Tk()
top.title('人脸识别门禁系统')
top.geometry('580x600+450+100')

#绘制视频画布
canvas = tk.Canvas(top,bg = 'white',width = 580,height = 600 )
canvas.pack()

#图像预处理
def tkImage():
    ref,frame=cap.read()
    frame = cv2.flip(frame, 1) #摄像头翻转
    cvimage = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
    pilImage=Image.fromarray(cvimage)
    pilImage = pilImage.resize((image_width, image_height),Image.ANTIALIAS)
    tkImage =  ImageTk.PhotoImage(image=pilImage)
    return tkImage

#动态显示
while True:
  pic = tkImage()
  canvas.create_image(0,0,anchor = 'nw',image = pic)
  top.update()

cap.release()
top.mainloop()  

? ? ? ? 7、日志

????????建立一个txt文件,记录下管理员的操作,以及人脸识别结果。

import time
import datetime

now_time = datetime.datetime.now()
str_time = now_time.strftime("%Y-%m-%d %X")# 格式化时间字符串

log = open("log.txt", "a",encoding='utf-8')#每次打开会接着往下写,若文件不存在则会自己创建
log = open("log.txt", "w",encoding='utf-8')#每次打开会清空日志内容,若文件不存在则会自己创建
log.write(str_time+"  "+"管理员重置人脸识别门禁系统日志!\n")

log.close()# 关闭打开的文件

三、说明

? ? ? ? 1、整合

? ? ? ? 结合前几期的内容,以及这期的主要内容,进行代码整合,即可实现tkinter界面的人脸识别门禁管理系统,在此基础上,可以继续添加管理员的注册管理,人脸信息登记,对视频流进行图像处理,加一些动态特效啥的,还可以对接数据库等等

? ? ? ? 2、tk界面动态显示的时候,直接右上角关闭界面会报错的问题

? ? ? ? 因为程序在循环里还在执行,直接关闭会摧毁窗口,但图像还在获取,会报Erro: Too early to create image的错误 。

解决方法:利用protocol("WM_DELETE_WINDOW",quit)#触发点击窗口关闭处理事件。捕获点击右上角关闭事件,然后在quit函数里进行处理,通知界面不要再获取图像了,常见方法就是在获取图像函数里设置信号量,之后该释放的资源释放,该摧毁的摧毁,该关闭的关闭

? ? ? ? 3、一些小点

? ? ? ? (1)密码输入框: tk.Entry(login_frame,show='*'),通过参数show='*',隐藏输入的内容

? ? ? ? (2)组件设置后,要设置place或者grid或者pack方法才会显示

? ? ? ? (3)为了弥补tk组件的美观,ttk可以设置style,类似css,具体参考官方文档

? ? ? ? (4)在画布上添加组件:canvas.create_window(210, 50, window=tk.Entry(login_frame, borderwidth=3)),实现在画布的背景图片上添加组件。

????????

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-02-05 21:53:26  更:2022-02-05 21:54:02 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 10:24:21-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码