隨著健身行業的發展,越來越多的智能應用涌現,用于幫助健身者更好地記錄和分析運動情況。特別是在體能訓練中,俯臥撐和引體向上是兩個非常常見的動作,它們通常用來鍛煉上半身力量和耐力。為了使訓練更加科學和高效,實時監控和自動計數這些動作變得尤為重要。
在這篇博客中,我們將介紹如何基于 YOLO-Pose 模型來監控俯臥撐和引體向上的執行情況,并結合計算機視覺技術實現動作計數。我們將探索 YOLO-Pose 如何與人體姿勢估計結合,通過檢測人體關鍵點來判斷動作的完成度,并最終實現運動計數功能。
1. YOLO-Pose 模型概述
YOLO(You Only Look Once)是一種高效的目標檢測算法,以其在實時檢測中的高性能而廣受歡迎。隨著 YOLO 系列的更新,尤其是 YOLOv8、YOLOv9、YOLOv10 和 YOLOv12,YOLO 已經不再僅僅局限于傳統的目標檢測任務,它還擴展到了包括人體姿勢估計、實例分割、語義分割等任務。在姿勢估計方面,YOLO-Pose 正是結合 YOLO 的強大檢測能力,通過提取人體的關鍵點坐標來分析人體的運動狀態。
YOLO-Pose 模型基于 YOLO 系列架構,專注于人體姿勢估計,能夠在視頻流中實時檢測人體的關鍵點并分析其運動。通過檢測這些關鍵點的相對位置,我們可以判斷出用戶是否正在進行俯臥撐、引體向上等動作,并基于這些信息進行自動計數。
2. YOLO-Pose 在運動監控中的應用
在運動監控中,尤其是像俯臥撐和引體向上這樣依賴肢體動作的訓練項目中,我們通常需要對以下幾個關節的姿勢進行跟蹤:
-
俯臥撐監控:我們需要監控肩膀、肘部和腕部的相對位置,尤其是肘部的彎曲角度。
-
引體向上監控:我們需要跟蹤肩膀、肘部和手腕的運動,特別是手臂是否完全伸直或完全彎曲。
YOLO-Pose 提供的關節坐標(如肩膀、肘部、膝蓋等)能夠幫助我們精確地計算出這些動作的完成度。通過計算關鍵點之間的角度變化,我們可以準確判斷是否完成了動作的一個循環。
2.1 俯臥撐監控
俯臥撐是一項主要鍛煉上肢和胸部肌肉的動作,其標準動作包括雙手撐地并彎曲肘部,直到胸部接近地面,然后恢復到初始姿勢。在這種運動中,肘部角度的變化是判斷動作是否完成的關鍵。
-
當肘部角度小于某個閾值時,表示身體處于下壓狀態;
-
當肘部角度大于閾值時,表示動作恢復到起始位置。
2.2 引體向上監控
引體向上是一項主要鍛煉背部和上肢力量的運動。其標準動作是通過雙手抓住橫桿,彎曲肘部將身體拉起,直到下巴超過橫桿位置,然后恢復到起始姿勢。引體向上的關鍵監控點是肘部和肩膀。
-
當肘部接近伸直時,表示動作結束;
-
當肘部彎曲并拉升身體時,表示進入上升狀態。
3. AIGym 類的實現:基于 YOLO-Pose 的實時運動監控
在 AIGym
類的實現中,我們使用了 YOLO-Pose 來處理實時視頻流中的姿勢估計。該類能夠實時監控并統計不同類型的運動(如俯臥撐、引體向上等)。下面是 AIGym
類的核心代碼,它實現了基于 YOLO-Pose 模型的運動監控和計數功能。
3.1 AIGym
類初始化
from ultralytics.utils.checks import check_imshow
from ultralytics.utils.plotting import Annotatorclass AIGym:"""A class to manage the gym steps of people in a real-time video stream based on their poses."""def __init__(self,kpts_to_check=None,line_thickness=2,pose_up_angle=145.0,pose_down_angle=90.0,pose_type="pullup",):"""Initializes the AIGym class with the specified parameters.Args:kpts_to_check (list, optional): Indices of keypoints to check. Defaults to [6, 8, 10].line_thickness (int, optional): Thickness of the lines drawn. Defaults to 2.pose_up_angle (float, optional): Angle threshold for the 'up' pose. Defaults to 145.0.pose_down_angle (float, optional): Angle threshold for the 'down' pose. Defaults to 90.0.pose_type (str, optional): Type of pose to detect ('pullup', 'pushup', 'abworkout', 'squat'). Defaults to "pullup"."""self.kpts_to_check = kpts_to_check or [6, 8, 10] # Default keypointsself.tf = line_thicknessself.poseup_angle = pose_up_angleself.posedown_angle = pose_down_angleself.pose_type = pose_type# Initialize attributesself.im0 = Noneself.keypoints = Noneself.annotator = Noneself.env_check = check_imshow(warn=True)self.count = []self.angle = []self.stage = []
在初始化方法中,我們定義了以下參數:
-
kpts_to_check
:關鍵點索引,指示需要監測的關節位置(例如,肩膀、肘部、腕部等)。 -
pose_up_angle
和pose_down_angle
:這兩個角度閾值用于判斷動作的上下階段,適用于不同的運動類型(如俯臥撐、引體向上)。 -
pose_type
:指定需要監測的運動類型,如“pullup”(引體向上)、“pushup”(俯臥撐)等。
3.2 obj_exe
方法:實時處理視頻幀
def obj_exe(self, im0, results):"""Function used to count the gym steps.Args:im0 (ndarray): Current frame from the video stream.results (list): Pose estimation data."""self.im0 = im0if not len(results[0]):return self.im0# Initialize annotator objectself.annotator = Annotator(self.im0, line_width=self.tf)# If there are more humans in the current frame, extend the count, angle, and stage listsif len(results[0]) > len(self.count):new_human = len(results[0]) - len(self.count)self.count.extend([0] * new_human)self.angle.extend([0] * new_human)self.stage.extend(["-"] * new_human)# Get keypoints from the pose estimation resultself.keypoints = results[0].keypoints.data# Iterate over each detected personfor ind, k in enumerate(self.keypoints):if self.pose_type in {"pushup", "pullup", "abworkout", "squat"}:# Calculate the angle between keypointsself.angle[ind] = self.annotator.estimate_pose_angle(k[int(self.kpts_to_check[0])].cpu(),k[int(self.kpts_to_check[1])].cpu(),k[int(self.kpts_to_check[2])].cpu(),)# Draw keypoints (no need to pass 'shape' argument)self.im0 = self.annotator.draw_specific_points(k, self.kpts_to_check, radius=10)# Determine the exercise stage and countif self.pose_type in {"abworkout", "pullup"}:if self.angle[ind] > self.poseup_angle:self.stage[ind] = "down"if self.angle[ind] < self.posedown_angle and self.stage[ind] == "down":self.stage[ind] = "up"self.count[ind] += 1elif self.pose_type in {"pushup", "squat"}:if self.angle[ind] > self.poseup_angle:self.stage[ind] = "up"if self.angle[ind] < self.posedown_angle and self.stage[ind] == "up":self.stage[ind] = "down"self.count[ind] += 1# Annotate the angle, count, and stage on the imageself.annotator.plot_angle_and_count_and_stage(angle_text=self.angle[ind],count_text=self.count[ind],stage_text=self.stage[ind],center_kpt=k[int(self.kpts_to_check[1])],)# Draw keypoint linesself.annotator.kpts(k, radius=1, kpt_line=True)return self.im0
在 obj_exe
方法中,YOLO-Pose 模型的輸出結果被傳遞給 AIGym
類,我們利用關鍵點的角度變化來判斷用戶的動作是否完成,并更新計數。根據運動類型(如“俯臥撐”或“引體向上”),代碼會判斷當前動作是否已經完成一個周期(上升和下壓)。
4. 總結與未來展望
基于 YOLO-Pose 模型的實時運動監控系統能夠為用戶提供精準的動作計數和實時反饋。無論是在家庭健身、健身房還是專業訓練中,這樣的智能系統都可以幫助用戶更好地掌握自己的訓練效果。通過跟蹤關鍵點和計算角度,YOLO-Pose 可以實時檢測各種運動姿勢,幫助用戶提高運動質量,防止錯誤動作。
隨著 YOLO-Pose 技術的不斷進步和計算機視覺領域的創新,未來這些技術將在更廣泛的應用場景中發揮更大的作用,包括康復訓練、運動科學研究等領域。通過不斷優化算法,增加更多的運動姿勢監測功能,未來的智能健身系統將更加精準、智能和高效。
對 PiscTrace or PiscCode感興趣?更多精彩內容請移步官網看看~🔗 PiscTrace
引體向上效果在這里使用 YOLO 姿態模型進行動作判定和監測:如何在 PiscTrace 中實現引體向上檢測_yolo 姿態監控-CSDN博客