Реалізація AI-розпізнавання їжі та підрахунку калорій за фотографією у мобільному застосунку

TRUETECH займається розробкою, підтримкою та обслуговуванням мобільних додатків iOS, Android, PWA. Маємо великий досвід та експертизу для публікації мобільних додатків до популярних маркетів Google Play, App Store, Amazon, AppGallery та інші.

Розробка та підтримка будь-яких видів мобільних додатків:

Інформаційні та розважальні мобільні програми
Новинки, ігри, довідники, онлайн-каталоги, погодні, фітнес та здоров'я, туристичні, освітні, соціальні мережі та месенджери, квіз, блоги та подкасти, форуми, агрегатори
Мобільні програми електронної комерції
Інтернет-магазини, B2B-додатки, маркетплейси, онлайн-обмінники, кешбек-сервіси, біржі, дропшиппінг-платформи, програми лояльності, доставка їжі та товарів, платіжні системи
Мобільні програми для управління бізнес-процесами
CRM-системи, ERP-системи, управління проектами, інструменти для команди продажів, облік фінансів, управління виробництвом, логістика та доставка, управління персоналом, системи моніторингу даних
Мобільні програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, платформи надання електронних послуг, платформи кешбеку, відеохостинги, тематичні портали, платформи онлайн-бронювання та запису, платформи онлайн-торгівлі

Це лише деякі з типів мобільних додатків, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1735 послуг
Реалізація AI-розпізнавання їжі та підрахунку калорій за фотографією у мобільному застосунку
Складний
~1-2 тижні
Часті запитання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_mobile-applications_feedme_467_0.webp
    Розробка мобільного додатка для компанії FEEDME
    792
  • image_mobile-applications_xoomer_471_0.webp
    Розробка мобільного додатку для компанії XOOMER
    671
  • image_mobile-applications_rhl_428_0.webp
    Розробка мобільного додатку для компанії RHL
    1097
  • image_mobile-applications_zippy_411_0.webp
    Розробка мобільного додатку для компанії ZIPPY
    969
  • image_mobile-applications_affhome_429_0.webp
    Розробка мобільного додатку для компанії Affhome
    914
  • image_mobile-applications_flavors_409_0.webp
    Розробка мобільного додатку для компанії FLAVORS
    495

AI-Розпізнавання їжі та підрахунок калорій за фотографією у мобільних застосунках

Фудтрекинг через фото—одна з найтехнічно насичених «простих» задач у мобільній AI. Користувач очікує: сфотографував борщ—отримав КБЖУ. На деле між цими двома точками стоїть ланцюжок: розпізнавання блюда, ідентифікація інгредієнтів, оцінка порції, пошук у нутриційній базі. Кожне звено додає похибку.

Технічна ланцюжок розпізнавання

Правильна архітектура—не «одна модель на всі», а конвеєр із кількох спеціалізованих кроків.

Крок 1: детекція й класифікація блюда. CoreML на iOS (модель EfficientDet або YOLOv8 класифікації), TFLite на Android. Для MVP—облачне API: Clarifai Food Model, Google Cloud Vision із food-тегами або спеціалізований Logmeal API.

Крок 2: оцінка порції. Складніше. Без reference object у кадрі (монета, рука, стандартна тарілка) оцінити граммовку майже неможливо. Два практичні рішення: попросити користувача вказати тип тари (тарілка 20см, склянка 200мл) або використовувати ARKit/ARCore для depth estimation. Depth estimation через ARKit дає прийнятні результати для об'ємних блюд—похибка 15–25%, краще, ніж ручний ввід у користувачів (вони зазвичай занижають порцію).

Крок 3: пошук нутриційних даних. USDA FoodData Central—безплатне API з 700 000+ продуктів. Open Food Facts—open-source база, хороша для упакованих продуктів. Для російського ринку критично мати вітчизняні блюда: борщ, пельмені, олів'є—їх немає в USDA в звичному форматі.

// iOS: повний конвеєр розпізнавання
struct FoodRecognitionPipeline {

