ML Kit 提供兩個經過最佳化的姿勢偵測 SDK。
SDK 名稱 | PoseDetection | PoseDetectionAccurate |
---|---|---|
導入作業 | 基本偵測器的素材資源會在建構期間與應用程式建立靜態連結。 | 精確偵測器的素材資源會在建構期間與應用程式建立靜態連結。 |
應用程式大小 | 上限為 29.6 MB | 最多 33.2 MB |
成效 | iPhone X:約 45 FPS | iPhone X:約 29 FPS |
立即試用
- 請試用範例應用程式,瞭解這個 API 的使用範例。
事前準備
在 Podfile 中加入下列 ML Kit Pod:
# If you want to use the base implementation: pod 'GoogleMLKit/PoseDetection', '8.0.0' # If you want to use the accurate implementation: pod 'GoogleMLKit/PoseDetectionAccurate', '8.0.0'
安裝或更新專案的 Pod 後,請使用
xcworkspace
開啟 Xcode 專案。Xcode 13.2.1 以上版本支援 ML Kit。
1. 建立 PoseDetector
的例項
如要偵測圖片中的姿勢,請先建立 PoseDetector
的例項,並視需要指定偵測器設定。
PoseDetector
種付款方式
偵測模式
PoseDetector
會以兩種偵測模式運作。請務必選擇符合您用途的版本。
stream
(預設)- 姿勢偵測器會先偵測圖片中最顯眼的人,然後執行姿勢偵測。在後續影格中,除非人物遭到遮蔽,或系統不再以高可信度偵測到人物,否則不會執行人物偵測步驟。姿勢偵測器會嘗試追蹤最顯眼的人,並在每次推論中傳回該人的姿勢。這麼做可減少延遲時間,並順利偵測。如要偵測影片串流中的姿勢,請使用這個模式。
singleImage
- 姿勢偵測器會偵測人物,然後執行姿勢偵測。每張圖片都會執行人物偵測步驟,因此延遲時間會更長,且不會進行人物追蹤。在靜態圖片上使用姿勢偵測功能,或不希望追蹤時,請使用這個模式。
指定姿勢偵測器選項:
Swift
// Base pose detector with streaming, when depending on the PoseDetection SDK let options = PoseDetectorOptions() options.detectorMode = .stream // Accurate pose detector on static images, when depending on the // PoseDetectionAccurate SDK let options = AccuratePoseDetectorOptions() options.detectorMode = .singleImage
Objective-C
// Base pose detector with streaming, when depending on the PoseDetection SDK MLKPoseDetectorOptions *options = [[MLKPoseDetectorOptions alloc] init]; options.detectorMode = MLKPoseDetectorModeStream; // Accurate pose detector on static images, when depending on the // PoseDetectionAccurate SDK MLKAccuratePoseDetectorOptions *options = [[MLKAccuratePoseDetectorOptions alloc] init]; options.detectorMode = MLKPoseDetectorModeSingleImage;
最後,取得 PoseDetector
的例項。傳遞您指定的選項:
Swift
let poseDetector = PoseDetector.poseDetector(options: options)
Objective-C
MLKPoseDetector *poseDetector = [MLKPoseDetector poseDetectorWithOptions:options];
2. 準備輸入圖片
如要偵測姿勢,請針對每張圖片或影片影格執行下列操作。如果您已啟用串流模式,就必須從 CMSampleBuffer
建立 VisionImage
物件。
使用 UIImage
或 CMSampleBuffer
建立 VisionImage
物件。
如果您使用 UIImage
,請按照下列步驟操作:
- 使用
UIImage
建立VisionImage
物件。請務必指定正確的.orientation
。Swift
let image = VisionImage(image: UIImage) visionImage.orientation = image.imageOrientation
Objective-C
MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image]; visionImage.orientation = image.imageOrientation;
如果您使用 CMSampleBuffer
,請按照下列步驟操作:
-
指定
CMSampleBuffer
中所含圖片資料的方向。如要取得圖片方向,請按照下列步驟操作:
Swift
func imageOrientation( deviceOrientation: UIDeviceOrientation, cameraPosition: AVCaptureDevice.Position ) -> UIImage.Orientation { switch deviceOrientation { case .portrait: return cameraPosition == .front ? .leftMirrored : .right case .landscapeLeft: return cameraPosition == .front ? .downMirrored : .up case .portraitUpsideDown: return cameraPosition == .front ? .rightMirrored : .left case .landscapeRight: return cameraPosition == .front ? .upMirrored : .down case .faceDown, .faceUp, .unknown: return .up } }
Objective-C
- (UIImageOrientation) imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation cameraPosition:(AVCaptureDevicePosition)cameraPosition { switch (deviceOrientation) { case UIDeviceOrientationPortrait: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationLeftMirrored : UIImageOrientationRight; case UIDeviceOrientationLandscapeLeft: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationDownMirrored : UIImageOrientationUp; case UIDeviceOrientationPortraitUpsideDown: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationRightMirrored : UIImageOrientationLeft; case UIDeviceOrientationLandscapeRight: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationUpMirrored : UIImageOrientationDown; case UIDeviceOrientationUnknown: case UIDeviceOrientationFaceUp: case UIDeviceOrientationFaceDown: return UIImageOrientationUp; } }
- 使用
CMSampleBuffer
物件和方向建立VisionImage
物件:Swift
let image = VisionImage(buffer: sampleBuffer) image.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition)
Objective-C
MLKVisionImage *image = [[MLKVisionImage alloc] initWithBuffer:sampleBuffer]; image.orientation = [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation cameraPosition:cameraPosition];
3. 處理圖片
將 VisionImage
傳遞至姿勢偵測器的其中一個圖片處理方法。您可以使用非同步的 process(image:)
方法,也可以使用同步的 results()
方法。
如要同步偵測物件,請按照下列步驟操作:
Swift
var results: [Pose] do { results = try poseDetector.results(in: image) } catch let error { print("Failed to detect pose with error: \(error.localizedDescription).") return } guard let detectedPoses = results, !detectedPoses.isEmpty else { print("Pose detector returned no results.") return } // Success. Get pose landmarks here.
Objective-C
NSError *error; NSArray*poses = [poseDetector resultsInImage:image error:&error]; if (error != nil) { // Error. return; } if (poses.count == 0) { // No pose detected. return; } // Success. Get pose landmarks here.
如要以非同步方式偵測物件,請按照下列步驟操作:
Swift
poseDetector.process(image) { detectedPoses, error in guard error == nil else { // Error. return } guard !detectedPoses.isEmpty else { // No pose detected. return } // Success. Get pose landmarks here. }
Objective-C
[poseDetector processImage:image completion:^(NSArray* _Nullable poses, NSError * _Nullable error) { if (error != nil) { // Error. return; } if (poses.count == 0) { // No pose detected. return; } // Success. Get pose landmarks here. }];
4. 取得偵測到的姿勢相關資訊
如果在圖片中偵測到人物,姿勢偵測 API 會將 Pose
物件的陣列傳遞至完成處理常式,或傳回陣列,這取決於您呼叫的是非同步或同步方法。
如果人物並未完全位於圖片內,模型會將缺少的里程碑座標指派至影格外,並為其提供低的 InFrameConfidence 值。
如果未偵測到任何人,陣列會是空的。
Swift
for pose in detectedPoses { let leftAnkleLandmark = pose.landmark(ofType: .leftAnkle) if leftAnkleLandmark.inFrameLikelihood > 0.5 { let position = leftAnkleLandmark.position } }
Objective-C
for (MLKPose *pose in detectedPoses) { MLKPoseLandmark *leftAnkleLandmark = [pose landmarkOfType:MLKPoseLandmarkTypeLeftAnkle]; if (leftAnkleLandmark.inFrameLikelihood > 0.5) { MLKVision3DPoint *position = leftAnkleLandmark.position; } }
提升成效的訣竅
結果的品質取決於輸入圖片的品質:
- 為了讓 ML Kit 準確偵測姿勢,圖片中的人物應包含足夠的像素資料;為求最佳效能,主體至少應為 256 x 256 像素。
- 如果您要在即時應用程式中偵測姿勢,也許也要考慮輸入圖片的整體尺寸。較小的圖片可加快處理速度,因此為了減少延遲時間,請以較低解析度拍攝圖片,但請注意上述解析度規定,並確保拍攝主體盡可能佔據圖片的大部分空間。
- 圖片對焦不佳也會影響準確度。如果您無法取得可接受的結果,請要求使用者重新拍攝圖片。
如果您想在即時應用程式中使用姿勢偵測功能,請按照下列指南取得最佳影格速率:
- 使用基本 PoseDetection SDK 和
stream
偵測模式。 - 建議您以較低解析度拍攝相片。不過,請注意這個 API 的圖片尺寸規定。
- 如要處理影片影格,請使用偵測器的
results(in:)
同步 API。從 AVCaptureVideoDataOutputSampleBufferDelegate 的 captureOutput(_, didOutput:from:) 函式呼叫這個方法,即可同步取得指定影片影格中的結果。請將 AVCaptureVideoDataOutput 的 alwaysDiscardsLateVideoFrames 設為 true,以便限制對偵測器的呼叫。如果偵測器在執行期間收到新的影片影格,系統會捨棄該影格。 - 如果您使用偵測器的輸出內容,在輸入圖片上疊加圖形,請先從 ML Kit 取得結果,然後在單一步驟中算繪圖片和疊加圖形。這樣一來,您只需為每個已處理的輸入影格轉譯一次顯示介面。如需範例,請參閱展示範例應用程式中的 previewOverlayView 和 MLKDetectionOverlayView 類別。
後續步驟
- 如要瞭解如何使用姿勢地標來分類姿勢,請參閱「姿勢分類訣竅」。
- 如需此 API 的使用範例,請參閱 GitHub 上的 ML Kit 快速入門範例。