|

讓我們Py在一起:手勢控制PowerPoint放映切換

   
作者:Ted Lee

在先前的拙著《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.client

import 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註冊即可享有一切福利!

會員福利
1

免費電子報

2

會員搶先看

3

主題訂閱

4

好文收藏

Ted Lee

Author: Ted Lee

從工程師轉任中學教師,又為了捍衛教育理念,投身成為 STEAM 教育工作者,自稱「無可救藥的人文教育理想主義者」的李俊德(Ted Lee)。

Share This Post On

Submit a Comment

發佈留言必須填寫的電子郵件地址不會公開。