譯者 | 朱先忠
審校 | 重樓
摘要:本文將通過實際操作并結合編程方式介紹如何通過開源工具Rerun輕松實現基于開源框架MediaPipe的人體姿態跟蹤的可視化呈現。
概述
本文中,我們將探索一個利用開源框架MediaPipe的功能以二維和三維方式跟蹤人體姿勢的使用情形。使這一探索更有趣味的是由開源可視化工具Rerun提供的可視化展示,該工具能夠提供人類動作姿勢的整體視圖。
您將一步步跟隨作者使用MediaPipe在2D和3D環境中跟蹤人體姿勢,并探索工具Rerun的可視化功能。
人體姿勢跟蹤
人體姿勢跟蹤是計算機視覺中的一項任務,其重點是識別關鍵的身體位置、分析姿勢和對動作進行分類。這項技術的核心是一個預先訓練的機器學習模型,用于評估視覺輸入,并在圖像坐標和3D世界坐標中識別身體上的地標。該技術的應用場景包括但不限于人機交互、運動分析、游戲、虛擬現實、增強現實、健康等領域。
有一個完美的模型固然很好,但不幸的是,目前的模型仍然不完美。盡管數據集可能存儲了多種體型數據,但人體在個體之間是有所不同的。每個人身體的獨特性都帶來了挑戰,尤其是對于那些手臂和腿部尺寸不標準的人來說,這可能會導致使用這項技術時精度較低。在考慮將這項技術集成到系統中時,承認不準確的可能性至關重要。希望科學界正在進行的努力將為開發更強大的模型鋪平道路。
除了缺乏準確性之外,使用這項技術還需要考慮倫理和法律因素。例如,如果個人未經同意,在公共場所拍攝人體姿勢可能會侵犯隱私權。在現實世界中實施這項技術之前,考慮到任何道德和法律問題都是至關重要的。
先決條件和初始設置
首先,安裝所需的庫:
# 安裝所需的Python包
pip install mediapipe
pip install numpy
pip install opencv-python<4.6
pip install requests>=2.31,<3
pip install rerun-sdk
# 也可以直接使用配置文件requirements.txt
pip install -r examples/python/human_pose_tracking/requirements.txt
使用MediaPipe跟蹤人體姿勢
谷歌提供的姿勢地標檢測指南中的圖像(參考文獻1)
對于希望集成計算機視覺和機器學習的設備ML解決方案的開發人員來說,基于Python語言的MediaPipe框架正是一個方便的工具。
在下面的代碼中,MediaPipe姿態標志檢測被用于檢測圖像中人體的標志。該模型可以將身體姿勢標志檢測為圖像坐標和3D世界坐標。一旦成功運行ML模型,就可以使用圖像坐標和3D世界坐標來可視化輸出。
import mediapipe as mp
import numpy as np
from typing import Any
import numpy.typing as npt
import cv2
"""
從Mediapipe姿勢結果集中讀取二維地標位置。
Args:
results (Any): Mediapipe Pose results.
image_width (int): Width of the input image.
image_height (int): Height of the input image.
Returns:
np.array | None: Array of 2D landmark positions or None if no landmarks are detected.
"""
def read_landmark_positions_2d(
results: Any,
image_width: int,
image_height: int,
) -> npt.NDArray[np.float32] | None:
if results.pose_landmarks is None:
return None
else:
# 提取標準化的地標位置并將其縮放為圖像尺寸
normalized_landmarks = [results.pose_landmarks.landmark[lm] for lm in mp.solutions.pose.PoseLandmark]
return np.array([(image_width * lm.x, image_height * lm.y) for lm in normalized_landmarks])
"""
從Mediapipe Pose結果集中讀取三維地標位置。
Args:
results (Any): Mediapipe Pose results.
Returns:
np.array | None: Array of 3D landmark positions or None if no landmarks are detected.
"""
def read_landmark_positions_3d(
results: Any,
) -> npt.NDArray[np.float32] | None:
if results.pose_landmarks is None:
return None
else:
# 提取三維地標位置
landmarks = [results.pose_world_landmarks.landmark[lm] for lm in mp.solutions.pose.PoseLandmark]
return np.array([(lm.x, lm.y, lm.z) for lm in landmarks])
"""
跟蹤并分析輸入圖像中的姿勢。
Args:
image_path (str): Path to the input image.
"""
def track_pose(image_path: str) -> None:
# 讀取圖像,將顏色轉換為RGB格式
image = cv2.imread(image_path)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# 創建Pose模型實例
pose_detector = mp.solutions.pose.Pose(static_image_mode=True)
# 處理圖像以獲得姿勢標志
results = pose_detector.process(image)
h, w, _ = image.shape
# 讀取二維和三維地標位置
landmark_positions_2d = read_landmark_positions_2d(results, w, h)
landmark_positions_3d = read_landmark_positions_3d(results)
使用Rerun可視化MediaPipe的輸出
Rerun圖像瀏覽器(圖像來自于Rerun官方文檔,參考資料2)
Rerun可作為多模態數據的可視化工具。通過Rerun圖像瀏覽器,您可以構建布局、自定義可視化以及與數據交互。本節的其余部分將詳細介紹如何使用Rerun SDK在Rerun圖像瀏覽器中記錄和顯示數據。
姿勢標志模型(谷歌通過姿勢標志檢測指南拍攝的圖像,參考資料1)
在二維和三維點中,指定點之間的連接至關重要。定義這些連接會自動渲染它們之間的線。使用MediaPipe提供的信息,可以從pose_connections集合獲取姿勢點連接,然后使用Annotation Context將它們設置為關鍵點連接。
rr.log(
"/",
rr.AnnotationContext(
rr.ClassDescription(
info=rr.AnnotationInfo(id=0, label="Person"),
keypoint_annotatinotallow=[rr.AnnotationInfo(id=lm.value, label=lm.name) for lm in mp_pose.PoseLandmark],
keypoint_cnotallow=mp_pose.POSE_CONNECTIONS,
)
),
timeless=True,
)
圖像坐標——二維位置
將人的姿勢可視化為2D點(作者本人提供的圖像)
在視頻中以可視化方式觀察身體姿勢的標志似乎是一個不錯的選擇。要實現這一點,您需要仔細遵循Rerun文檔中有關Entities和Components的相關介紹。其中,“實體路徑層次結構(The Entity Path Hierarchy)”頁面描述了如何在同一實體上記錄多個組件。例如,您可以創建“video”實體,并包括視頻的“video/rgb”組件和身體姿勢的“video/pose”組件。不過,如果你打算把它用于視頻設計中的話,你需要認真掌握時間線的概念。每個幀都可以與適當的數據相關聯。
以下是一個可以將視頻上的2D點可視化的函數:
def track_pose_2d(video_path: str) -> None:
mp_pose = mp.solutions.pose
with closing(VideoSource(video_path)) as video_source, mp_pose.Pose() as pose:
for idx, bgr_frame in enumerate(video_source.stream_bgr()):
if max_frame_count is not None and idx >= max_frame_count:
break
rgb = cv2.cvtColor(bgr_frame.data, cv2.COLOR_BGR2RGB)
# 將幀與數據關聯
rr.set_time_seconds("time", bgr_frame.time)
rr.set_time_sequence("frame_idx", bgr_frame.idx)
# 呈現視頻
rr.log("video/rgb", rr.Image(rgb).compress(jpeg_quality=75))
# 獲取預測結果
results = pose.process(rgb)
h, w, _ = rgb.shape
# 把2D點記錄到'video'實體中
landmark_positions_2d = read_landmark_positions_2d(results, w, h)
if landmark_positions_2d is not None:
rr.log(
"video/pose/points",
rr.Points2D(landmark_positions_2d, class_ids=0, keypoint_ids=mp_pose.PoseLandmark),
)
三維世界坐標——三維點
將人的姿勢可視化為3D點(作者本人提供的圖像)
當你有三維點的時候,為什么要選擇二維點呢?創建一個新實體,將其命名為“Person”,并輸出有關這些三維點的數據。這就行了!這樣就可以創建人體姿勢的三維演示。
以下是操作方法:
def track_pose_3d(video_path: str, *, segment: bool, max_frame_count: int | None) -> None:
mp_pose = mp.solutions.pose
rr.log("person", rr.ViewCoordinates.RIGHT_HAND_Y_DOWN, timeless=True)
with closing(VideoSource(video_path)) as video_source, mp_pose.Pose() as pose:
for idx, bgr_frame in enumerate(video_source.stream_bgr()):
if max_frame_count is not None and idx >= max_frame_count:
break
rgb = cv2.cvtColor(bgr_frame.data, cv2.COLOR_BGR2RGB)
# 把幀與數據關聯起來
rr.set_time_seconds("time", bgr_frame.time)
rr.set_time_sequence("frame_idx", bgr_frame.idx)
# 呈現視頻
rr.log("video/rgb", rr.Image(rgb).compress(jpeg_quality=75))
# 取得預測結果
results = pose.process(rgb)
h, w, _ = rgb.shape
# 對于3D呈現的新的實例"Person"
landmark_positions_3d = read_landmark_positions_3d(results)
if landmark_positions_3d is not None:
rr.log(
"person/pose/points",
rr.Points3D(landmark_positions_3d, class_ids=0, keypoint_ids=mp_pose.PoseLandmark),
)
源代碼探索
本文重點介紹了“人體姿勢跟蹤”示例的主要部分。對于那些喜歡動手的人來說,這個例子的完整源代碼可以在GitHub(https://github.com/rerun-io/rerun/blob/latest/examples/python/human_pose_tracking/main.py)上找到。您可以隨意探索、修改和理解其中實現的內部工作原理。
提示和建議
1.壓縮圖像以提高效率
您可以通過壓縮記錄的圖像來提高整個過程的速度:
rr.log(
"video",
rr.Image(img).compress(jpeg_quality=75)
)
2.限制內存使用
如果你記錄的數據超過了RAM的容量,它就會開始丟棄舊數據。默認限制是系統RAM的75%。如果你想增加這個限制,可以使用命令行參數——內存限制。有關內存限制的更多信息,請參閱Rerun的“如何限制內存使用”頁面信息。
3.根據您的需求定制視覺效果
自定義Rerun查看器(作者本人提供的圖像)
超越人體姿勢跟蹤
如果你覺得這篇文章有用且有些見地,下面再推薦一篇類似主題的文章:
- MediaPipe的實時手部跟蹤和手勢識別:Rerun應用示例
另外,我會經常分享一些關于計算機視覺和機器人的可視化教程。
參考資料
[1]谷歌公司的論文《Pose Landmark Detection Guide》,本頁面的部分內容轉載自谷歌創建和共享的作品,可根據Creative Commons 4.0 Attribution許可證中描述的條款使用。
[2] Rerun官方參考文檔,可根據MIT許可使用。
譯者介紹
朱先忠,51CTO社區編輯,51CTO專家博客、講師,濰坊一所高校計算機教師,自由編程界老兵一枚。
原文標題:Human Pose Tracking with MediaPipe in 2D and 3D: Rerun Showcase,作者:Andreas Naoum