牟奕炫
在上期的基礎篇中, 我們借助MediaPipe 實現(xiàn)了對十個數(shù)的手勢識別(Windows 環(huán)境)。在此基礎之上我們借助樹莓派實現(xiàn)一個簡易的“猜拳”游戲:用戶和樹莓派都隨機出“剪子包袱錘”(與數(shù)字2、5、0 的手勢一致)中的一種,由程序來判定輸贏(輸出文字信息),同時樹莓派也用不同顏色的LED 燈提示(也可以另外添加蜂鳴器或OLED 顯示屏)。
實驗硬件包括樹莓派3B+ 主板一塊,古德微擴展板一塊,攝像頭一個,紅色、綠色和黃色LED 燈各一支。將綠色和黃色LED 燈按照“長腿正、短腿負”的原則,分別插入擴展板的6 號和12 號引腳處即可。
接下來,給樹莓派通電啟動操作系統(tǒng),通過Windows 的遠程桌面連接進入Thonny 編輯器,開始Python 代碼的編寫。
將之前的“[01]Recognize_Number.py” 復制粘貼, 重命名為“[02]Finger_Game.py”。在庫模塊的導入部分,需要添加語句:“import random”、“import time”和“from gpiozero importLED”; 刪除計算矢量角度的finger_angle(point1,point2) 函數(shù), 因為不再需要識別數(shù)字9(彎曲的食指);再來精簡finger_sign(tip_finger,list_data) 函數(shù)代碼:
只保留2、5 和0 三個數(shù)字的相關代碼,刪除其他7 個數(shù)字的手勢識別代碼,并將對應的變量finger_sign 分別賦值為“剪子”、“包袱”和“錘”,也就是將手勢識別結果進行重定義:當檢測到食指指尖和中指指尖同時在“凸包”區(qū)域外時,則認定該手勢為“剪刀”;當檢測到五個指尖均在“凸包”區(qū)域外時,則認定該手勢為“包袱”;當在“凸包”區(qū)域外沒有檢測到有任何手指指尖時,則認定該手勢為“錘”。
在main() 主程序的初始化部分,需要添加對三支LED 燈的引腳定義語句:“Red_LED = LED(5)”、“Green_LED = LED(6)” 和“Yellow_LED =LED(12)”。
在程序的手勢識別后半部分,新建變量your_finger 并賦值為“finger_sign(tip_finger,list_data)”,作用是“接收”通過函數(shù)調(diào)用返回后的手勢識別結果;建立三種手勢名稱的變量guess_list,賦值為“[" 剪刀"," 包袱"," 錘"]”;再建立樹莓派隨機手勢變量raspi,賦值為“random.choice(guess_list)”,通過調(diào)用random庫中的choice() 函數(shù)從guess_list 列表中隨機“抽取”一種手勢;建立變量win_list,賦值為“[[" 剪刀"," 包袱"],[" 包袱","錘"],[" 錘"," 剪刀"]]”(列表中嵌套列表數(shù)據(jù)),作用是列舉出三種“勝局”所對應的對弈情況:“剪刀”勝“包袱”、“包袱”勝“錘”、“錘”勝“剪刀”。
接下來, 建立“if your_finger:” 選擇結構(當有手勢識別信息返回時),先分別打印輸出用戶和樹莓派各自的手勢:“print(" 您出的是:",your_finger)”、“print(" 樹莓派出的是:",raspi)”;然后對二者進行判斷——如果相同(“if your_finger==raspi:”),則輸出提示信息“這是一場平局咯!”,并且控制黃色LED發(fā)光(“Yellow_LED.on()”); 如果二者所組合的列表是變量win_list 所存儲的任意一種“勝局”數(shù)據(jù)(“elif [your_finger,raspi] in win_list:”), 則輸出提示信息“祝賀——您贏,樹莓派輸啦!”,并且控制綠色LED 燈發(fā)光(“Green_LED.on()”);如果不是以上兩種情況(else分支),則輸出提示信息“sorry——樹莓派贏,您輸啦!”,并且控制紅色LED 燈發(fā)光(“Red_LED.on()”)。
添加時間延遲語句“time.sleep(3)”, 作用是確保LED 燈每次發(fā)光要持續(xù)3 秒鐘;然后,在進入下一輪游戲之前關閉LED 燈:“Yellow_LED.off()”、“Green_LED.off()” 和“Red_LED.off()”。
保存并運行程序,分別在攝像頭前多次嘗試剪刀、包袱和錘的隨機手勢,樹莓派同樣也會隨機產(chǎn)生某種手勢。程序判斷出“輸贏”結果后,會在屏幕上顯示輸出相關的提示信息,同時所對應顏色的LED燈也會發(fā)光(如圖)。
源代碼請關注壹零社公眾號,從網(wǎng)盤下載2023-19.zip。