How to Build a Bicep Curls Counter App

Building an AI-Powered Bicep Curls Counter App with Pose Estimation Using QuickPose iOS SDK

Are you looking to develop an AI-powered bicep curls counter for your fitness app? Bicep curls are a fundamental strength-training exercise that primarily targets the biceps brachii, with additional engagement of the brachialis and brachioradialis muscles in the arms. This isolation movement is crucial for building arm strength and improving muscle definition.

In this guide, you’ll discover how to create a bicep curls counter app using pose estimation with the QuickPose iOS SDK. We’ll cover how to implement real-time rep counting, ensure accurate form tracking, and provide customized feedback to enhance the user experience. Whether you’re building a new fitness application or enhancing an existing one, this tutorial will help you leverage AI and pose estimation technology to deliver an effective and innovative bicep curls counter that stands out in the fitness market.

Image is a GIF of bicep curls performed in a gym counted by AI pose estimation in a fitness app.

Steps to integrate an AI Bicep Curls 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 bicep curls counter using the QuickPose iOS SDK. You can see the full documentation here: QuickPose iOS SDK Bicep Curls Counter installation.

Activate Bicep Curls Feature

				
					feature = .fitness(.bicepCurls)
feature = .fitness(.bicepCurls, style: customOrConditionalStyle)
				
			


Use the Feedback Feature to guide the user

We recommend using the feature feedback to guide the user if an error occurs

 
				
					quickPose.start(features: [.fitness(.bicepCurls)], onFrame: { status, image, features, feedback, landmarks in
    switch status {
        case .success:
            overlayImage = image
            if let result = features.values.first  {
                feedbackText = "Bicep Curls: \(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";
    }
})
				
			
Image shows bicep curls in a fitness app

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(.bicepCurls, style: customOrConditionalStyle)], 
                onFrame: { status, image, features, feedback, landmarks in  ...
})
				
			

How to Count Bicep Curls

Real-time bicep curls counting with AI

To count the Bicep Curls 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 Bicep Curl result to the counter, and display in the feedback text declared above.

				
					quickPose.start(features: [.fitness(.bicepCurls)], 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) Bicep Curls"
            } else {
                feedbackText = nil
            }
            
        case .noPersonFound:
            feedbackText = "Stand in view";
        case .sdkValidationError:
            feedbackText = "Be back soon";
    }
})
				
			

Bicep Curl Timer

To time the Bicep Curls declare a configurable threshold timer, which can be used to turn lots of our features into timers. For Bicep Curls, 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(.bicepCurls)], 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";
    }
})
				
			

Need help building an AI project?

At QuickPose, our mission is to build smart Pose Estimation Solutions that elevate your product. Schedule a free consultation with us to discuss your project.