    func analyze(image: UIImage, portionContext: PortionContext?) async throws -> MealAnalysis {

        // 1. Розпізнавання блюда через Logmeal API
        let foodItems = try await logmealClient.recognizeFood(image: image)

        // 2. Оцінка порції
        let portionEstimates: [PortionEstimate]
        if let context = portionContext {
            portionEstimates = estimatePortionFromContext(foodItems, context: context)
        } else {
            portionEstimates = try await estimatePortionWithAR(image: image)
        }

        // 3. Нутриційні дані
        let nutritionData = try await withThrowingTaskGroup(of: NutritionResult.self) { group in
            for (item, portion) in zip(foodItems, portionEstimates) {
                group.addTask {
                    try await self.fetchNutrition(food: item, grams: portion.estimatedGrams)
                }
            }
            return try await group.reduce(into: []) { $0.append($1) }
        }

        return MealAnalysis(
            items: foodItems,
            portions: portionEstimates,
            nutrition: nutritionData.aggregate(),
            confidence: foodItems.map(\.confidence).min() ?? 0
        )
    }
}

Паралельні запити нутриційних даних через TaskGroup важливі: при 3 блюдах послідовні запити дають 3× затримку.

Складні блюда—головна складність

Борщ на фото—свіжа капуста, морква, картофель, м'ясо, сметана в невідомих пропорціях. Два варіанти рішення:

Рецептна база. LLM або кастомна модель розбиває блюдо на інгредієнти за рецептом. Працює для стандартних блюд, погано—для домашної кухні з варіаціями.

Користувацька корректировка. Після автоматичного розпізнавання користувач бачить передбачуваний склад і може убрати або додати інгредієнти. Swipe-to-remove на інгредієнті, slider для граммовки. Це принципово кращий UX, ніж «точність 98%» без можливості редагування.

// Android: UI складу блюда з редагуванням
@Composable
fun MealCompositionEditor(
    items: List<FoodItem>,
    onItemRemoved: (FoodItem) -> Unit,
    onPortionChanged: (FoodItem, Float) -> Unit
) {
    LazyColumn {
        items(items, key = { it.id }) { item ->
            SwipeToDismiss(
                state = rememberDismissState { if (it == DismissValue.DismissedToStart) {
                    onItemRemoved(item); true } else false
                },
                background = { DeleteBackground() },
                dismissContent = {
                    FoodItemRow(
                        item = item,
                        onPortionChange = { grams -> onPortionChanged(item, grams) }
                    )
                }
            )
        }
    }
}

Інтеграція HealthKit і Health Connect

Записаний приймання їжі повинно попадати в екосистему здоров'я.

// iOS: запис у HealthKit
func logMealToHealthKit(_ meal: MealAnalysis) async throws {
    let store = HKHealthStore()
    let caloriesType = HKQuantityType(.dietaryEnergyConsumed)
    let proteinType = HKQuantityType(.dietaryProtein)
    let carbsType = HKQuantityType(.dietaryCarbohydrates)
    let fatType = HKQuantityType(.dietaryFatTotal)

    let metadata: [String: Any] = [
        HKMetadataKeyFoodType: meal.primaryItem?.name ?? "Mixed Meal"
    ]

    let samples = [
        HKQuantitySample(type: caloriesType,
                        quantity: .init(unit: .kilocalorie(), doubleValue: meal.nutrition.calories),
                        start: .now, end: .now, metadata: metadata),
        HKQuantitySample(type: proteinType,
                        quantity: .init(unit: .gram(), doubleValue: meal.nutrition.protein),
                        start: .now, end: .now)
        // + вуглеводи, жири
    ]

    try await store.save(samples)
}

Запрошуйте дозволи завчасно через HKHealthStore.requestAuthorization. Розповсюджена помилка—запрошувати дозволи при першому відкритті застосунку, до того як користувач побачив цінність. Apple не заборонює, але конверсія значно вища, якщо запит з'являється в момент першої записи їжі.

Бар'єри точності й чесне показування

Навіть хороша модель помиляється на нестандартних блюдах, поганому освітленні й незвичних ракурсах. Ховати невпевненість—помилка. Показувати confidence score поруч із результатом—правильно:

struct NutritionDisplayView: View {
    let analysis: MealAnalysis

    var body: some View {
        VStack(alignment: .leading, spacing: 12) {
            if analysis.confidence < 0.6 {
                ConfidenceWarningBanner(
                    message: "Низька впевненість у розпізнаванні. Перевірте склад блюда."
                )
            }
            CalorieSummaryCard(nutrition: analysis.nutrition)
            MacroBreakdownChart(nutrition: analysis.nutrition)
            IngredientList(items: analysis.items, editable: true)
        }
    }
}

Орієнтири за часом

Базова інтеграція (один API розпізнавання + USDA нутриційна база + простий UI)—1–2 тижні. Повна реалізація з оцінкою порції через AR, складними блюдами, користувацькою корректировкою, HealthKit/Health Connect, історією харчування й денними нормами КБЖУ—1–2 місяці.