Реалізація розпізнавання емоцій за обличчям у мобільних додатках
Розпізнавання емоцій — це детекція обличчя, видобування мімічних ознак та класифікація за базовими емоціями (щастя, смуток, гнів, здивування, страх, відраза, нейтральна за моделлю Екмана). Звучить прямолінійно, але точність промислових систем в реальних умовах (різне освітлення, часткова окклюзія, культурні різниці у вираженні)—активна дослідна тема.
Що працює на мобілі
На iOS: VNDetectFaceLandmarksRequest надає 76 landmarks—достатньо для обчислення геометричних дескрипторів (дистанція між кутиками рота, ступінь відкриття очей, кут брів). Навчайте невеликий класифікатор на цих дескрипторах як CoreML модель (MLP 3–4 шари). Цей підхід стабільніший за пряму CNN на зображенні, особливо при поганому освітленні—landmarks нормалізовані до положення голови.
На Android: ML Kit Face Detection з setContourDetectionEnabled(true) дає 468 точок—повна face mesh. Надлишкова для класифікації емоцій, але дозволяє точне відстеження мімічних м'язів.
Альтернатива: MediaPipe Face Landmarker—cross-platform, 478 landmarks + blendshapes (52 параметри типу mouthSmileLeft, eyeBlinkRight, browDownLeft). Blendshapes — це вже семантичні дескриптори мімічного виразу, передавайте напрямую класифікатору без додаткової геометрії. MediaPipe Face Landmarker latency на Pixel 7: ~15 ms.
Моделі класифікації емоцій
Готові on-device варіанти: HSEmotion TFLite (7 класів, ~4 MB), MobileNet-based emotion classifier (FER2013). Точність на валідації: 65–72% на 7 класах. В реальних умовах—нижче. Не bug, а фундаментальне обмеження: "нейтральний" та "задумчивий" вирази вкрай складно класифікувати.
Для бізнес-кейсів (аналітика залучення в edtech, вимірювання реакції на рекламний контент), не працюйте з миттєвою класифікацією. Використовуйте усереднені значення за 2–5 секунд та агреговані метрики: % часу з позитивною емоцією, % нейтральною, піки здивування.
Анімація реакції
Якщо додаток реагує на емоцію користувача (edtech-маскот, інтерактивний персонаж), latency має значення. Цикл: захоплення кадру → infer → оновлення анімації повинен укладатися в 100 ms, інакше реакція сприймається запізнілою.
На iOS: SwiftUI + withAnimation(.spring()) для плавного переходу стану маскота. Infer на background queue, результат через @Published → @StateObject на main actor. На Android: Animator + MotionLayout для складних переходів анімації.
Реальний кейс: освітня програма для дітей з елементами гри. Персонаж реагує на посмішку дитини—танцює, якщо посмішка утримується >1.5 секунди. Використовували MediaPipe Face Landmarker + mouthSmileLeft/Right значення blendshape > 0.6 як триггер. Проблема: дитина сміється з відкритим ротом—mouthOpen blendshape заплутав фільтр. Додали умову: mouthSmile > 0.6 AND mouthOpen < 0.4 OR (mouthOpen > 0.4 AND jawOpen > 0.3). Хибні срабатування скоротилися на 40%.
Аналітика залучення
Для A/B-тестування контенту (який екран викликає більше позитивної реакції)—агрегуйте emotion scores за сесію, надішліть до аналітики. Дані—не фото, тільки числові вектори. Згода користувача через явний opt-in (emotion analytics—чутливі дані).
Часові рамки
MediaPipe / ML Kit детекція + кастомний класифікатор + анімація реакції: 1–2 тижні. Дашборд аналітики залучення: додатково 1 тиждень. Вартість розраховується індивідуально.







