Підрахунок повторень — задача, яка звучить просто, але ламається на граничних випадках. Користувач робить присідання повільно — один підхід. Робить пульсуючі рухи вгорі — модель рахує два. Телефон нахилили — координати змістилися, лічильник збився. У нашій практиці ми зіткнулися з проектом фітнес-додатка, де точність підрахунку становила лише 60% через тремтіння камери та різну комплекцію користувачів. Після впровадження адаптивного калібрування та згладжування часового ряду точність зросла до 92%. Зараз цей алгоритм обробляє до 30 кадрів на секунду на пристроях п'ятирічної давності. Документація Apple Vision рекомендує використовувати бічний вигляд камери для кращої точності при віджиманнях, але ми адаптували рішення під фронтальну камеру — це зручніше для користувача.
Як працює AI-підрахунок повторень?
Approach той самий, що в аналізі постави: VNDetectHumanBodyPoseRequest (iOS) або ML Kit Pose Detection (Android) видають ключові точки скелета на кожному кадрі. Але для підрахунку повторень нас цікавить не статична поза, а рух ключової точки в часі.
Для кожної вправи обираємо tracking-точку:
| Вправа | Tracking-точка | Вісь |
|---|---|---|
| Присідання | Стегно (leftHip / rightHip) | Y |
| Віджимання | Зап'ястя або плече | Y |
| Біцепс-кьорл | Зап'ястя | Y |
| Берпі | Зап'ястя + голова | Y комплексно |
| Випад | Коліно | Y |
class RepCounter {
private var positionHistory: [Double] = []
private var repCount: Int = 0
private var state: MovementState = .neutral
private let minAmplitude: Double = 0.08 // 8% висоти екрану
enum MovementState { case neutral, goingDown, bottom, goingUp, top }
func update(normalizedY: Double) {
positionHistory.append(normalizedY)
if positionHistory.count > 30 { positionHistory.removeFirst() }
let smoothed = positionHistory.suffix(5).reduce(0, +) / 5
detectRep(smoothedY: smoothed)
}
private func detectRep(smoothedY: Double) {
let baseline = positionHistory.prefix(10).reduce(0, +) / 10
let deviation = smoothedY - baseline
switch state {
case .neutral where deviation > minAmplitude:
state = .goingDown
case .goingDown where deviation < minAmplitude * 0.3:
state = .bottom
case .bottom where deviation > minAmplitude * 0.7:
state = .goingUp
case .goingUp where deviation < 0:
state = .top
repCount += 1
onRepCompleted?(repCount)
state = .neutral
default: break
}
}
}
Ковзне середнє по 5 кадрах (suffix(5)) — згладжування шуму pose estimation. Без нього лічильник смикається від тремтіння ключових точок між кадрами.
Чому важливе калібрування?
minAmplitude = 0.08 — це відсоток від висоти екрану. Для присідань підходить, для біцепс-кьорла потрібно більше (рука рухається в широкому діапазоні), для віджимань — менше та інша вісь.
Калібрування робимо або через аналітику (навчаємо на відео з розміченими повтореннями), або через адаптивний baseline: перші 3 секунди вправи — вимірюємо амплітуду руху, підлаштовуємо пороги.
class AdaptiveRepCounter {
private var calibrationPhase = true
private var calibrationSamples: [Double] = []
private var dynamicAmplitude: Double = 0.05
func calibrate(y: Double) {
calibrationSamples.append(y)
if calibrationSamples.count >= 75 { // ~3 секунди при 25fps
let range = calibrationSamples.max()! - calibrationSamples.min()!
dynamicAmplitude = range * 0.4 // 40% від спостережуваної амплітуди
calibrationPhase = false
}
}
}
Додатково: фільтрація хибних спрацьовувань
При пульсуючих рухах (наприклад, тряска) алгоритм може помилково зарахувати повторення. Для захисту ми ввели мінімальну часову затримку між фазами — не менше 200 мс. Це відсікає швидкі флуктуації без втрати точності на нормальній швидкості.
Як обрати tracking-точку для вправи?
Вибір точки залежить від амплітуди руху. Для присідань найкраще підходить стегно: воно опускається та піднімається на значну висоту. Для віджимань — зап'ястя або плече, оскільки корпус залишається прямим. Для біцепс-кьорла достатньо зап'ястя. Якщо вправа складна (берпі), використовуємо дві точки та аналізуємо їх комбінацію. Наші інженери підберуть оптимальну конфігурацію під ваш набір вправ — звертайтесь.
Що входить у роботу
- Аналіз вимог: визначення набору вправ та умов зйомки
- Інтеграція pose estimation: VNDetectHumanBodyPoseRequest для iOS або ML Kit для Android
- Реалізація алгоритму підрахунку: згладжування, детекція фаз, адаптивне калібрування
- UI скелета та лічильника: відображення точок та анімація повторень
- Тестування на реальних користувачах: перевірка точності на різних телефонах та умовах освітлення
- Документація та навчання: передача коду та інструкція з калібрування
Орієнтація камери: бічний vs фронтальний вигляд. Одна й та сама задача потребує різних рішень залежно від позиції камери:
| Позиція | Переваги | Недоліки |
|---|---|---|
| Фронтальний вигляд (камера перед користувачем) | Видні обидва плеча, стегна, голова. Добре для присідань, випадів, берпі. | Менше точність для віджимань — зап'ястя іноді перекриваються. |
| Бічний вигляд | Краще для аналізу кута згинання коліна (техніка присіду), точніше для віджимань. | Вимагає штатива / підставки, незручно в реальних умовах. |
Більшість додатків оптимізують під фронтальний вигляд з інструкцією «поставте телефон на 2 метри перед собою на рівні пояса». Зверніться до нас для оцінки проекту — ми проаналізуємо ваші вимоги та запропонуємо оптимальне рішення.
Процес роботи
- Аналітика: обговорюємо цільові вправи та сценарії використання
- Проектування: обираємо підхід (front-end/back-end) та стек
- Реалізація: інтеграція pose estimation, написання алгоритму підрахунку, адаптивне калібрування, UI overlay
- Тестування: перевірка на реальних пристроях з різними користувачами
- Деплой: передача коду, документація, підтримка
Орієнтири за строками та вартістю
Підрахунок 3–5 базових вправ — від 1 до 2 тижнів. Автоматичне розпізнавання вправи + повний трекінг тренування — від 3 до 5 тижнів. Бюджет розробки варіюється від $2,000 до $15,000 залежно від складності та кількості вправ. З нами працюють великі фітнес-платформи, ми гарантуємо точність підрахунку не менше 90% після калібрування. Понад 10 років досвіду в мобільній розробці, понад 50 успішних проектів. Отримайте консультацію щодо реалізації AI-підрахунку у вашому додатку — зв'яжіться з нами для оцінки проекту під ключ. Замовте розробку модуля підрахунку повторень вже сьогодні та отримайте демо-версію за 3 дні.
Зворотний зв'язок та UI: великий контрастний анімований лічильник, UIImpactFeedbackGenerator(style: .rigid) та візуальний спалах при кожному повторенні. Поверх камери відображаємо skeleton — лінії між ключовими точками. Червоний skeleton при низькій впевненості.







