前言
在現(xiàn)代信息化時(shí)代,圖形化用戶界面(Graphical User Interface, GUI)已經(jīng)成為各種軟件應(yīng)用和設(shè)備交互的主流方式,與傳統(tǒng)的命令行界面(CLI)相比,GUI 具有直觀性、易用性、交互性、可視化和多任務(wù)處理等優(yōu)勢(shì)。設(shè)計(jì)良好的用戶交互界面可以讓用戶以更加直觀、友好的方式與計(jì)算機(jī)系統(tǒng)進(jìn)行交互,提高用戶的滿意度和使用體驗(yàn)。本項(xiàng)目將設(shè)計(jì)一款實(shí)用人機(jī)交互界面,用戶通過(guò)界面的按鈕、文本框、圖表等能夠更加便捷地完成人臉采識(shí)別、語(yǔ)音交互下單等任務(wù)。
下面是界面演示視頻。
人工智能系統(tǒng)界面操作視頻
一、項(xiàng)目介紹
本項(xiàng)目利用Tkinter模塊搭建了一個(gè)人工智能系統(tǒng)界面,如圖1和圖2所示,用戶在界面按下按鈕或者輸入文本框內(nèi)容,可以與系統(tǒng)進(jìn)行數(shù)據(jù)交互,避免通過(guò)命令行等繁瑣的輸入方式來(lái)執(zhí)行程序。本項(xiàng)目設(shè)計(jì)的界面主要包含以下兩大功能。
1.人臉信息驗(yàn)證
界面的左邊欄目中用戶可進(jìn)行人臉采集、模型訓(xùn)練、人臉識(shí)別驗(yàn)證。
(1)人臉采集。用戶首先需要完成人臉采集,輸入“用戶ID”“用戶姓名”后,點(diǎn)擊“采集”按鈕,可以調(diào)取攝像頭,完成100張人臉圖像的采集。
(2)模型訓(xùn)練。用戶需要在“模型名稱”中輸入對(duì)應(yīng)人臉模型的名字,例如“l(fā)yx”,點(diǎn)擊“訓(xùn)練”按鈕后,系統(tǒng)會(huì)自動(dòng)生成一個(gè)命為“l(fā)yx.yml”的模型,并自動(dòng)保存到“FaceRecognition/Model”文件夾下。
(3)人臉識(shí)別。用戶完成人臉采集與模型訓(xùn)練之后,才能點(diǎn)擊“識(shí)別”按鈕,當(dāng)人臉識(shí)別成功后,系統(tǒng)會(huì)調(diào)取該用戶的人臉圖像顯示在系統(tǒng)界面上。
當(dāng)用戶按下界面中的“清除”“注銷”按鈕可以消除已有的信息。
2.訂單信息可視化
用戶可在界面右邊欄目中,通過(guò)按下“語(yǔ)音啟動(dòng)”按鈕,說(shuō)出“系統(tǒng)啟動(dòng)”來(lái)開(kāi)啟后續(xù)操作。系統(tǒng)啟動(dòng)后,會(huì)通過(guò)語(yǔ)音合成提醒用戶完成人臉識(shí)別,只有用戶的身份信息核實(shí)通過(guò)后,用戶才能夠向3位攤主進(jìn)行下單任務(wù),下單時(shí)同樣需要用戶通過(guò)與系統(tǒng)進(jìn)行語(yǔ)音交互來(lái)完成。訂單完成后,界面顯示用戶向每位攤主下單的總數(shù),并通過(guò)扇形圖展示出來(lái)。點(diǎn)擊下方的“訂單詳情”,界面會(huì)切換到對(duì)每位攤主詳細(xì)的需求。
二、項(xiàng)目準(zhǔn)備
1.Tkinter模塊相關(guān)組件的知識(shí),可以詳看我前面寫過(guò)的文章
2.準(zhǔn)備一個(gè)TCP調(diào)試助手,用于TCP通信。如果沒(méi)有,可見(jiàn)文末附件。打開(kāi)TCP調(diào)試助手,設(shè)置為服務(wù)端,其IP地址為“127.0.0.1”,端口為“2005”,打開(kāi)開(kāi)關(guān)。
3.安裝好相關(guān)的庫(kù)文件,詳細(xì)見(jiàn)下圖,版本是3.75。
4.本項(xiàng)目中的程序人臉識(shí)別和語(yǔ)音功能是直接調(diào)用已經(jīng)寫好的人臉采集、訓(xùn)練、識(shí)別和語(yǔ)音識(shí)別、語(yǔ)音合成的函數(shù),可以見(jiàn)人臉識(shí)別和語(yǔ)音識(shí)別和語(yǔ)音合成這3篇文章,全部的程序都會(huì)放在本文末附錄。
三、項(xiàng)目實(shí)施
備注:界面設(shè)計(jì)的參考程序建議從后面的主程序往前看,找到對(duì)應(yīng)的功能函數(shù)。
1.導(dǎo)入相關(guān)庫(kù)文件
from tkinter import *
from tkinter import ttk
from PIL import Image, ImageTk
import time
import cv2
from playsound import playsound #播放聲音
from FaceCollect import GetFace #導(dǎo)入采集程序中的函數(shù)
import socket #連接服務(wù)器
from FaceTrain import getImagesAndLabels,recognizer #導(dǎo)入訓(xùn)練程序中的函數(shù)
import numpy as np
from FaceRecognition import Face #導(dǎo)入識(shí)別程序中的函數(shù)
from baiduasr import record, asr_updata #語(yǔ)音合成文件中的函數(shù)
import baiduasr #語(yǔ)音合成文件
from TTS import tts #語(yǔ)音合成文件
import threading #開(kāi)啟線程所用
import openpyxl #表格處理模塊
import matplotlib #繪圖
from matplotlib.figure import Figure
2.人臉信息驗(yàn)證功能
# 人臉圖片顯示函數(shù),所有的人臉圖片顯示的時(shí)候可以加載這個(gè)函數(shù)
def face_image(face_photo):
global photo1 # 一定要將photo設(shè)置成全局變量不然調(diào)用顯示不出來(lái) image
photo_open1 = Image.open('./' + face_photo + '.jpg') # 打開(kāi)圖片
photo1 = photo_open1.resize((100 , 120)) # 圖片尺寸
photo1 = ImageTk.PhotoImage(photo1)
Label(Frame1_3,image=photo1).place(x= 90,y = 10) # 放置人臉圖像的標(biāo)簽及位置
#清除函數(shù)
def clear(entry1,entry2):
print("文本清除")
entry1.delete(0,END) #清除文本框內(nèi)容,從第一個(gè)字符到最后一個(gè)字符
entry2.delete(0,END) #清除文本框內(nèi)容,從第一個(gè)字符到最后一個(gè)字符
# 人臉注銷函數(shù)。function:face_logout
def face_logout():
print("圖像注銷")
Label(Frame1_3,text = " " , bg = "#DAE3F3").place(x= 100,y = 150) # 用空格頂?shù)粼械男畔?
Label(Frame1_3,text = " " , bg = "#DAE3F3").place(x= 100,y = 200) # 用空格頂?shù)粼械男畔?
face_image('face')
# 采集函數(shù)。function:fece_collect
#利用get()方法獲取用戶輸入的姓名、ID,調(diào)用FaceCollect中的Getface函數(shù)完成圖像采集。
def register():
print("人臉采集")
Name = name.get()
ID = id.get() #獲取文本框內(nèi)容
GetFace(Name,ID) #采集人臉數(shù)據(jù)
# 人臉訓(xùn)練函數(shù)。function:fece_train
#利用get()方法獲取用戶輸入的模型名稱,調(diào)用FaceTrain中的函數(shù)完成人臉模型的訓(xùn)練,生成的模型文件保存到Model文件夾內(nèi),并以用戶輸入的模型名稱命名。
def Train():
print("人臉訓(xùn)練")
Moudle = moudle_name1.get() #獲取文本框內(nèi)容
faces, ids = getImagesAndLabels(path) #獲取訓(xùn)練程序中的人臉和標(biāo)簽
# 開(kāi)始訓(xùn)練
recognizer.train(faces, np.array(ids))
# 保存文件
recognizer.write(r'./Model/'+ Moudle +'.yml') #以用戶輸入的模型名稱給生成的模型命名
# 人臉識(shí)別函數(shù)
#完善“識(shí)別”按鈕函數(shù)。調(diào)用FaceRecognition中的Face函數(shù)來(lái)識(shí)別用戶身份,并將信息顯示在界面。
def face_recognition():
print("人臉識(shí)別")
Name,idnum,Confidence = Face() #調(diào)用人臉識(shí)別函數(shù)
print("您的名字是:", Name,"您的ID是:", idnum)
Label(Frame1_3,text=idnum,font=("黑體",15),width=4,bg = "#DAE3F3").place(x=110,y=150)#ID
Label(Frame1_3,text=Name ,font= ("黑體",15),width=4,bg = "#DAE3F3").place(x=110,y=200)#姓名
face_image('image') #設(shè)置界面的人臉圖像
這段程序即界面左邊人臉信息驗(yàn)證部分的功能。
3.語(yǔ)音交互與TCP數(shù)據(jù)通信
(1)創(chuàng)建socket客戶端變量,利用socket_client.send方法向TCP發(fā)送數(shù)據(jù),該客戶端變量是在最下面的主函數(shù)中定義的。
(2)執(zhí)行Start()函數(shù)時(shí),首先通過(guò)tts合成語(yǔ)音提示用戶進(jìn)行錄音,然后進(jìn)行語(yǔ)音識(shí)別,用戶說(shuō)出“系統(tǒng)啟動(dòng)后”,再進(jìn)行人臉識(shí)別,并給TCP客戶端發(fā)送匹配度指數(shù)和“start”指令。
# 向TCP服務(wù)端發(fā)送數(shù)據(jù)
def senddata(text):
socket_client.send(text.encode())
# 按下“語(yǔ)音啟動(dòng)”按鈕
def Start():
print("系統(tǒng)啟動(dòng)")
global face_flag
tts("開(kāi)始進(jìn)行語(yǔ)音識(shí)別")
while True:
msg = ''
baiduasr.record() # 錄音
data = baiduasr.asr_updata() # 語(yǔ)音識(shí)別
t = data.split(',') # 字符串分割
print(t)
for i in range(len(t)):
if '系統(tǒng)啟動(dòng)' in t[i]:
tts("開(kāi)始進(jìn)行人臉識(shí)別.") #語(yǔ)音合成
Name,idnum,Confidence = Face() #調(diào)用人臉識(shí)別函數(shù)
score = str("{0}".format(round(200 - Confidence))) #匹配度指數(shù)
tts("您的名字是:" + Name)
#顯示人臉圖像代碼
faceimg = cv2.imread('./image.jpg')
cv2.imshow('image',faceimg)
cv2.waitKey(3000)
cv2.destroyAllWindows() #摧毀窗口
msg = f'{score}'
senddata(msg) #發(fā)送發(fā)送匹配指數(shù)
tts("人臉識(shí)別通過(guò)")
face_image('image') #將用戶人臉?lè)旁诮缑嫔?/span>
face_flag = 1 # 人臉識(shí)別標(biāo)志置1
Label(Frame1_3,text = idnum ,font = ("黑體",15),width = 4 , bg = "#DAE3F3").place(x= 110,y = 150)#ID
Label(Frame1_3,text = Name ,font = ("黑體",15),width = 4 , bg = "#DAE3F3").place(x= 110,y = 200) #姓名
break
if face_flag == 1: #人臉驗(yàn)證通過(guò)后可以開(kāi)始執(zhí)行訂單指令
msg='start'
print(msg)
senddata(msg) #向TCP發(fā)送start
break #人臉識(shí)別通過(guò)后跳出循環(huán)
4.數(shù)據(jù)信息可視化
人工智能系統(tǒng)界面的訂單數(shù)據(jù)可視化功能,要求實(shí)現(xiàn)當(dāng)用戶通過(guò)語(yǔ)音完成下單后,在訂單分布界面能夠顯示用戶向每位攤主的需求總數(shù),按下“訂單詳情”按鈕,能夠切換到新的界面,顯示每位攤主的4類物料的需求數(shù)量。
(1)定義訂單數(shù)量函數(shù),用于后于語(yǔ)音識(shí)別中判斷用戶輸入的語(yǔ)音信息中的訂單數(shù)量。
def num(text):
if '一' in text:
return '1'
elif '兩' in text:
return '2'
elif '三' in text:
return '3'
elif '四' in text:
return '4'
elif '五' in text:
return '5'
else:
return '0'
(2)定義wait_order函數(shù),該函數(shù)在主函數(shù)中通過(guò)開(kāi)啟threading線程來(lái)啟動(dòng),用于等待接受TCP服務(wù)端發(fā)送過(guò)來(lái)“xiadingdan”指令,通過(guò)開(kāi)啟線程來(lái)持續(xù)等待,這樣才不會(huì)導(dǎo)致界面刷新不出來(lái)。初始化各個(gè)變量,等待接受TCP服務(wù)端發(fā)送過(guò)來(lái)“xiadingdan”的指令后,通過(guò)語(yǔ)音交互,讓用戶向三位攤主分別下單。
#人臉驗(yàn)證通過(guò)后,等待PLC發(fā)送過(guò)來(lái)'xiadingdan',用戶才能語(yǔ)音下單
def wait_order():
global face_flag
while 1:
if face_flag == 1: #只有人臉驗(yàn)證通過(guò)后,接收到的PLC下單指令才有用
while (True):
command = socket_client.recv(1024).decode()
print(command)
time.sleep(0.1)
dingdan_list = ["dingdan"] # 初始化訂單的值
order = '' # 初始化每個(gè)攤主的訂單
sum = 0 #攤主個(gè)數(shù)
No1 = 0
No2 = 0
No3 = 0
need_list = []
need_new = []
fraces = [] # 扇形圖的占比初始值
labels = [] # 扇形圖的標(biāo)簽初始值
colors = []
if command == 'xiadingdan':
for k in range(3):
tts("請(qǐng)為"+ str(k+1) +"號(hào)位攤主下單")
sum +=1 #攤主個(gè)數(shù)
tts("開(kāi)始錄音")
baiduasr.record() # 錄音
data = baiduasr.asr_updata() # 語(yǔ)音識(shí)別
t = data.split(',') # 字符串分割
print(t)
label1 = '0' # 每次給新的攤主下訂單需要初始化對(duì)應(yīng)變量
label2 = '0'
label3 = '0'
label4 = '0'
for i in range(len(t)):
if '水果' in t[i]:
label1 = num(t[i])
order = f'{label1},{label2},{label3},{label4}' # 輸出
elif '蔬菜' in t[i]:
label2 = num(t[i])
order = f'{label1},{label2},{label3},{label4}' # 輸出
elif '服裝' in t[i]:
label3 = num(t[i])
order = f'{label1},{label2},{label3},{label4}' # 輸出
elif '零食' in t[i]:
label4 = num(t[i])
order = f'{label1},{label2},{label3},{label4}' # 輸出
else:
order = '0,0,0,0' #如果沒(méi)有上述物品或者輸入錯(cuò)誤,則全部置零
dingdan_list.append(order) # 把每一個(gè)向攤主下的單組合到列表dingdan_list
(3)把用戶的向每一位攤主下的訂單信息order,填寫到表格中。然后將用戶輸入訂單信息轉(zhuǎn)為列表dingdan_list,獲取每一位攤主的訂單需求量。例如dingdan_list=[dingdan,[1,0,0,0],[1,1,1,0],[1,1,1,1]],那么No1=1,No2=3,No1=4。設(shè)置繪制扇形圖需要的各個(gè)變量,這里調(diào)用draw_pie函數(shù),其參數(shù)frame,colors,fraces,為列表類型,labels為元組類型。
# 填寫相關(guān)信息到表格
max_row1 = sheet1.max_row # 獲取該表格最大行行數(shù)
#將表格中的內(nèi)容為order的值, order為字符串 '0,0,0,0' ,字符長(zhǎng)度是6
sheet1.cell(max_row1+1,1).value = str(sum) # 填寫到“序號(hào)”一欄
sheet1.cell(max_row1+1,2).value = str(sum) + "號(hào)" # 填寫到“攤主”一欄
sheet1.cell(max_row1+1,3).value = order[0] # 填寫到“水果”一欄
sheet1.cell(max_row1+1,4).value = order[2] # 填寫到“蔬菜”一欄
sheet1.cell(max_row1+1,5).value = order[4] # 填寫到“零食”一欄
sheet1.cell(max_row1+1,6).value = order[6] # 填寫到“服裝”一欄
sheets.save("Data.xlsx") # 保存表格
#將每個(gè)攤位的元素相加,得到總數(shù)!
print(dingdan_list)
No1 = int(dingdan_list[1][0]) + int(dingdan_list[1][2]) + int(dingdan_list[1][4]) + int(dingdan_list[1][6]) #1號(hào)攤主需求量
No2 = int(dingdan_list[2][0]) + int(dingdan_list[2][2]) + int(dingdan_list[2][4]) + int(dingdan_list[2][6]) #2號(hào)攤主需求量
No3 = int(dingdan_list[3][0]) + int(dingdan_list[3][2]) + int(dingdan_list[3][4]) + int(dingdan_list[3][6]) #3號(hào)攤主需求量
#print("No1,No2,No3:",No1,No2,No3)
#將各個(gè)攤主及其需求量和扇形圖對(duì)應(yīng)顏色組合到列表
need_list = [["1號(hào)",No1, "#63A0DB"], ["2號(hào)",No2 , "#FFC727"] , ["3號(hào)" , No3 , "#20EA37" ] ]
#以下操作是為了剔除占比為需求量為0的那部分,需求量為0則不顯示在扇形圖上
for k in need_list:
if k[1]== 0: #提取列表索引為0的值
continue #不做處理
else:
need_new.append(k) #把值不為0的部分拼接起來(lái),例如[["1號(hào)攤主",No1, "#63A0DB"],["2號(hào)",No2 , "#FFC727"] ]
for k in need_new: #遍歷列表,獲得每一個(gè)扇形函數(shù)的參數(shù),labels參數(shù)是標(biāo)簽,fraces是扇形的占比,colors對(duì)應(yīng)的顏色
labels.append(k[0]) # 獲取攤主對(duì)應(yīng)的列表
fraces.append(k[1]) # 獲取需求量對(duì)應(yīng)占比的列表
colors.append(k[2]) # 獲取攤主對(duì)應(yīng)顏色的列表
labels = tuple(labels) # 轉(zhuǎn)為元組,獲取攤主對(duì)應(yīng)標(biāo)簽 labels = ("1號(hào)","2號(hào)","3號(hào)")
#print(labels,fraces,colors)
draw_pie(Frame2_1,labels,fraces,colors) # 畫(huà)扇形圖
pie_image() # 扇形圖顯示函數(shù)
Label(Frame2_1,text = str(No1)+ "個(gè)", font = ("微軟雅黑",12), bg = "#63A0DB" , width = 4 , height = 2 , anchor = 'w').place(x= 160,y = 150)
Label(Frame2_1,text = str(No2)+ "個(gè)", font = ("微軟雅黑",12), bg = "#FFC727" , width = 4 , height = 2 , anchor = 'w').place(x= 160,y = 250)
Label(Frame2_1,text = str(No3)+ "個(gè)", font = ("微軟雅黑",12), bg = "#20EA37" , width = 4 , height = 2 , anchor = 'w').place(x= 160,y = 350)
#循環(huán)3次后發(fā)送最終訂單 例如[dingdan,1,0,0,0,0,1,0,0,0,0,1,0]
msg = ",".join(dingdan_list) # 列表轉(zhuǎn)字符串 "dingdan,1,0,0,0,0,1,0,0,0,0,1,0"3
senddata(msg) #發(fā)送最終訂單
face_flag = 0 #標(biāo)志位置0
(4)定義扇形圖形式函數(shù)。該函數(shù)用于將生成的扇形圖片展示在Frame框架上。
# 扇形圖顯示函數(shù),所有的扇形圖圖片顯示的時(shí)候可以加載這個(gè)函數(shù)
def pie_image():
global photo3 # 一定要將photo設(shè)置成全局變量不然調(diào)用顯示不出來(lái)
# 初始化的圖片使用PIL庫(kù)來(lái)加載圖像
photo_open3 = Image.open('./pie.png') # 打開(kāi)扇形圖片
photo3 = photo_open3.resize((350 , 350)) # 圖片尺寸
photo3 = ImageTk.PhotoImage(photo3)
Label(Frame2_1,image=photo3).place(x= 220,y = 100) # 放置圖像
(5)定義draw_pie函數(shù),利用matplotlib模塊畫(huà)扇形圖,最后將生成的扇形圖片通過(guò)savefig()方法保存到與GUI_3.py同目錄下,并命名為“pie.png”
# matplotlib模塊畫(huà)扇形圖
def draw_pie(frame,labels,fraces , colors):
# Figure創(chuàng)建圖像對(duì)象,figsize指定畫(huà)布的大小,(寬度,高度),單位為英寸。
# dpi 指定繪圖對(duì)象的分辨率,即每英寸多少個(gè)像素,默認(rèn)值為80
fig = Figure(figsize=(4, 4), dpi=100)
# subplot()均等劃分畫(huà)布,如果不想覆蓋之前的圖,需要使用 add_subplot() 函數(shù)
drawPic_a = fig.add_subplot(111)
# 解決漢字亂碼問(wèn)題,使用指定的漢字字體類型(此處為黑體)
matplotlib.rcParams['font.sans-serif'] = ['SimHei']
# 繪制pie()餅狀圖:labels為每個(gè)扇形區(qū)域備注一個(gè)標(biāo)簽名字,autopct格式化字符串"fmt%pct",百分比格式
drawPic_a.pie(x=fraces, labels=labels, colors = colors , autopct='%0.2f%%')
drawPic_a.set_title('訂單分布圖') #餅狀圖命名
fig.savefig('pie.png') # 將扇形圖保存到文件夾下
(6)定義訂單詳情畫(huà)面,使用Treeview來(lái)呈現(xiàn)表格內(nèi)容。用戶按下初始界面的“訂單詳情”按鈕后,能夠切換到另外一個(gè)框架(Frame4)的組成畫(huà)面,該畫(huà)面放置TreeView組件,是一個(gè)樹(shù)狀結(jié)構(gòu)和表格的結(jié)合體。第一列是樹(shù)狀結(jié)構(gòu),后幾列是列表。創(chuàng)建表格對(duì)象tree,第一列為序號(hào),后面幾列分別為“攤位”“水果”“蔬菜”“服裝”“零食”。用戶下單后會(huì)將訂單信息保存到“Data.xlsx”表格中,在data_monitorh函數(shù)中調(diào)用“Data.xlsx”工作表的內(nèi)容,遍歷每一行(每一位攤主),獲取每一行中各列(4大類物料)的數(shù)量,然后通過(guò)使用Treeview來(lái)呈現(xiàn)表格內(nèi)容數(shù)據(jù)。
#訂單詳情畫(huà)面,使用Treeview來(lái)呈現(xiàn)表格內(nèi)容
def data_monitor():
print("訂單詳情")
Frame2_1.pack_forget() # 隱藏Frame3的組件,pack_forget()方法讓控件“不再顯示”但控件還存在可以再次pack出來(lái)
Frame4 = Frame(Frame2,bg="White",height=500,width=600)
Frame4.place(x = 50 , y = 100)
Button(Frame4,text = "返回統(tǒng)計(jì)圖",bg = "#C1FFC1",font = ("黑體",15),width = 12,height=2, command = Frame4.place_forget).place(x=450,y=430) #返回統(tǒng)計(jì)按鈕
# 表格。建立標(biāo)題
tree = ttk.Treeview(Frame4) # 創(chuàng)建表格對(duì)象
tree["columns"] = ("序號(hào)","攤位","水果","蔬菜","服裝","零食") # 定義列
tree.column("序號(hào)" , width = 60 ) # 寬度
tree.column("攤位" , width = 60 )
tree.column("水果" , width = 60 )
tree.column("蔬菜" , width = 60 )
tree.column("服裝" , width = 60 )
tree.column("零食" , width = 60 )
tree.heading("#0" , text = "序號(hào)") # 表格標(biāo)題
tree.heading("#1" , text = "攤位")
tree.heading("#2" , text = "水果")
tree.heading("#3" , text = "蔬菜")
tree.heading("#4" , text = "服裝")
tree.heading("#5" , text = "零食")
tree.place(x=20,y=50)
max_row1 = sheet1.max_row # 獲取該表格最大行行數(shù)
max_column1 = sheet1.max_column # 獲取該表格最大列列數(shù)
for i in range(2,max_row1+1): # 從表格第2行開(kāi)始遍歷
b = [] # 設(shè)空列表
for j in range(1,max_column1+1): # 遍歷每一列,獲取每一行的列內(nèi)容
a = sheet1.cell(i,j).value # 獲取每一個(gè)單元格的值,
b.append(a) # 字符串轉(zhuǎn)列表
del(b[0]) # 刪除第一個(gè)序號(hào)
tree.insert("", index = END , text = i-1,values=b) # 加載到表格上,text是序號(hào),values是序號(hào)后的內(nèi)容
tree.place(x=20,y=50)
(7)主函數(shù)程序設(shè)計(jì)。增加人臉識(shí)別初始標(biāo)志,創(chuàng)建TCP客戶端。使用openpyxl.Workbook()創(chuàng)建工作薄,命名為“Data.xlsx”,然后加載打開(kāi)表格,在表格第一行的前6列寫入相關(guān)內(nèi)容。然后開(kāi)啟線程,用于接收發(fā)送過(guò)來(lái)PLC的指令,更新到界面。
if __name__ == '__main__':
# 創(chuàng)建全局變量
face_flag = 0 #人臉識(shí)別標(biāo)志
global command
# 創(chuàng)建socket客戶端變量
socket_client = ''
socket_client = socket.socket()
socket_client.connect(('127.0.0.1',2005))
# 創(chuàng)建一個(gè)新表格,用于存儲(chǔ)人員信息,每次打開(kāi)都覆蓋原來(lái)的表格
workbook = openpyxl.Workbook() # 創(chuàng)建一個(gè)工作薄
worksheet = workbook.active # 在工作薄中創(chuàng)建一個(gè)工作表
workbook.save("Data.xlsx") # 保存表格到對(duì)應(yīng)路徑
# 打開(kāi)工作表
sheets = openpyxl.load_workbook("Data.xlsx")
# 在表格第一行填寫內(nèi)容
sheet1 = sheets[sheets.sheetnames[0]]
sheet1.cell(1, 1).value = "序號(hào)"
sheet1.cell(1, 2).value = "攤位"
sheet1.cell(1, 3).value = "水果"
sheet1.cell(1, 4).value = "蔬菜"
sheet1.cell(1, 5).value = "服裝"
sheet1.cell(1, 6).value = "零食"
sheets.save("Data.xlsx") # 保存表格
# 開(kāi)啟線程,用于接收發(fā)送過(guò)來(lái)PLC的指令,更新到界面
thread = threading.Thread(target=wait_order) #定義wait_order函數(shù),等待接受
thread.daemon = True
thread.start()
(8)主程序界面設(shè)計(jì)。創(chuàng)建窗口,設(shè)置窗口的相關(guān)屬性。
# 人臉訓(xùn)練集路徑
path = './Facedata/'
#主界面程序
top = Tk()
top.title("越疆科技")
top.geometry("1200x700")
top.configure(bg = "#F8CBAD") # 窗口背景顏色
# 大標(biāo)題
Label(top ,text = "人工智能機(jī)器人系統(tǒng)集成及應(yīng)用平臺(tái)",font = ("宋體",18),fg = "black",bg = "#F8CBAD",width = 35,height = 2).place(x=440,y = 0)
(9)界面放置人臉信息驗(yàn)證的框架Frame1,在Frame1布置3個(gè)小框架,分別用于放置人臉采集、訓(xùn)練、識(shí)別的按鈕或文本框等組件。各個(gè)框架中的按鈕通過(guò)參數(shù)command綁定對(duì)應(yīng)的執(zhí)行函數(shù)。
#在第一個(gè)框架再里面放置3個(gè)框架Frame1_1、Frame1_2、Frame1_3,用于人臉采集、訓(xùn)練、識(shí)別
#在第一個(gè)框架再里面放置第1個(gè)框架
Frame1_1 = Frame(Frame1,bg="#DAE3F3",height=150,width=300)
Frame1_1.place(x = 25 , y = 25)
#利用StringVar接收用戶ID輸入
var_ID = StringVar()
id = Entry(Frame1_1,textvariable=var_ID, font=('黑體', 13) , width=15) #輸入框
id.place(x=100,y=25)
Label(Frame1_1 ,text = "用戶ID",font = ("黑體",13),bg = "#DAE3F3", width = 8 ).place(x=20,y=25)
#利用StringVar接收用戶姓名輸入
var_name = StringVar()
name = Entry(Frame1_1,textvariable=var_name, font=('黑體', 13) , width=15) #輸入框
name.place(x=100,y=75)
Label(Frame1_1 ,text = "用戶姓名",font = ("黑體",13),bg = "#DAE3F3", width = 8 ).place(x=20,y=75)
#采集、清除按鈕
Button(Frame1_1,text = "采集",bg = "#836FFF",font = ("黑體",13),width = 10,command = register).place(x=35,y=110)
Button(Frame1_1,text = "清除",bg = "#836FFF",font = ("黑體",13),width = 10,command = lambda : clear(id,name)).place(x=165,y=110)
#在第一個(gè)框架再里面放置第2個(gè)框架
Frame1_2 = Frame(Frame1,bg="#DAE3F3",height=100,width=300)
Frame1_2.place(x = 25 , y = 200)
#利用StringVar接收用戶輸入的模型名稱
var_moudle1 = StringVar()
moudle_name1 = Entry(Frame1_2,textvariable=var_moudle1, font=('黑體', 13) , width=15) #輸入框
moudle_name1.place(x=100,y=15)
Label(Frame1_2 ,text = "模型名稱",font = ("黑體",13),bg = "#DAE3F3", width = 8 ).place(x=20,y=15)
#訓(xùn)練、清除按鈕
Button(Frame1_2,text = "訓(xùn)練",bg = "#836FFF",font = ("黑體",13),width = 10,command = Train).place(x=35,y=60)
Button(Frame1_2,text = "清除",bg = "#836FFF",font = ("黑體",13),width = 10,command = lambda : moudle_name1.delete(0,END)).place(x=165,y=60)
#在第一個(gè)框架再里面放置第3個(gè)框架
Frame1_3 = Frame(Frame1,bg="#DAE3F3",height=275,width=300)
Frame1_3.place(x = 25 , y = 325)
#繪制畫(huà)布,用于顯示信息畫(huà)布背景為白色
face_image('face') # 初始化人臉圖像
#識(shí)別用戶姓名
Label(Frame1_3 ,text = "用戶ID:",font = ("黑體",13),bg = "#DAE3F3", width = 9 ).place(x=20,y=150)
Label(Frame1_3 ,text = "用戶姓名:",font = ("黑體",13),bg = "#DAE3F3", width = 9 ).place(x=20,y=200)
#識(shí)別、清除按鈕
Button(Frame1_3,text = "識(shí)別",bg = "#836FFF",font = ("黑體",13),width = 10,command = face_recognition).place(x=35,y=235)
Button(Frame1_3,text = "注銷",bg = "#836FFF",font = ("黑體",13),width = 10,command = face_logout).place(x=165,y=235)
(10)界面放置訂單詳情框架Frame2。放置“語(yǔ)音啟動(dòng)”“退出系統(tǒng)”按鈕,放置攤主詳情的Lable文字組件。
# 第二個(gè)框架:訂單信息部分
Frame2 = Frame(top,bg="#B4C7E7",height=625,width=700)
Frame2.place(x = 450 , y = 50)
#系統(tǒng)啟動(dòng)\訂單詳情按鈕
Button(Frame2,text = "語(yǔ)音啟動(dòng)",bg = "#C1FFC1",font = ("黑體",15),width = 12,height=2,command = Start).place(x=150,y=20)
Button(Frame2,text = "退出系統(tǒng)",bg = "#C1FFC1",font = ("黑體",15),width = 12,height=2,command = top.destroy).place(x=400,y=20)
#在Frame2框架再里面放置1個(gè)框架
Frame2_1 = Frame(Frame2,bg="white",height=500,width=600)
Frame2_1.place(x = 50 , y = 100)
Label(Frame2_1,text = "訂單分布圖 ", font = ("微軟雅黑",15), bg = "white" , width = 18 , height = 2 ).place(x= 200,y = 10)
Label(Frame2_1,text = "1號(hào)攤位需求量: ", font = ("微軟雅黑",12), bg = "#63A0DB" , width = 15 , height = 2 ).place(x= 20,y = 150)
Label(Frame2_1,text = "2號(hào)攤位需求量: " , font = ("微軟雅黑",12), bg = "#FFC727" , width = 15 , height = 2 ).place(x= 20,y = 250)
Label(Frame2_1,text = "3號(hào)攤位需求量: " , font = ("微軟雅黑",12), bg = "#20EA37" , width = 15 , height = 2 ).place(x= 20,y = 350)
Button(Frame2_1,text = "訂單詳情",bg = "#C1FFC1",font = ("黑體",15),width = 12,height=2, command = data_monitor).place(x=30,y=430) #返回統(tǒng)計(jì)按鈕
top.mainloop() #消息循環(huán)
五、運(yùn)行效果
(1)人臉信息驗(yàn)證
依次在界面左邊欄目中按照人臉采集、模型訓(xùn)練、人臉識(shí)別的順序來(lái)完成人臉信息驗(yàn)證,如下圖所示。
(2)語(yǔ)音交互
點(diǎn)擊“語(yǔ)音啟動(dòng)”按鈕,系統(tǒng)通過(guò)語(yǔ)音合成“開(kāi)始進(jìn)行語(yǔ)音識(shí)別”,通過(guò)麥克風(fēng)說(shuō)出“系統(tǒng)啟動(dòng)”,然后系統(tǒng)提示“開(kāi)始進(jìn)行人臉識(shí)別”,人臉驗(yàn)證通過(guò)后,可以在界面看到拍攝的人臉圖像和對(duì)用的ID、姓名。同時(shí),TCP服務(wù)端接受到發(fā)送的匹配指數(shù)和“start”指令。利用TCP客戶端發(fā)送“xiadingdan”指令,如所示。系統(tǒng)提示分別向3位攤主下訂單,例如向1號(hào)攤主下單“我要一個(gè)水果”,向2號(hào)攤主下單“我要一份蔬菜,一個(gè)服裝。”,向3號(hào)攤主下單“我要一個(gè)零食”,下單完成后,生成訂單列表[‘dingdan’, ‘1,0,0,0’, ‘1,1,1,0’, ‘1,1,1,1’],將發(fā)送給TCP服務(wù)端。同時(shí),界面將展示訂單分布的扇形圖。點(diǎn)擊“訂單詳情”按鈕??梢钥吹接脩粝蛎课粩傊鞯木唧w訂單列表。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-794477.html
四、相關(guān)附件
本項(xiàng)目相關(guān)程序及TCP調(diào)試助手、第三方python庫(kù)詳見(jiàn)這戳我~
提取碼:lyx4文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-794477.html
到了這里,關(guān)于人工智能交互系統(tǒng)界面設(shè)計(jì)(Tkinter界面設(shè)計(jì))的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!