「Pose 地標」工作可讓你偵測圖片中的人體地標 影片。您可以用這項工作找出主要的身體位置、分析情況 以及分類運動這項工作會使用 像是單張圖片或單一圖片這項工作會輸出圖片中的身體姿勢地標 以及 3D 世界座標。
以下指示將示範如何搭配使用 Pose 地標和 iOS 應用程式。程式碼 您可在 GitHub。
如要查看這項工作的實際運作情形,請參閱這個網頁 示範。 進一步瞭解功能、模型和設定選項 請參閱 總覽:
程式碼範例
MediaPipe Tasks 程式碼範例是 Pose Lander 的基本實作 App Engine 應用程式此範例使用實體 iOS 裝置上的相機來偵測 偵測連續影片串流中的姿勢這個應用程式也可以偵測 下載這些內容
你可以將這個應用程式做為起點,開始使用 iOS 應用程式,也可以參照這個應用程式 做出決定Pose Lander 範例程式碼 GitHub。
下載程式碼
以下說明如何建立範例的本機副本 git 指令列工具編寫程式碼。
如要下載範例程式碼,請按照下列步驟操作:
使用下列指令複製 git 存放區:
git clone https://github.com/google-ai-edge/mediapipe-samples
您也可以設定 Git 執行個體來使用稀疏結帳功能, 只有 Pose 地標 er 範例應用程式的檔案:
cd mediapipe git sparse-checkout init --cone git sparse-checkout set examples/pose_landmarker/ios/
建立範例程式碼的本機版本後,您可以安裝 MediaPipe 工作程式庫,使用 Xcode 開啟專案,然後執行應用程式。適用對象 操作說明,請參閱 iOS 設定指南。
重要元件
以下檔案包含 Pose Lander 範例的重要程式碼 應用程式:
- PoseLandmarkerService.swift: 初始化地標器、處理模型選取作業並執行推論 預測出的權重
- CameraViewController: 實作用於即時攝影機畫面輸入模式的 UI,並以視覺化方式呈現 地標。
- MediaLibraryViewController.swift: 實作靜態圖片和影片檔案輸入模式的 UI。 以視覺方式呈現地標
設定
本節說明設定開發環境的重要步驟,以及 程式碼專案使用 Pose 地標 er。如需設定 使用 MediaPipe 工作 (包括平台版本) 的開發環境 規定,請參閱 iOS 設定指南。
依附元件
Pose 地標 er 會使用 MediaPipeTasksVision
程式庫 (必須安裝)
開發應用程式這個程式庫同時與 Swift 和 Objective-C 應用程式相容
且不需要額外設定任何特定語言
如需在 macOS 上安裝 CocoaPods 的操作說明,請參閱 CocoaPods
安裝指南。
有關如何建立包含所需 Pod 的 Podfile
的操作說明
請參閱使用
CocoaPods
使用下列程式碼在 Podfile
中新增 MediaPipeTasksVision Pod:
target 'MyPoseLandmarkerApp' do
use_frameworks!
pod 'MediaPipeTasksVision'
end
如果您的應用程式包含單元測試目標,請參閱設定指南:
iOS,進一步瞭解設定方式
您的 Podfile
。
型號
MediaPipe Pose Landmarker 需要經過訓練且與 透過這項工作如要進一步瞭解 定位地標,請參閱工作總覽模型 專區。
使用 download_models.sh
腳本
下載模型,並使用 Xcode 將模型新增到專案目錄。適用對象
如需將檔案新增至 Xcode 專案的操作說明,請參閱管理檔案
Xcode 中的資料夾和資料夾
專案。
使用 BaseOptions.modelAssetPath
屬性指定模型的路徑
。如需程式碼範例,請參閱下一節。
建立工作
您可以呼叫其其中一個初始化器來建立 Pose Materialer 工作。
PoseLandmarker(options:)
初始化器接受設定值
只要設定成「自動重新啟動」
和「在主機維護期間」選項即可
如果你不需要透過自訂設定初始化的 Pose 地標
您可以使用 PoseLandmarker(modelPath:)
初始化器建立
使用預設選項擺動地標人物。進一步瞭解設定
選項,請參閱設定總覽。
Pose Marker 工作支援 3 種輸入資料類型:靜態圖片、影片檔案
和即時影像串流根據預設,PoseLandmarker(modelPath:)
會初始化
靜態圖片如要初始化工作以處理影片
檔案或直播影片串流,請使用 PoseLandmarker(options:)
指定影片
或即時串流執行模式使用直播模式時,
poseLandmarkerLiveStreamDelegate
設定選項,以便啟用
調整位置標記,將姿勢地標的偵測結果傳送給委派代表
以非同步方式載入物件
選擇與執行中模式對應的分頁,瞭解如何建立工作 然後執行推論
Swift
圖片
import MediaPipeTasksVision let modelPath = Bundle.main.path(forResource: "pose_landmarker", ofType: "task") let options = PoseLandmarkerOptions() options.baseOptions.modelAssetPath = modelPath options.runningMode = .image options.minPoseDetectionConfidence = minPoseDetectionConfidence options.minPosePresenceConfidence = minPosePresenceConfidence options.minTrackingConfidence = minTrackingConfidence options.numPoses = numPoses let poseLandmarker = try PoseLandmarker(options: options)
影片
import MediaPipeTasksVision let modelPath = Bundle.main.path(forResource: "pose_landmarker", ofType: "task") let options = PoseLandmarkerOptions() options.baseOptions.modelAssetPath = modelPath options.runningMode = .video options.minPoseDetectionConfidence = minPoseDetectionConfidence options.minPosePresenceConfidence = minPosePresenceConfidence options.minTrackingConfidence = minTrackingConfidence options.numPoses = numPoses let poseLandmarker = try PoseLandmarker(options: options)
直播
import MediaPipeTasksVision // Class that conforms to the `PoseLandmarkerLiveStreamDelegate` protocol and // implements the method that the pose landmarker calls once it finishes // performing pose landmark detection in each input frame. class PoseLandmarkerResultProcessor: NSObject, PoseLandmarkerLiveStreamDelegate { func poseLandmarker( _ poseLandmarker: PoseLandmarker, didFinishDetection result: PoseLandmarkerResult?, timestampInMilliseconds: Int, error: Error?) { // Process the pose landmarker result or errors here. } } let modelPath = Bundle.main.path(forResource: "pose_landmarker", ofType: "task") let options = PoseLandmarkerOptions() options.baseOptions.modelAssetPath = modelPath options.runningMode = .liveStream options.minPoseDetectionConfidence = minPoseDetectionConfidence options.minPosePresenceConfidence = minPosePresenceConfidence options.minTrackingConfidence = minTrackingConfidence options.numPoses = numPoses // Assign an object of the class to the `poseLandmarkerLiveStreamDelegate` // property. let processor = PoseLandmarkerResultProcessor() options.poseLandmarkerLiveStreamDelegate = processor let poseLandmarker = try PoseLandmarker(options: options)
Objective-C
圖片
@import MediaPipeTasksVision; NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"pose_landmarker" ofType:@"task"]; MPPPoseLandmarkerOptions *options = [[MPPPoseLandmarkerOptions alloc] init]; options.baseOptions.modelAssetPath = modelPath; options.runningMode = MPPRunningModeImage; options.minPoseDetectionConfidence = minPoseDetectionConfidence; options.minPosePresenceConfidence = minPosePresenceConfidence; options.minTrackingConfidence = minTrackingConfidence; options.numPoses = numPoses; MPPPoseLandmarker *poseLandmarker = [[MPPPoseLandmarker alloc] initWithOptions:options error:nil];
影片
@import MediaPipeTasksVision; NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"pose_landmarker" ofType:@"task"]; MPPPoseLandmarkerOptions *options = [[MPPPoseLandmarkerOptions alloc] init]; options.baseOptions.modelAssetPath = modelPath; options.runningMode = MPPRunningModeVideo; options.minPoseDetectionConfidence = minPoseDetectionConfidence; options.minPosePresenceConfidence = minPosePresenceConfidence; options.minTrackingConfidence = minTrackingConfidence; options.numPoses = numPoses; MPPPoseLandmarker *poseLandmarker = [[MPPPoseLandmarker alloc] initWithOptions:options error:nil];
直播
@import MediaPipeTasksVision; // Class that conforms to the `MPPPoseLandmarkerLiveStreamDelegate` protocol // and implements the method that the pose landmarker calls once it finishes // performing pose landmarks= detection in each input frame. @interface APPPoseLandmarkerResultProcessor : NSObject@end @implementation APPPoseLandmarkerResultProcessor - (void)poseLandmarker:(MPPPoseLandmarker *)poseLandmarker didFinishDetectionWithResult:(MPPPoseLandmarkerResult *)poseLandmarkerResult timestampInMilliseconds:(NSInteger)timestampInMilliseconds error:(NSError *)error { // Process the pose landmarker result or errors here. } @end NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"pose_landmarker" ofType:@"task"]; MPPPoseLandmarkerOptions *options = [[MPPPoseLandmarkerOptions alloc] init]; options.baseOptions.modelAssetPath = modelPath; options.runningMode = MPPRunningModeLiveStream; options.minPoseDetectionConfidence = minPoseDetectionConfidence; options.minPosePresenceConfidence = minPosePresenceConfidence; options.minTrackingConfidence = minTrackingConfidence; options.numPoses = numPoses; // Assign an object of the class to the `poseLandmarkerLiveStreamDelegate` // property. APPPoseLandmarkerResultProcessor *processor = [APPPoseLandmarkerResultProcessor new]; options.poseLandmarkerLiveStreamDelegate = processor; MPPPoseLandmarker *poseLandmarker = [[MPPPoseLandmarker alloc] initWithOptions:options error:nil];
注意:如果你使用影片模式或直播模式,Pose 地標會使用 避免在每個影格觸發手掌偵測模型 縮短延遲時間
設定選項
這項工作有下列 iOS 應用程式設定選項:
選項名稱 | 說明 | 值範圍 | 預設值 |
---|---|---|---|
running_mode |
設定任務的執行模式。在架構中
模式: 圖片:單一圖片輸入模式。 VIDEO:影片已解碼的影格模式。 LIVE_STREAM:輸入串流模式 擷取的資訊等。 在此模式下, poseLandmarkerLiveStreamDelegate 必須設為
實作
PoseLandmarkerLiveStreamDelegate ,以便接收
以非同步方式執行姿勢地標偵測
|
{RunningMode.image, RunningMode.video, RunningMode.liveStream } |
RunningMode.image |
num_poses |
可偵測的姿勢數量上限 擺好姿勢的地標師。 | Integer > 0 |
1 |
min_pose_detection_confidence |
姿勢偵測必須達到的最低可信度分數 。 | Float [0.0,1.0] |
0.5 |
min_pose_presence_confidence |
擺出姿勢的最低可信度分數 姿勢地標偵測結果的分數 | Float [0.0,1.0] |
0.5 |
min_tracking_confidence |
姿勢追蹤的最低可信度分數 才算是成功 | Float [0.0,1.0] |
0.5 |
output_segmentation_masks |
Pose 地標 er 是否會為偵測到的警示輸出區隔遮罩 姿勢。 | Boolean |
False |
result_callback |
設定結果事件監聽器以接收地標結果
以非同步方式顯示參與者
只有在執行模式設為「LIVE_STREAM 」時才能使用 |
ResultListener |
N/A |
直播設定
將跑步模式設為即時串流時,Pose Lander 需要
額外的 poseLandmarkerLiveStreamDelegate
設定選項
讓 Pose 地標 er 傳送姿勢地標的偵測結果
以非同步方式載入物件委派項目必須執行
poseLandmarker(_:didFinishDetection:timestampInMilliseconds:error:)
方法,
Pose Lander 會在處理完姿勢的結果後呼叫
每個影格都有地標偵測項目
選項名稱 | 說明 | 值範圍 | 預設值 |
---|---|---|---|
poseLandmarkerLiveStreamDelegate |
使 Pose 地標 er 取得姿勢的跑步結果
在直播模式下非同步進行地標偵測。該類別具有
設為這個屬性必須導入
poseLandmarker(_:didFinishDetection:timestampInMilliseconds:error:)
方法。 |
不適用 | 未設定 |
準備資料
您必須先將輸入圖片或影格轉換為 MPImage
物件。
把它傳給 Pose 地標者MPImage
支援不同類型的 iOS 圖片
並且可在任何執行模式中使用,以便進行推論。如要
關於「MPImage
」的資訊,請參閱
MPImage API
根據您的用途和執行模式,選擇 iOS 圖片格式
應用程式需要。MPImage
接受 UIImage
、CVPixelBuffer
和
CMSampleBuffer
iOS 圖片格式。
UIImage
UIImage
格式非常適合下列執行模式:
圖片:應用程式套件、使用者圖片庫或檔案系統的圖片,格式為
UIImage
張圖片可轉換成MPImage
物件。影片:使用 AVAssetImageGenerator 將影片影格擷取到 CGImage 格式,然後轉換為
UIImage
張圖片。
Swift
// Load an image on the user's device as an iOS `UIImage` object. // Convert the `UIImage` object to a MediaPipe's Image object having the default // orientation `UIImage.Orientation.up`. let image = try MPImage(uiImage: image)
Objective-C
// Load an image on the user's device as an iOS `UIImage` object. // Convert the `UIImage` object to a MediaPipe's Image object having the default // orientation `UIImageOrientationUp`. MPImage *image = [[MPPImage alloc] initWithUIImage:image error:nil];
本範例使用預設值來初始化 MPImage
UIImage.Orientation.Up
方向。您可以使用任一支援的任一種初始化 MPImage
UIImage.Orientation
輕鬆分配獎金姿勢地標不支援鏡像方向,例如 .upMirrored
。
.downMirrored
,.leftMirrored
,.rightMirrored
。
如要進一步瞭解 UIImage
,請參閱 UIImage Apple 開發人員
說明文件:
CVPixelBuffer
CVPixelBuffer
格式非常適合會產生影格的應用程式
並使用 iOS CoreImage
處理流程
CVPixelBuffer
格式非常適合下列執行模式:
圖片:應用程式在經過處理後產生
CVPixelBuffer
張圖片 使用 iOS 的CoreImage
架構,就能傳送給 Pose 地標 執行映像檔執行模式影片:您可以將影片影格轉換為
CVPixelBuffer
格式 並傳送到 Pose 地標,這時影片模式直播:系統可能會轉換使用 iOS 相機產生影格的應用程式。 轉換成
CVPixelBuffer
格式進行處理,才能傳送到 在直播模式中擺動地標人物
Swift
// Obtain a CVPixelBuffer. // Convert the `CVPixelBuffer` object to a MediaPipe's Image object having the default // orientation `UIImage.Orientation.up`. let image = try MPImage(pixelBuffer: pixelBuffer)
Objective-C
// Obtain a CVPixelBuffer. // Convert the `CVPixelBuffer` object to a MediaPipe's Image object having the // default orientation `UIImageOrientationUp`. MPImage *image = [[MPPImage alloc] initWithUIImage:image error:nil];
如要進一步瞭解 CVPixelBuffer
,請參閱 CVPixelBuffer Apple
顯像組件
說明文件:
CMSampleBuffer
CMSampleBuffer
格式會儲存統一媒體類型的媒體樣本,
也很適合使用直播模式iOS 攝影機的即時影格
由 iOS 以 CMSampleBuffer
格式非同步提供
AVCaptureVideoDataOutput。
Swift
// Obtain a CMSampleBuffer. // Convert the `CMSampleBuffer` object to a MediaPipe's Image object having the default // orientation `UIImage.Orientation.up`. let image = try MPImage(sampleBuffer: sampleBuffer)
Objective-C
// Obtain a `CMSampleBuffer`. // Convert the `CMSampleBuffer` object to a MediaPipe's Image object having the // default orientation `UIImageOrientationUp`. MPImage *image = [[MPPImage alloc] initWithSampleBuffer:sampleBuffer error:nil];
如要進一步瞭解 CMSampleBuffer
,請參閱 CMSampleBuffer Apple
顯像組件
說明文件:
執行工作
如要執行 Pose 地標,請使用已指派的 detect()
方法
執行模式:
- 靜態圖片:
detect(image:)
- 影片:
detect(videoFrame:timestampInMilliseconds:)
- 直播:
detectAsync(image:timestampInMilliseconds:)
以下程式碼範例顯示如何在 不同的跑步模式
Swift
圖片
let result = try poseLandmarker.detect(image: image)
影片
let result = try poseLandmarker.detect( videoFrame: image, timestampInMilliseconds: timestamp)
直播
try poseLandmarker.detectAsync( image: image, timestampInMilliseconds: timestamp)
Objective-C
圖片
MPPPoseLandmarkerResult *result = [poseLandmarker detectImage:image error:nil];
影片
MPPPoseLandmarkerResult *result = [poseLandmarker detectVideoFrame:image timestampInMilliseconds:timestamp error:nil];
直播
BOOL success = [poseLandmarker detectAsyncImage:image timestampInMilliseconds:timestamp error:nil];
Pose Marker 程式碼範例說明每種模式的實作方式
詳細說明 detect(image:)
、detect(videoFrame:timestampInMilliseconds:)
和 detectAsync(image:timestampInMilliseconds:)
。範例程式碼允許
使用者可以切換使用系統可能不需要的處理模式
確認是否屬於此情況
注意事項:
以影片模式或直播模式執行時,您必須同時提供 輸入框的時間戳記。
在圖片或影片模式中執行時,「Pose 地標」工作會封鎖 直到完成處理輸入圖片或影格為止。目的地: 為避免封鎖目前的執行緒,請在背景執行處理作業 使用 iOS 的執行緒 調度或 NSOperation 架構。
在直播模式下執行時,Pose 地標 er 工作會立即傳回 但不會封鎖目前的執行緒該函式會叫用
poseLandmarker(_:didFinishDetection:timestampInMilliseconds:error:)
種方式 處理每個輸入影格後,含有姿勢地標結果 調整地標位置,以非同步方式在專屬的系列中叫用這個方法 調度佇列。為了在使用者介面顯示結果,請調度 結果傳送到主要佇列。如果detectAsync
而 Pose 地標工作正忙於處理其他工作時,會呼叫函式 便忽略新的輸入框
處理及顯示結果
在執行推論時,「Pose 地標 er」工作會傳回 PoseLandmarkerResult
內含每個姿勢地標的座標。
以下範例顯示這項工作的輸出資料範例:
PoseLandmarkerResult:
Landmarks:
Landmark #0:
x : 0.638852
y : 0.671197
z : 0.129959
visibility : 0.9999997615814209
presence : 0.9999984502792358
Landmark #1:
x : 0.634599
y : 0.536441
z : -0.06984
visibility : 0.999909
presence : 0.999958
... (33 landmarks per pose)
WorldLandmarks:
Landmark #0:
x : 0.067485
y : 0.031084
z : 0.055223
visibility : 0.9999997615814209
presence : 0.9999984502792358
Landmark #1:
x : 0.063209
y : -0.00382
z : 0.020920
visibility : 0.999976
presence : 0.999998
... (33 world landmarks per pose)
SegmentationMasks:
... (pictured below)
輸出結果包含正規化座標 (Landmarks
) 和世界
每個地標的座標 (WorldLandmarks
)。
輸出結果包含下列正規化座標 (Landmarks
):
x
和y
:地標座標,由 0.0 和 1.0 正規化 圖片寬度 (x
) 和高度 (y
)。z
:地標深度,月經中點的深度為 來源。值越小,地標越接近相機位置。 z 的規模與x
幾乎相同。visibility
:地標在圖片中可見的可能性。
輸出結果包含下列世界座標 (WorldLandmarks
):
x
、y
和z
:實際 3D 座標 (以公尺為單位), 這兩個字的起源visibility
:地標在圖片中可見的可能性。
下圖是工作輸出內容的視覺化呈現:
選用的區隔遮罩代表每個像素歸屬的可能性 並提供給偵測到的人下圖是 工作輸出:
「Pose 地標 er」範例程式碼示範如何顯示 Pose 地標 er 也就是預測結果