Building an AI-Powered Leg Raises Counter App with Pose Estimation Using QuickPose iOS SDK
Are you interested in developing an AI-powered Leg Raises counter for your fitness app? Leg Raises are a fundamental core exercise that primarily targets the lower abdominal muscles, including the rectus abdominis and the hip flexors, while also engaging the obliques and lower back. This exercise is essential for building core strength, improving stability, and enhancing overall lower body control.
In this guide, you’ll learn how to create a Leg Raises counter app using pose estimation with the QuickPose iOS SDK. Whether you’re building a new fitness app or enhancing an existing one, this tutorial will help you harness the power of AI and pose estimation technology to deliver an effective and user-friendly Leg Raises counter that sets your app apart in the competitive fitness market.
Steps to integrate an AI Leg Raises Counter into your app:
Register an SDK Key with QuickPose
Get your free SDK key on https://dev.quickpose.ai, usage limits may apply. SDK Keys are linked to your bundle ID, please check Key before distributing to the App Store.
This is a quick look to integrate the Leg Raises counter using the QuickPose iOS SDK. You can see the full documentation here: QuickPose iOS SDK Leg Raises Counter installation.
Activate Leg Raises Feature
feature = .fitness(.legRaises)
feature = .fitness(.legRaises, style: customOrConditionalStyle)
Form Feedback
We recommend using the feature feedback to guide the user if an error occurs.
quickPose.start(features: [.fitness(.legRaises)], onFrame: { status, image, features, feedback, landmarks in
switch status {
case .success:
overlayImage = image
if let result = features.values.first {
feedbackText = "Leg Raises: \(Int(result.value * 100))%"
} else if let feedback = feedback.values.first, feedback.isRequired {
feedbackText = feedback.displayString
} else {
feedbackText = nil
}
case .noPersonFound:
feedbackText = "Stand in view";
case .sdkValidationError:
feedbackText = "Be back soon";
}
})
Body position: "Get on your back, side on"
.body(feedback: floorSideOnWithBackOnTheGround, isRequired: true)
Exercise Specific: "Straighten knees" "Lower hips"
.group(action: .straighten, group: .knees, direction: nil, isRequired: true)
.group(action: .lower, group: .hips, direction: nil, isRequired: true)
Conditional Styling
To give user feedback consider using conditional styling so that when the user’s measurement goes above a threshold, here 0.8, a green highlight is shown.
let greenHighlightStyle = QuickPose.Style(conditionalColors: [QuickPose.Style.ConditionalColor(min: 0.8, max: nil, color: UIColor.green)])
quickPose.start(features: [.fitness(.legRaises, style: customOrConditionalStyle)],
onFrame: { status, image, features, feedback, landmarks in ...
})
How to Count Leg Raises
Real-time leg raise counting with AI
To count the Leg Raises declare a configurable threshold counter, which can be used to turn lots of our features into counts.
@State private var counter = QuickPoseThresholdCounter()
Then pass QuickPose’s Leg Raise result to the counter, and display in the feedback text declared above.
quickPose.start(features: [.fitness(.legRaises)], onFrame: { status, image, features, feedback, landmarks in
switch status {
case .success:
overlayImage = image
if let result = features.values.first {
let counterState = counter.count(result.value)
feedbackText = "\(counterState.count) Leg Raises"
} else {
feedbackText = nil
}
case .noPersonFound:
feedbackText = "Stand in view";
case .sdkValidationError:
feedbackText = "Be back soon";
}
})
Leg Raises Timer
To time the Leg Raises declare a configurable threshold timer, which can be used to turn lots of our features into timers. For Leg Raises, we suggest modifying the default threshold, taking account of expected camera positioning and tilt.
@State private var timer = QuickPoseThresholdTimer(threshold: 0.2)
Then pass the result’s raw value to the timer, and display in the feedback text declared above.
quickPose.start(features: [.fitness(.legRaises)], onFrame: { status, image, features, feedback, landmarks in
switch status {
case .success:
overlayImage = image
if let result = features.values.first {
let timerState = timer.time(result.value)
feedbackText = String(format: "%.1f", timerState.time) + "secs"
} else {
feedbackText = nil
}
case .noPersonFound:
feedbackText = "Stand in view";
case .sdkValidationError:
feedbackText = "Be back soon";
}
})