首頁 > 軟體

深度學習—計算機視覺 使用Python+OpenCV實現姿態估計

2021-05-21 01:00:07

計算機視覺是一個能夠理解影象和視訊如何儲存和操作的過程,它還有助於從影象或視訊中檢索資料。計算機視覺是人工智慧的一部分。

計算機視覺在自動駕駛汽車,物體檢測,機器人技術,物體跟蹤等方面發揮著重要作用。

什麼是OpenCV?

OpenCV是一個開放原始碼庫,主要用於計算機視覺,影象處理和機器學習。通過OpenCV,它可以為實時資料提供更好的輸出,我們可以處理影象和視訊,以便實現的演算法能夠識別諸如汽車,交通訊號燈,車牌等物體以及人臉,或者甚至是人類的筆跡。藉助其他資料分析庫,OpenCV能夠根據自己的需求處理影象和視訊。

可以在這裡獲取有關OpenCV的更多資訊 https://opencv.org/

我們將與OpenCV-python一起使用的庫是Mediapipe

什麼是Mediapipe?

Mediapipe是主要用於構建多模式音訊,視訊或任何時間序列資料的框架。藉助MediaPipe框架,可以構建令人印象深刻的ML管道,例如TensorFlow,TFLite等推理模型以及媒體處理功能。

姿態估計

通過視訊或實時饋送進行人體姿態估計在諸如全身手勢控制,量化體育鍛煉和手語識別等各個領域中發揮著至關重要的作用。

例如,它可用作健身,瑜伽和舞蹈應用程式的基本模型。它在增強現實中找到了自己的主要作用。

Media Pipe Pose是用於高保真人體姿勢跟蹤的框架,該框架從RGB視訊幀獲取輸入並推斷出整個人類的33個3D界標。當前最先進的方法主要依靠強大的桌面環境進行推理,而此方法優於其他方法,並且可以實時獲得很好的結果。

姿勢地標模型

來源:https://google.github.io/mediapipe/solutions/pose.html

現在開始

首先,安裝所有必需的庫。

– pip install OpenCV-python

– pip install mediapipe

下載任何類型的視訊,例如跳舞,跑步等。

我們將利用這些視訊進行姿勢估計。我正在使用下面的連結中提供的視訊。

https://drive.google.com/file/d/1kFWHaAaeRU4biZ_1wKZlL4KCd0HSoNYd/view?usp=sharing

為了檢查mediapipe是否正常工作,我們將使用上面下載的視訊實現一個小的程式碼。

import cv2import mediapipe as mpimport time

mpPose = mp.solutions.posepose = mpPose.Pose()mpDraw = mp.solutions.drawing_utils#cap = cv2.VideoCapture(0)cap = cv2.VideoCapture('a.mp4')pTime = 0while True:success, img = cap.read()imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)results = pose.process(imgRGB)print(results.pose_landmarks)if results.pose_landmarks:mpDraw.draw_landmarks(img, results.pose_landmarks, mpPose.POSE_CONNECTIONS)for id, lm in enumerate(results.pose_landmarks.landmark):h, w,c = img.shapeprint(id, lm)cx, cy = int(lm.x*w), int(lm.y*h)cv2.circle(img, (cx, cy), 5, (255,0,0), cv2.FILLED)cTime = time.time()fps = 1/(cTime-pTime)pTime = cTimecv2.putText(img, str(int(fps)), (50,50), cv2.FONT_HERSHEY_SIMPLEX,1,(255,0,0), 3)cv2.imshow("Image", img)cv2.waitKey(1)

在上面的內容中,你可以很容易地使用OpenCV從名為「 a.mp4」的視訊中讀取幀,並將幀從BGR轉換為RGB影象,並使用mediapipe在整個處理後的幀上繪製界標。最後,我們將獲得具有地標的視訊輸出,如下所示。

變數「 cTime」,「 pTime」和「 fps」用於計算每秒的讀取幀。你可以在下面的輸出中看到左角的幀數。

