Pose Tracking
API Interface of the iOS Framework
Define holistic pose model variable
private var holisticPoseModel: HolisticPoseModel?
Configure and Instantiate the model with HolisticPoseModelBuilder
@interface HolisticPoseModelBuilder : NSObject
- (instancetype _Nonnull)init;
/**
* \brief Sets the complexity of the used pose landmark model.
*
* \param complexity New pose landmark model complexity.
* Higher model complexity corresponds to higher accuracy of
* the landmarks, but also increases inference latency.
* Default to \a PoseModelComplexity_Normal.
*
* \returns Pointer to the \a HolisticPoseModelBuilder.
*/
- (HolisticPoseModelBuilder* _Nonnull)setPoseModelComplexity:(PoseModelComplexity)complexity;
/**
* \brief Enables pose landmarks smoothing to reduce jitter between consequent
* input frames.
*
* \param enable If set to \a true, the solution filters pose landmarks across
* different input images to reduce jitter. Default to \a true.
*
* \returns Pointer to the \a HolisticPoseModelBuilder.
*/
- (HolisticPoseModelBuilder* _Nonnull)enablePoseLandmarksSmoothing:(bool)enable;
/**
* \brief Enables face landmarks refinement.
*
* \param enable If set to \a true, the solution refines face landmarks
* coordinates around the eyes and lips, and output additional
* landmarks around the irises.
* Default to \a false.
*
* \returns Pointer to the \a HolisticPoseModelBuilder.
*/
- (HolisticPoseModelBuilder* _Nonnull)enableFaceLandmarksRefinement:(bool)enable;
/**
* \brief Creates a new instance of \a HolisticPoseModel.
*
* \param error Object containing error information if model instantiation fails.
*
* \returns Pointer to the new instance of \a HolisticPoseModel if instantiation
* is successful, \a nil otherwise.
*
* \note Model instantiation is a blocking call which can take some time, therefore
* this should be done on a separate serial dispatch queue.
* That won't block the main queue which keeps the UI responsive.
*/
- (HolisticPoseModel* _Nullable)build:(NSError* _Nullable* _Nonnull)error;
@end
Example:
do {
self.holisticPoseModel = try HolisticPoseModelBuilder()
.build()
} catch {
fatalError(
"Failed to instantiate holistic pose model: \(error.localizedDescription)"
)
}
Model instantiation is a blocking call that can take some time, therefore this should be done on a separate serial dispatch queue. That won't block the main queue which keeps the UI responsive.
Schedule the task with HolisticPoseModel.detect
method when the model is instantiated
func captureOutput(_ output: AVCaptureOutput,
didOutput sampleBuffer: CMSampleBuffer,
from connection: AVCaptureConnection) {
guard let imageBuffer = sampleBuffer.imageBuffer else {
return
}
do {
try holisticPoseModel!.detect(on: imageBuffer,
at: sampleBuffer.outputPresentationTimeStamp)
} catch {
NSLog("Failed to submit holistic pose detection task: \(error.localizedDescription)")
}
}
HolisticPoseModel
returns its results through the HolisticPoseDelegate
@protocol HolisticPoseDelegate <NSObject>
/**
* \brief Callback triggered whenever the \a HolisticPoseModel completes the
* processing of the passed frame
*
* \param model The \a HolisticPoseModel that acquired provided detection.
* \param detection Optional \a HolisticPose prediction. \a nil corresponds
* to the situation when none of the \a HolisticPose parts
* are detected.
*/
@optional
- (void)holisticPoseModel:(HolisticPoseModel* _Nonnull)model
didOutputDetection:(HolisticPose* _Nullable)detection;
@end
Example:
func holisticPoseModel(_ model: HolisticPoseModel,
didOutputDetection detection: HolisticPose?) {
cameraPreviewView.draw(detection)
}
Each HolisticPose
instance is represented with the following class
@interface HolisticPose: NSObject
/**
* \brief Collection of 468 face landmarks with normalized coordinates.
* Reference distribution of the landmarks:
* https://raw.githubusercontent.com/google/mediapipe/master/mediapipe/modules/face_geometry/data/canonical_face_model_uv_visualization.png
*
* Depth is predicted relative to the center of the head being the origin.
* \a nil corresponds the situation when face detection has confidence lower
* than the threshold.
*/
@property (readonly, nonatomic) NSArray<Landmark*>* _Nullable faceLandmarks;
/**
* \brief Collection of 16 pose landmarks with normalized coordinates.
*
* Landmarks related to the face and hands are removed for the sake of
* more accurate individual predictions.
*
* Depth is predicted relative to the midpoint of hips being the origin.
* \a nil corresponds the situation when pose detection has confidence lower
* than the threshold.
*/
@property (readonly, nonatomic) NSArray<Landmark*>* _Nullable mergedPoseLandmarks;
/**
* \brief Collection of 33 pose landmarks with normalized coordinates.
*
* Depth is predicted relative to the midpoint of hips being the origin.
* \a nil corresponds the situation when pose detection has confidence lower
* than the threshold.
*/
@property (readonly, nonatomic) NSArray<Landmark*>* _Nullable poseLandmarks;
/**
* \brief Collection of 33 pose landmarks with real-world 3D coordinates in
* meters with the origin at the center between hips.
*
* \a nil corresponds the situation when pose detection has confidence lower
* than the threshold.
*/
@property (readonly, nonatomic) NSArray<Landmark*>* _Nullable poseWorldLandmarks;
/**
* \brief Collection of 21 hand landmarks on the left hand (without respect of
* the real camera position).
*
* Depth is predicted relative to the wrist being the origin.
* \a nil corresponds the situation when hand detection has confidence lower
* than the threshold.
*/
@property (readonly, nonatomic) NSArray<Landmark*>* _Nullable leftHandLandmarks;
/**
* \brief Collection of 21 hand landmarks on the right hand (without respect of
* the real camera position).
* Depth is predicted relative to the wrist being the origin.
* \a nil corresponds the situation when hand detection has confidence lower
* than the threshold.
*/
@property (readonly, nonatomic) NSArray<Landmark*>* _Nullable rightHandLandmarks;
@end
Last updated