【MediaPipe】(2) AI视觉,人体姿态关键点实时跟踪,附python完整代码
各位同學好,今天和大家分享一下如何使用MediaPipe完成人體姿態關鍵點的實時跟蹤檢測,先放張圖看效果,FPS值為17,右下輸出框為32個人體關鍵點的xy坐標。
有需要的可以使用?cv2.VideoCapture(0)?捕獲電腦攝像頭。本節就用馬老師的視頻來跟蹤人體姿態。
1. 導入工具包
# 安裝opencv
pip install opencv-contrib-python
# 安裝mediapipe
pip install mediapipe
# pip install mediapipe --user #有user報錯的話試試這個# 安裝之后導入各個包
import cv2 #opencv
import mediapipe as mp
import time
人體姿態檢測相關說明見官方文檔:Pose - mediapipe (google.github.io)
MediaPipe Pose 中的地標模型預測了 33 個姿勢地標的位置(見下圖)。
2. 相關函數說明
從mediapipe中導入檢測方法,今天我們使用mediapipe.solutions.pose,其他的后續章節再寫。
mediapipe.solutions.hands # 手部關鍵點檢測
mediapipe.solutions.pose # 人體姿態檢測
mediapipe.solutions.face_mesh # 人臉網狀檢測
mediapipe.solutions.face_detection # 人臉識別
....................
(1)mediapipe.solutions.pose.Pose()? 姿態關鍵點檢測函數
參數:
static_image_mode: 默認為 False,將輸入圖像視為視頻流。它將嘗試在第一張圖像中檢測最突出的人,并在成功檢測后進一步定位姿勢地標。在隨后的圖像中,它只是簡單地跟蹤那些地標,而不會調用另一個檢測,直到失去對目標的跟蹤,可以減少計算和延遲。若為 True,則會對每張輸入圖像執行人體檢測方法,非常適合處理一批靜態的、可能不相關的圖像。
model_complexity: 默認為 1,姿勢地標模型的復雜度:0、1 、2。地標準確度和推理延遲通常隨著模型復雜度的增加而增加。
smooth_landmarks: 默認為 True,平滑圖像,過濾不同的輸入圖像上的姿勢地標以減少抖動,但如果static_image_mode也設置為 True 則忽略。
upper_body_only: 默認為 False,是否只檢測上半身的地標。人體姿勢共有33個地標,上半身的姿勢地標有25個。
enable_segmentation: 默認為False。如果設置為 true,除了姿勢地標之外,該解決方案還會生成分割掩碼。
smooth_segmentation:默認為 True,過濾不同的輸入圖像上的分割掩碼以減少抖動,但如果 enable_segmentation?設置為?False,或者 static_image_mode?設置為 True 則忽略。
min_detection_confidence: 默認為 0.5,來自人員檢測模型的最小置信值 (0-1之間),高于該閾值則認為檢測視為成功。
min_tracking_confidence:默認為 0.5。來自地標跟蹤模型的最小置信值 (0-1之間),用于將被視為成功跟蹤的姿勢地標,否則將在下一個輸入圖像上自動調用人物檢測。將其設置為更高的值可以提高解決方案的穩健性,但代價是更高的延遲。如果 static_image_mode 為 True,則人員檢測將在每幀圖像上運行。
返回值:
具有 "pose_landmarks" 字段的 NamedTuple 對象,其中包含檢測到的最突出人物的姿勢坐標。
(2)mediapipe.solutions.drawing_utils.draw_landmarks() ?繪制手部關鍵點的連線
參數:?
image: 需要畫圖的原始圖片
landmark_list: 檢測到的手部關鍵點坐標
connections: 連接線,需要把那些坐標連接起來
landmark_drawing_spec: 坐標的顏色,粗細
connection_drawing_spec: 連接線的粗細,顏色等
3. 繪制關鍵點和連線
使用cv2.VideoCapture()讀取視頻文件時,文件路徑最好不要出現中文,防止報錯。
變量.read()?每次執行就從視頻中提取一幀圖片,需要循環來不斷提取。用success來接收是否能打開,返回True表示可以打開。img保存返回的的每一幀圖像。
由于讀入視頻圖像通道一般為RGB,而opencv中圖像通道的格式為BGR,因此需要cv2.cvtColor()函數將opencv讀入的視頻圖像轉為RGB格式?cv2.COLOR_BGR2RGB。
在繪制人體關鍵點時 mpDraw.draw_landmarks();results.pose_landmarks 獲取所有關鍵點信息;如果不傳入參數mpPose.POSE_CONNECTIONS,那么就不會繪制關鍵點之間的連線 。
import cv2
import mediapipe as mp
import time# 導入姿態跟蹤方法
mpPose = mp.solutions.pose # 姿態識別方法
pose = mpPose.Pose(static_image_mode=False, # 靜態圖模式,False代表置信度高時繼續跟蹤,True代表實時跟蹤檢測新的結果#upper_body_only=False, # 是否只檢測上半身smooth_landmarks=True, # 平滑,一般為Truemin_detection_confidence=0.5, # 檢測置信度min_tracking_confidence=0.5) # 跟蹤置信度
# 檢測置信度大于0.5代表檢測到了,若此時跟蹤置信度大于0.5就繼續跟蹤,小于就沿用上一次,避免一次又一次重復使用模型# 導入繪圖方法
mpDraw = mp.solutions.drawing_utils#(1)導入視頻
filepath = 'C:\\GameDownload\\Deep Learning\\master.mp4'
cap = cv2.VideoCapture(filepath)pTime = 0 # 設置第一幀開始處理的起始時間#(2)處理每一幀圖像
while True:# 接收圖片是否導入成功、幀圖像success, img = cap.read()# 將導入的BGR格式圖像轉為RGB格式imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)# 將圖像傳給姿態識別模型results = pose.process(imgRGB)# 查看體態關鍵點坐標,返回x,y,z,visibility# print(results.pose_landmarks)# 如果檢測到體態就執行下面內容,沒檢測到就不執行if results.pose_landmarks:# 繪制姿態坐標點,img為畫板,傳入姿態點坐標,坐標連線mpDraw.draw_landmarks(img, results.pose_landmarks, mpPose.POSE_CONNECTIONS)# 查看FPScTime = time.time() #處理完一幀圖像的時間fps = 1/(cTime-pTime)pTime = cTime #重置起始時間# 在視頻上顯示fps信息,先轉換成整數再變成字符串形式,文本顯示坐標,文本字體,文本大小cv2.putText(img, str(int(fps)), (70,50), cv2.FONT_HERSHEY_PLAIN, 3, (255,0,0), 3) # 顯示圖像,輸入窗口名及圖像數據cv2.imshow('image', img) if cv2.waitKey(10) & 0xFF==27: #每幀滯留15毫秒后消失,ESC鍵退出break# 釋放視頻資源
cap.release()
cv2.destroyAllWindows()
繪制人體33個關鍵點及連線
??
4. 保存坐標點信息,繪圖編輯
接下來,我們將33個關鍵點的坐標保存下來,并將這些關鍵點放大一些,使其更加明顯。因此我們補充上面的代碼。
由于 results.pose_landmarks.landmark 中保存的xyz坐標是歸一化后的比例坐標,即某一像素點在圖像的某一比例位置,如[0.5, 0.5]。我們需要將其轉為像素坐標,如[200,200],像素坐標一定是整數。通過圖像寬高乘以各自比例即可得到像素坐標下的寬高。為了能更明顯的顯示關鍵點,把關鍵點畫的大一些,只需以關鍵點的像素坐標為圓心畫圓cv2.circle()即可。將像素坐標保存到lmlist中。
import cv2
import mediapipe as mp
import time# 導入姿態跟蹤方法
mpPose = mp.solutions.pose # 姿態識別方法
pose = mpPose.Pose(static_image_mode=False, # 靜態圖模式,False代表置信度高時繼續跟蹤,True代表實時跟蹤檢測新的結果#upper_body_only=False, # 是否只檢測上半身smooth_landmarks=True, # 平滑,一般為Truemin_detection_confidence=0.5, # 檢測置信度min_tracking_confidence=0.5) # 跟蹤置信度
# 檢測置信度大于0.5代表檢測到了,若此時跟蹤置信度大于0.5就繼續跟蹤,小于就沿用上一次,避免一次又一次重復使用模型# 導入繪圖方法
mpDraw = mp.solutions.drawing_utils#(1)導入視頻
filepath = 'C:\\GameDownload\\Deep Learning\\master.mp4'
cap = cv2.VideoCapture(filepath)pTime = 0 # 設置第一幀開始處理的起始時間#(2)處理每一幀圖像
lmlist = [] # 存放人體關鍵點信息while True:# 接收圖片是否導入成功、幀圖像success, img = cap.read()# 將導入的BGR格式圖像轉為RGB格式imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)# 將圖像傳給姿態識別模型results = pose.process(imgRGB)# 查看體態關鍵點坐標,返回x,y,z,visibility# print(results.pose_landmarks)# 如果檢測到體態就執行下面內容,沒檢測到就不執行if results.pose_landmarks:# 繪制姿態坐標點,img為畫板,傳入姿態點坐標,坐標連線mpDraw.draw_landmarks(img, results.pose_landmarks, mpPose.POSE_CONNECTIONS)# 獲取32個人體關鍵點坐標, index記錄是第幾個關鍵點for index, lm in enumerate(results.pose_landmarks.landmark):# 保存每幀圖像的寬、高、通道數h, w, c = img.shape# 得到的關鍵點坐標x/y/z/visibility都是比例坐標,在[0,1]之間# 轉換為像素坐標(cx,cy),圖像的實際長寬乘以比例,像素坐標一定是整數cx, cy = int(lm.x * w), int(lm.y * h)# 打印坐標信息print(index, cx, cy)# 保存坐標信息lmlist.append((cx, cy))# 在關鍵點上畫圓圈,img畫板,以(cx,cy)為圓心,半徑5,顏色綠色,填充圓圈cv2.circle(img, (cx,cy), 3, (0,255,0), cv2.FILLED)# 查看FPScTime = time.time() #處理完一幀圖像的時間fps = 1/(cTime-pTime)pTime = cTime #重置起始時間# 在視頻上顯示fps信息,先轉換成整數再變成字符串形式,文本顯示坐標,文本字體,文本大小cv2.putText(img, str(int(fps)), (70,50), cv2.FONT_HERSHEY_PLAIN, 3, (255,0,0), 3) # 顯示圖像,輸入窗口名及圖像數據cv2.imshow('image', img) if cv2.waitKey(10) & 0xFF==27: #每幀滯留15毫秒后消失,ESC鍵退出break# 釋放視頻資源
cap.release()
cv2.destroyAllWindows()
?結果如下,右下輸出框打印每一幀圖像的關鍵點的xy坐標信息
總結
以上是生活随笔為你收集整理的【MediaPipe】(2) AI视觉,人体姿态关键点实时跟踪,附python完整代码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【MediaPipe】(1) AI视觉,
- 下一篇: 【MediaPipe】(3) AI视觉,