終端部分中的輸出是mediapipe檢測到的界標。

姿勢界標

你可以在上圖的終端部分中看到姿勢界標的列表。每個地標包括以下內容:

x和y:這些界標座標分別通過影象的寬度和高度歸一化為[0.0,1.0]。z:通過將臀部中點處的深度作為原點來表示界標深度,並且z值越小,界標與攝影機越近。z的大小几乎與x的大小相同。可見性:[0.0,1.0]中的值,指示界標在影象中可見的可能性。

MediaPipe運行得很好。

讓我們創建一個用於估計姿勢的模組,並且將該模組用於與姿態估計有關的任何其他項目。另外,你可以在網路攝像頭的幫助下實時使用它。

創建一個名為「 PoseModule」的python檔案

import cv2import mediapipe as mpimport time

class PoseDetector:def __init__(self, mode = False, upBody = False, smooth=True, detectionCon = 0.5, trackCon = 0.5):self.mode = modeself.upBody = upBodyself.smooth = smoothself.detectionCon = detectionConself.trackCon = trackConself.mpDraw = mp.solutions.drawing_utilsself.mpPose = mp.solutions.poseself.pose = self.mpPose.Pose(self.mode, self.upBody, self.smooth, self.detectionCon, self.trackCon)def findPose(self, img, draw=True):imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)self.results = self.pose.process(imgRGB)#print(results.pose_landmarks)if self.results.pose_landmarks:if draw:self.mpDraw.draw_landmarks(img, self.results.pose_landmarks, self.mpPose.POSE_CONNECTIONS)return imgdef getPosition(self, img, draw=True):lmList= []if self.results.pose_landmarks:for id, lm in enumerate(self.results.pose_landmarks.landmark):h, w, c = img.shape#print(id, lm)cx, cy = int(lm.x * w), int(lm.y * h)lmList.append([id, cx, cy])if draw:cv2.circle(img, (cx, cy), 5, (255, 0, 0), cv2.FILLED)return lmListdef main():cap = cv2.VideoCapture('videos/a.mp4') #make VideoCapture(0) for webcampTime = 0detector = PoseDetector()while True:success, img = cap.read()img = detector.findPose(img)lmList = detector.getPosition(img)print(lmList)cTime = time.time()fps = 1 / (cTime - pTime)pTime = cTimecv2.putText(img, str(int(fps)), (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 3)cv2.imshow("Image", img)cv2.waitKey(1)if __name__ == "__main__": main()

這是姿態估計所需的程式碼,在上面,有一個名為「 PoseDetector」的類,在其中我們創建了兩個物件「 findPose」和「 getPosition」。

在這裡,名為「 findPose」的物件將獲取輸入幀,並藉助名為mpDraw的mediapipe函數,它將繪製身體上的界標,而物件「 getPosition」」將獲得檢測區域的座標,我們還可以藉助此物件高亮顯示任何座標點。

在main函數中,我們將進行測試運行,你可以通過將main函數中的第一行更改為「 cap = cv2.VideoCapture(0)」來從網路攝像頭中獲取實時資料。

由於我們在上面的檔案中創建了一個類,因此我們將在另一個檔案中使用它。

現在是最後階段

import cv2import timeimport PoseModule as pm

cap = cv2.VideoCapture(0)pTime = 0detector = pm.PoseDetector()while True:success, img = cap.read()img = detector.findPose(img)lmList = detector.getPosition(img)print(lmList)cTime = time.time()fps = 1 / (cTime - pTime)pTime = cTimecv2.putText(img, str(int(fps)), (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 3)cv2.imshow("Image", img)cv2.waitKey(1)

在這裡,程式碼將僅呼叫上面創建的模組,並在輸入視訊或網路攝像頭的實時資料上運行整個演算法。這是測試視訊的輸出。

完整的程式碼可在下面的GitHub連結中找到。

https://github.com/BakingBrains/Pose_estimation


IT145.com E-mail:sddin#qq.com