在先前的拙著《Python玩AI,你也可以》中,成功的解析了「剪刀石頭布RSP」實例(RSP.py)。緊接著,我們也測試了PowerPoint檔自動放映的範例(Slideshow.py)。本文嘗試將這兩隻個別測妥的程式合併成可以「用手勢自動切換PowerPoint」的小專案(PPT controller.py),並以此過程來展示專案開發的技巧:
將大問題拆解為數個小問題後,再將各部份的解答回組成原解。
圖1詳盡地說明本文發展的過程:第一線,和陳會安老師學了CVzone的 ch6-5.py 範例後,我們先很用功的寫出每一行程式的註解 cvzoneRSP_詳註.py 。接著,再發想出用手勢來控制PowerPoint的播放切換。隨後,著手搜尋並測試了 PPT slideshow.py 這個程式片段。完成之後,我們將這兩隻程式合拼成 PPT controller.py。
圖1:手勢控制PowerPoint切換的演進過程。
cvzoneRSP_詳註.py
詳細說明請讀者參閱《Python玩AI,你也可以》,以下僅列出完整程式碼:
from cvzone.HandTrackingModule import HandDetector #L5初始化用import cv2
cap = cv2.VideoCapture(0) #攝影機的handler
detector = HandDetector(detectionCon=0.5, maxHands=1) #detectionCon:偵測的信心值(confidence)、maxHands:可測到幾隻手
while cap.isOpened(): #當攝影機被開啟時
success, img = cap.read() #回傳攝影機讀到的影像
hands, img = detector.findHands(img) #從影像中中偵測手
if hands: #如果有偵測到手
hand = hands
bbox = hand #bbox: bounding box
fingers = detector.fingersUp(hand) #fingers =
totalFingers = fingers.count(1) #fingers裡有個1
print(totalFingers)
msg = "None" #顯示剪刀、石頭、布
if totalFingers == 5:
msg = "Paper"
if totalFingers == 0:
msg = "Rock"
if totalFingers == 2:
if fingers == 1 and fingers == 1: #食指 + 中指
msg = "Scissors"
cv2.putText(img, msg, (bbox+200,bbox-30), cv2.FONT_HERSHEY_PLAIN, 2, (0, 255, 0), 2) #顯示bbox框框 + 訊息
cv2.imshow("Image", img) #顯示圖片img,視窗標題為Image
if cv2.waitKey(1) & 0xFF == ord("q"): #按q離開迴圈
break
cap.release() #釋放攝影機handler cap
cv2.destroyAllWindows() #關閉視窗
PPT slideshow.py
這篇Satck Overflow中的文章展示如下的程式碼,它是援用Python版的Win32擴充(extensions) pywin32 使用 COM(Component Object Model ,元件物件模型) 來控制PowerPoint。
import win32com.client #L4, 5用import time #L8, 11, 14, 17用
app = win32com.client.Dispatch("PowerPoint.Application")
presentation = app.Presentations.Open(FileName=u'd:\\要播放的PowerPoint檔.pptx', ReadOnly=1) #開啟PowerPoint檔
presentation.SlideShowSettings.Run() #PowerPoint放映
time.sleep(1) #延遲一段時間
presentation.SlideShowWindow.View.Next() #切換到下一頁
time.sleep(1)
presentation.SlideShowWindow.View.Next() #切換到下一頁
time.sleep(1)
presentation.SlideShowWindow.View.Previous() #切回到上一頁
time.sleep(1)
presentation.SlideShowWindow.View.Exit() #關閉PowerPoint檔
app.Quit() #關閉PowerPoint
讓我們Py在一起:PPT controller.py
cvzoneRSP_詳註.py 和 PPT slideshow.py 整併如下:
import win32com.clientimport time
app = win32com.client.Dispatch("PowerPoint.Application")
presentation = app.Presentations.Open(FileName=u'd:\\Bit It.pptx', ReadOnly=1)
presentation.SlideShowSettings.Run()
delay_find = 0
flag = 0
import time
from cvzone.HandTrackingModule import HandDetector
import cv2
cap = cv2.VideoCapture(0) #使用第一台攝影機
detector = HandDetector(detectionCon=0.5, maxHands=1) #手部偵測
#攝影机已開啟
while cap.isOpened():
success, img = cap.read() #讀入影像
hands, img = detector.findHands(img) #找手
if flag == 0:
#找到手
if hands:
hand = hands
bbox = hand
#有幾根手指
fingers = detector.fingersUp(hand)
totalFingers = fingers.count(1)
msg = "None"
if totalFingers == 1:
presentation.SlideShowWindow.View.Next()
cv2.putText(img, msg, (bbox+200,bbox-30), cv2.FONT_HERSHEY_PLAIN, 2, (0, 255, 0), 2)
flag = 1
delay_find = 0
cv2.imshow("Image", img)
delay_find = delay_find + 1
if delay_find > 30:
flag = 0
#按q離開
if cv2.waitKey(1) & 0xFF == ord("q"):
presentation.SlideShowWindow.View.Exit() #關閉PowerPoint
app.Quit() #關閉PowerPoint
break
cap.release()
cv2.destroyAllWindows()
延伸應用發想
可以在控制PowerPoint放映時還能像新聞主播播報新聞那樣隨時圈畫重點嗎?也許將本文再結合這篇「AI虛擬畫家 」就能達成。讀者們可以自行試試看。或者,電腦視覺特區(Computer Vision Zone) 上也有許多使用AI的電腦視覺專案,像是「虛擬鍵盤(Virtual Keyboard)」,有興趣的讀者可以參考它們的程式碼再行整併出更有趣的實例。
期待!
後記:如何解題?
一般而言,解決問題的基本方法論(methodology)有兩種:由上而下(Top Down)或由下而上(Bottom Up),如圖2和圖3所示。
前者是把大問題先拆解為各個功能獨立的小問題,個別求出其解後再將之組成原問題的解答;後者是從已知解答的各個小問題再發想出相關的應用,而這個新問題的答案就能快速地從已知合併(merge)出最終的結果。
只需不到短短一分鐘...
輸入您的信箱與ID註冊即可享有一切福利!
會員福利
免費電子報
會員搶先看
主題訂閱
好文收藏