Реалізація AI-розпізнавання сцен для автоматизації розумного дому в мобільному додатку
Типова ситуація: ви запускаєте розумний дім із камерою, і автоматизація спрацьовує лише коли користувач заходить у кімнату, але не реагує на більш тонкі сцени — наприклад, приглушення світла під час перегляду кіно. Помилка в тому, що хмарні ML-сервіси додають латентність 200–500 мс і ризикують приватністю. Локальна класифікація на пристрої — єдиний шлях для сценаріїв реального часу. Це знижує операційні витрати на хмарні обчислення, особливо під час роботи з кількома камерами. Ми реалізували понад 10 таких інтеграцій і знаємо всі граблі: від хибних спрацьовувань при поганому освітленні до конфліктів із App Store Review Guidelines. Досвід показує, що правильна архітектура економить ресурси та час.
Чому локальна обробка критична для розумного дому?
Відправляти кадри з камери на сервер для класифікації — погана ідея для домашньої автоматизації. Латентність неприйнятна, плюс користувач втрачає контроль над даними. Все має працювати локально. Наприклад, на iOS ми використовуємо Apple Vision та CoreML, які виконують класифікацію на чипі A14+ за <30 мс.
iOS: CoreML + Vision framework
Apple Vision Scene Classification — вбудована модель VNClassifyImageRequest. Працює офлайн, видає VNClassificationObservation із confidence score. Для розумного дому достатньо ~20 категорій із 3000+ вбудованих. Документація Apple (Apple Vision Scene Classification) рекомендує такий підхід.
import Vision
import CoreML
class SceneClassifier {
private lazy var request: VNClassifyImageRequest = {
let r = VNClassifyImageRequest { [weak self] request, error in
self?.handleResults(request.results as? [VNClassificationObservation])
}
return r
}()
func classify(pixelBuffer: CVPixelBuffer) {
let handler = VNImageRequestHandler(cvPixelBuffer: pixelBuffer, options: [: ])
try? handler.perform([request])
}
private func handleResults(_ results: [VNClassificationObservation]?) {
guard let top = results?.filter({ $0.confidence > 0.6 }).first else { return }
// top.identifier: "bedroom", "kitchen", "living_room", "bathroom"
SmartHomeAutomation.shared.triggerScene(top.identifier)
}
}
Фільтруємо за confidence > 0.6 і за списком релевантних ідентифікаторів. Не чіпати кадри частіше ніж раз на 2–3 секунди — так економимо батарею та процесор. Для кастомних сценаріїв використовуємо Create ML із MobileNetV3, експорт у .mlpackage, розмір ~4 МБ.
Android: ML Kit Scene Detection + TFLite
ML Kit Subject Segmentation та Scene Detection працюють офлайн на пристрої:
val image = InputImage.fromMediaImage(mediaImage, rotation)
val labeler = ImageLabeling.getClient(
ImageLabelerOptions.Builder()
.setConfidenceThreshold(0.65f)
.build()
)
labeler.process(image)
.addOnSuccessListener { labels ->
val sceneLabel = labels.firstOrNull { it.text in SMART_HOME_SCENES }
sceneLabel?.let { automationEngine.trigger(it.text, it.confidence) }
}
SMART_HOME_SCENES — множина з "bedroom", "kitchen", "living room", "bathroom", "office". Для кастомних моделей — TFLite Interpreter із .tflite файлом, оптимізованим через TensorFlow Model Maker. Персоналізована модель на 500–1000 фото на клас, Fine-tuning MobileNetV2, Export в INT8 quantized — розмір моделі ~2 МБ, inference <50 мс на Snapdragon 778G.
Як реалізувати debounce для зміни сцени?
Розпізнавання сцени — це лише тригер. Далі потрібна логіка автоматизації без хибних спрацьовувань. Патерн: зміна сцени зараховується лише якщо одна категорія домінує 3 секунди поспіль із confidence > 0.7.
class SceneDebouncer(private val windowMs: Long = 3000) {
private var currentScene: String? = null
private var firstSeenAt: Long = 0
fun process(scene: String, confidence: Float): String? {
if (confidence < 0.7f) return null
val now = System.currentTimeMillis()
if (scene != currentScene) {
currentScene = scene
firstSeenAt = now
return null
}
return if (now - firstSeenAt >= windowMs) scene else null
}
}
Як керувати IoT через MQTT або Matter?
Після підтвердження сцени публікуємо команду в MQTT-брокер або надсилаємо через Matter controller:
// MQTT
mqttClient.publish(
"home/automation/scene",
MqttMessage("""{\"scene\":\"bedroom\",\"timestamp\":${System.currentTimeMillis()}}""".toByteArray()),
qos = 1,
retained = false
)
// Matter SDK (через Google Home Mobile SDK)
val deviceController = ChipDeviceController()
deviceController.sendCommand(
nodeId = lightbulbNodeId,
endpointId = 1,
clusterId = OnOffCluster.CLUSTER_ID,
commandId = OnOffCluster.Commands.On.ID,
tlvData = byteArrayOf()
)
Розклад і контекст
Автоматизація за сценою повинна враховувати час доби: "bedroom" о 23:00 → приглушити світло, "bedroom" о 7:00 → розбудити штори. Контекст додається через TimeOfDay фільтр у правилах на рівні додатка.
Порівняння CoreML vs TFLite
| Параметр | CoreML (iOS) | TFLite (Android) |
|---|---|---|
| Вбудована модель | VNClassifyImageRequest (3000+ класів) | ML Kit Scene Detection (5+ класів) |
| Донавчання | Create ML (MobileNetV3) | TensorFlow Model Maker (MobileNetV2) |
| Розмір кастомної моделі | ~4 MB | ~2 MB (INT8 quantized) |
| Inference time | <30 ms (Apple A14+) | <50 ms (Snapdragon 778G) |
| Приватність | Повністю локально | Повністю локально |
CoreML на 40% швидший на порівнянних пристроях, але TFLite дає більшу гнучкість при кросплатформній розробці.
Покрокова інструкція з інтеграції розпізнавання сцен
- Визначте цільові сцени (наприклад, "bedroom", "kitchen") та IoT-пристрої.
- Виберіть платформу: CoreML для iOS, TFLite для Android або загальний Flutter/RN.
- Інтегруйте ML-модель та налаштуйте локальний класифікатор.
- Реалізуйте debounce-логіку для уникнення хибних спрацьовувань.
- Підключіть MQTT або Matter для відправки команд.
- Протестуйте при різних умовах освітлення та кутах камери.
Детальніше про кастомні моделі
Для донавчання моделі використовуйте Transfer Learning: заморозьте перші шари MobileNetV2/V3, додайте голову під свої класи. На кожну сцену потрібно 200–500 розмічених кадрів. Оптимізація через Quantization Aware Training зменшує модель у 2 рази без втрати точності.
Чому приватність важлива при використанні камери розумного дому?
Додаток із постійним доступом до камери — червоний прапор для користувачів і модераторів App Store/Google Play. Правила:
- Класифікація лише коли користувач явно ввімкнув режим «Scene Detection»
- Жодні кадри не зберігаються і не покидають пристрій
- На iOS —
NSCameraUsageDescriptionіз явним поясненням локальної обробки - Privacy manifest в iOS 17+ з декларацією
NSPrivacyAccessedAPICategoryCamera
App Store reject по 4.3 Spam або privacy violations — реальний ризик. Опис в App Privacy Report має бути чесним.
Що входить у розробку
- Аудит вимог: цільові пристрої, IoT-протоколи (MQTT, Matter, Zigbee через хаб, HomeKit), набір тригерних сцен.
- Розробка моделі класифікації: вбудована або кастомна з донавчанням.
- Інтеграція з MQTT-брокером або Matter SDK.
- Реалізація логіки debounce та автоматизації.
- Тестування в реальних умовах — різне освітлення, кути камери, змішані сцени.
- Документація та передача вихідного коду.
- Підтримка після запуску.
Гарантуємо надійність та стабільність рішення, що базується на багаторічному досвіді. Вартість розраховується індивідуально, але ми гарантуємо прозорий бюджет без прихованих платежів.
Етапи та терміни
| Етап | Термін |
|---|---|
| Аудит та узгодження ТЗ | 3–5 днів |
| Розробка моделі (вбудована) | 1–2 тижні |
| Інтеграція з IoT-протоколом | 1–3 тижні |
| Логіка автоматизації та тестування | 1–2 тижні |
| Повний цикл із кастомною ML-моделлю | 2–3 місяці |
Базове розпізнавання з 5–10 сценами та MQTT-командами: 2–4 тижні. Кастомна ML-модель із донавчанням + повна інтеграція з Matter/HomeKit: 2–3 місяці. Вартість розраховується індивідуально, залежно від кількості підтримуваних IoT-протоколів та складності логіки автоматизації.
Замовте розробку під ключ — ми оцінимо ваш проєкт за 1 день і запропонуємо оптимальне рішення. Зв'яжіться з нами, щоб обговорити деталі.







