訂閱
糾錯
加入自媒體

一文了解如何使用Python+OpenCV構(gòu)建手部跟蹤系統(tǒng)

OpenCV 是一個用于計算機(jī)視覺應(yīng)用程序的庫。在 OpenCV 的幫助下,我們可以構(gòu)建大量實(shí)時運(yùn)行更好的應(yīng)用程序。主要用于圖像和視頻處理?梢栽诖颂帿@取有關(guān) OpenCV 的更多信息

除了 OpenCV,我們將使用 MediaPipe 庫。MediaPipeMediaPipe是一個主要用于構(gòu)建音頻、視頻或任何時間序列數(shù)據(jù)的框架。在 MediaPipe 框架的幫助下,我們可以為不同的媒體處理功能構(gòu)建管道。MediaPipe 的一些主要應(yīng)用。多手追蹤人臉檢測對象檢測和跟蹤Objection:3D 對象檢測和跟蹤AutoFlip:自動視頻裁剪管道等。

手地標(biāo)模型

MediaPipe 使用單次手掌檢測模型,一旦完成,它會對檢測到的手部區(qū)域中的 21 個 3D 手掌坐標(biāo)執(zhí)行精確的關(guān)鍵點(diǎn)定位。MediaPipe 管道使用多個模型,例如,從完整圖像返回定向手邊界框的手掌檢測模型。裁剪后的圖像區(qū)域被饋送到由手掌檢測器定義的手部標(biāo)志模型,并返回高保真 3D 手部關(guān)鍵點(diǎn),F(xiàn)在讓我們實(shí)現(xiàn)手部跟蹤模型。安裝所需的模塊–> pip install opencv-python–> pip install mediapipe首先,讓我們檢查網(wǎng)絡(luò)攝像頭的工作情況。import cv2
import time
cap = cv2.VideoCapture(0)
pTime = 0
while True:
   success, img = cap.read()
   imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
   cTime = time.time()
   fps = 1 / (cTime - pTime)
   pTime = cTime
   cv2.putText(img, f'FPS:{int(fps)}', (20, 70), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
   cv2.imshow("Test", img)
cv2.waitKey(1)

如果任何網(wǎng)絡(luò)攝像頭連接到你的 PC,上面的代碼將彈出一個窗口,并在輸出窗口的左上角顯示每秒幀數(shù) (fps),F(xiàn)在讓我們開始實(shí)施。導(dǎo)入所需的模塊并初始化所需的變量。import cv2
import mediapipe as mp
import time
cap = cv2.VideoCapture(0)
mpHands = mp.solutions.hands
hands = mpHands.Hands(static_image_mode=False,
                     max_num_hands=2,
                     min_detection_confidence=0.5,
                     min_tracking_confidence=0.5)
mpDraw = mp.solutions.drawing_utils
pTime = 0
cTime = 0
在上面這段代碼中,我們在mp.solutions.hand 中聲明了一個名為“hands”的對象來檢測手部,默認(rèn)情況下,查看類“ Hands() ”內(nèi)部,要檢測的手部數(shù)量設(shè)置為2、最小檢測置信度設(shè)置為0.5,最小跟蹤置信度設(shè)置為0.5。我們將使用mpDraw繪制關(guān)鍵點(diǎn),F(xiàn)在讓我們編寫一個 while 循環(huán)來執(zhí)行我們的代碼。while True:
   success, img = cap.read()
   imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
   results = hands.process(imgRGB)
   #print(results.multi_hand_landmarks)
   if results.multi_hand_landmarks:
       for handLms in results.multi_hand_landmarks:
           for id, lm in enumerate(handLms.landmark):
               #print(id,lm)
               h, w, c = img.shape
               cx, cy = int(lm.x *w), int(lm.y*h)
               #if id ==0:
               cv2.circle(img, (cx,cy), 3, (255,0,255), cv2.FILLED)
           mpDraw.draw_landmarks(img, handLms, mpHands.HAND_CONNECTIONS)
   cTime = time.time()
   fps = 1/(cTime-pTime)
   pTime = cTime
   cv2.putText(img,str(int(fps)), (10,70), cv2.FONT_HERSHEY_PLAIN, 3, (255,0,255), 3)
   cv2.imshow("Image", img)
   cv2.waitKey(1)
在上面的代碼中,我們從網(wǎng)絡(luò)攝像頭讀取幀并將圖像轉(zhuǎn)換為 RGB。然后我們在“ hands.process()” 函數(shù)的幫助下檢測幀中的手。一旦檢測到手,我們將找到關(guān)鍵點(diǎn),然后使用cv2.circle突出顯示關(guān)鍵點(diǎn)中的點(diǎn),并使用mpDraw.draw_landmarks連接關(guān)鍵點(diǎn)。整個代碼如下import cv2
import mediapipe as mp
import time
cap = cv2.VideoCapture(0)
mpHands = mp.solutions.hands
hands = mpHands.Hands(static_image_mode=False,
                     max_num_hands=2,
                     min_detection_confidence=0.5,
                     min_tracking_confidence=0.5)
mpDraw = mp.solutions.drawing_utils
pTime = 0
cTime = 0
while True:
   success, img = cap.read()
   imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
   results = hands.process(imgRGB)
   #print(results.multi_hand_landmarks)
   if results.multi_hand_landmarks:
       for handLms in results.multi_hand_landmarks:
           for id, lm in enumerate(handLms.landmark):
               #print(id,lm)
               h, w, c = img.shape
               cx, cy = int(lm.x *w), int(lm.y*h)
               #if id ==0:
               cv2.circle(img, (cx,cy), 3, (255,0,255), cv2.FILLED)
           mpDraw.draw_landmarks(img, handLms, mpHands.HAND_CONNECTIONS)
   cTime = time.time()
   fps = 1/(cTime-pTime)
   pTime = cTime
   cv2.putText(img,str(int(fps)), (10,70), cv2.FONT_HERSHEY_PLAIN, 3, (255,0,255), 3)
   cv2.imshow("Image", img)
   cv2.waitKey(1)
輸出是:

手部追蹤模型輸出現(xiàn)在讓我們創(chuàng)建一個手部跟蹤模塊,以便我們可以在其他項目中使用它。創(chuàng)建一個新的 python 文件,首先讓我們創(chuàng)建一個名為handDetector的類,其中有兩個成員函數(shù),名為findHands 和findPosition。函數(shù)findHands將接受一個 RGB 圖像并檢測幀中的手并定位關(guān)鍵點(diǎn),繪制地標(biāo),函數(shù)findPosition 將給出手的位置和 id。然后是我們初始化模塊的 main 函數(shù),我們還編寫了一個 while 循環(huán)來運(yùn)行模型。你可以在此處將此設(shè)置或模塊導(dǎo)入到任何其他相關(guān)項目作品中。整個代碼如下import cv2
import mediapipe as mp
import time
class handDetector():
   def __init__(self, mode = False, maxHands = 2, detectionCon = 0.5, trackCon = 0.5):
       self.mode = mode
       self.maxHands = maxHands
       self.detectionCon = detectionCon
       self.trackCon = trackCon
       self.mpHands = mp.solutions.hands
       self.hands = self.mpHands.Hands(self.mode, self.maxHands, self.detectionCon, self.trackCon)
       self.mpDraw = mp.solutions.drawing_utils
       
   def findHands(self,img, draw = True):
       imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
       self.results = self.hands.process(imgRGB)
       # print(results.multi_hand_landmarks)
       if self.results.multi_hand_landmarks:
           for handLms in self.results.multi_hand_landmarks:
               if draw:
                   self.mpDraw.draw_landmarks(img, handLms, self.mpHands.HAND_CONNECTIONS)
       return img
   def findPosition(self, img, handNo = 0, draw = True):
       lmlist = []
       if self.results.multi_hand_landmarks:
           myHand = self.results.multi_hand_landmarks[handNo]
           for id, lm in enumerate(myHand.landmark):
               h, w, c = img.shape
               cx, cy = int(lm.x * w), int(lm.y * h)
               lmlist.a(chǎn)ppend([id, cx, cy])
               if draw:
                   cv2.circle(img, (cx, cy), 3, (255, 0, 255), cv2.FILLED)
       return lmlist
def main():
   pTime = 0
   cTime = 0
   cap = cv2.VideoCapture(0)
   detector = handDetector()
   while True:
       success, img = cap.read()
       img = detector.findHands(img)
       lmlist = detector.findPosition(img)
       if len(lmlist) != 0:
           print(lmlist[4])
       cTime = time.time()
       fps = 1 / (cTime - pTime)
       pTime = cTime
       cv2.putText(img, str(int(fps)), (10, 70), cv2.FONT_HERSHEY_PLAIN, 3, (255, 0, 255), 3)
       cv2.imshow("Image", img)
       cv2.waitKey(1)
if __name__ == "__main__":
   main()
輸出將與上面顯示的相同,以及被跟蹤的手的位置。


聲明: 本文由入駐維科號的作者撰寫,觀點(diǎn)僅代表作者本人,不代表OFweek立場。如有侵權(quán)或其他問題,請聯(lián)系舉報。

發(fā)表評論

0條評論,0人參與

請輸入評論內(nèi)容...

請輸入評論/評論長度6~500個字

您提交的評論過于頻繁,請輸入驗證碼繼續(xù)

暫無評論

暫無評論

    人工智能 獵頭職位 更多
    掃碼關(guān)注公眾號
    OFweek人工智能網(wǎng)
    獲取更多精彩內(nèi)容
    文章糾錯
    x
    *文字標(biāo)題:
    *糾錯內(nèi)容:
    聯(lián)系郵箱:
    *驗 證 碼:

    粵公網(wǎng)安備 44030502002758號