Python 蹲的門面
Line:ted2016.kpvs
Email:Lct4246@gmail.com
FB:http://gg.gg/TedLeeFB/
Email:Lct4246@gmail.com
FB:http://gg.gg/TedLeeFB/
Blog:http://gg.gg/TedLeeBlog/
Jan. 15, 2023
在筆者的先前拙著《用變數傾印法玩 Python 蹲》(https://reurl.cc/LXk1qx)一文中,我們成功地在陳會安老師研發的 fChart 中的 Thonny IDE 測試了深蹲偵測及計次範例。本文將進一步地甞試以 fChart 內建的 Tinker 套件 [2] 為之再加上一套使用者介面(user interface,UI)來梳妝打扮一番。
新增功能
在本文中,我們將為《用變數傾印法玩 Python 蹲》範例擴充下列兩個新功能:
- 改用攝影機即時取得的影像(而非事先預錄的影片)。
- 增設深蹲達標關卡(為了便於測試,暫訂為深蹲三下)。
UI 佈局(layout)
在圖 1 上方,我們設計了一個 3×2 大小的畫面,第一行顯示專案名稱(Python 蹲)與版次(V1.0),第二行顯示由攝影機取得的即時影像與相關訊息,第三行為留白及作者姓名(Ted Lee)。圖 1 下方為 Tinker 刻出來的畫面。
在圖 2 中,我們先建立最外層的視窗 window 元件(component),再置入 frmTitle、frmVideo 和 frmTeam 三個框架元件(Frame)。緊接著,在 frmTitle 中擺放 lblTitle 和 lblVersion、在 frmVideo 中擺放 lblVideo 和 lblResult、在 frmTeam 中擺放 lblSpace 和 lblTeam。所有元件皆以 pack 佈局方式安排。詳如如圖 2 所示。
程式邏輯
我們將程式執行的流程畫成圖 3 的流程圖。此外,程式採模組化程式設計(modularized programming)的方法,將獨立的功能以下列三個副程式來達成:
import cv2
import numpy as np
from PIL import ImageFont, ImageDraw, Image
from tkinter import *
from PIL import Image, ImageTk
from PoseModule import PoseDetector
dir = 0
count = 0
def updateUI():
global img, lblVideo
cv2image = cv2.cvtColor(img, cv2.COLOR_BGR2RGBA)
img = Image.fromarray(cv2image)
imgtk = ImageTk.PhotoImage(image = img)
lblVideo.imgtk = imgtk
lblVideo.config(image = imgtk)
lblVideo.after(100, detectPose)
if count > 3:
lblResult.config(text = '你已達標!')
def detectPose():
global cap, detector, dir, count, img
success, img = cap.read()
if success:
img = cv2.resize(img, (640, 480))
h, w, c = img.shape
pose, img = detector.findPose(img, draw=True)
if pose:
lmList = pose["lmList"]
angle, img = detector.findAngle(lmList[24], lmList[26], lmList[28], img)
bar = np.interp(angle, (85, 180), (w//2-100, w//2+100))
cv2.rectangle(img, (w//2-100, 50), (int(bar), 100), (0, 255, 0), cv2.FILLED)
if angle <= 150:
if dir == 0:
count = count + 0.5
dir = 1
if angle >= 170:
if dir == 1:
count = count + 0.5
dir = 0
msg = str(int(count))
cv2.putText(img, msg, (100, 150), cv2.FONT_HERSHEY_SIMPLEX, 5, (255, 255, 255), 20)
cv2.imshow("Pose", img)
updateUI()
def cleanUp():
window.destroy()
cap.release()
cv2.destroyAllWindows()
cap = cv2.VideoCapture(0) #####開啟攝影機
detector = PoseDetector()
#開 UI ---------------------------------------------------------------------------------------------------------
#widow
window = Tk()
window.title('Python 蹲')
#window.geometry('1024x768')
window.attributes('-fullscreen', True)
#frame
frmTitle = Frame(window)
frmTitle.pack(side = TOP, fill = BOTH, expand = YES)
frmVideo = Frame(window)
frmVideo.pack(side = TOP, fill = BOTH, expand = YES)
frmTeam = Frame(window)
frmTeam.pack(side = BOTTOM, fill = BOTH, expand = YES)
#Title
lblTitle = Label(frmTitle, text = "Python 蹲", fg = '#005E5E', bg = '#666666', font = ('標楷體', 70), borderwidth = 0, highlightthickness = 0, relief = "sunken")
lblTitle.pack(side = LEFT, fill = BOTH, expand = YES)
lblVersion = Label(frmTitle, text = "V1.0", fg = '#005E5E', bg = '#666666', font = ('標楷體', 20), borderwidth = 0, highlightthickness = 0, relief = "sunken")
lblVersion.pack(side = RIGHT, fill = BOTH, expand = YES)
#Video
lblVideo = Label(frmVideo, bg = '#005E5E', borderwidth = 0, highlightthickness = 0, relief = "ridge")
lblVideo.pack(side = LEFT, fill = BOTH, expand = YES)
lblResult = Label(frmVideo, text = "", fg = 'white', bg = '#005E5E', font = ('標楷體', 40), borderwidth = 0, highlightthickness = 0, relief = "sunken")
lblResult.pack(side = RIGHT, fill = BOTH, expand = YES)
#Team
lblSpace = Label(frmTeam, text = "", fg = '#005E5E', bg = '#666666', font = ('標楷體', 20), borderwidth = 0, highlightthickness = 0, relief = "sunken")
lblSpace.pack(side = LEFT, fill = BOTH, expand = YES)
lblTeam = Label(frmTeam, text = "Ted Lee", fg = '#005E5E', bg = '#666666', font = ('標楷體', 20), borderwidth = 0, highlightthickness = 0, relief = "sunken")
lblTeam.pack(side = RIGHT, fill = BOTH, expand = YES)
#姿勢識別 ---------------------------------------------------------------------------------------------------
detectPose()
window.bind('<Escape>', lambda e: cleanUp())
mainloop()
進階問題
- 建置一「分數雲端排行榜」來記錄玩家的深蹲分數。
- 修改程式,使得深蹲次數達標後出現是否「重新訓練」詢問。
[1] 六種授權條款。
[2] 請參考拙著《AI 成績查詢系統》(https://reurl.cc/aaWlKl)一文。
沒有留言:
張貼留言