Реализация детекции объектов в мобильном приложении
Детекция объектов на мобиле — это не только «найти и обвести». Это ещё трекинг между кадрами, корректная проекция bounding box на превью-слой, обработка перекрывающихся детекций и управление производительностью на 30 FPS видеопотоке. Именно последнее чаще всего становится узким местом.
Выбор модели: YOLO vs SSD vs NanoDet
На мобиле работают три основных семейства:
- MobileNet SSD — классика, отлично поддерживается TFLite Task Library и ML Kit. На Pixel 7 — 18–25 ms на 320×320. Точность на COCO: mAP ~23–27.
- YOLOv8n/YOLOv5n — лучший баланс точность/скорость в 2024. После конвертации в TFLite или Core ML — 22–40 ms в зависимости от размера входа. mAP на COCO: 37+.
- NanoDet — для действительно слабых устройств, <10 ms на Snapdragon 665.
Для real-time видео на современных Android-флагманах — YOLOv8n с делегатом GPU. Для офлайн-фото на широком спектре устройств — MobileNet SSD v2.
Bounding box: проекция на камеру
Самая частая визуальная ошибка — bounding box не совпадает с объектом на превью. Причина: модель получает ресайзнутое изображение (например, 320×320), а превью камеры — 1920×1080 с AspectFill или AspectFit. Нужно пересчитать координаты с учётом масштаба и отступов.
На iOS с AVCaptureVideoPreviewLayer:
let converted = previewLayer.layerRectConverted(fromMetadataOutputRect: normalizedRect)
VNDetectedObjectObservation возвращает boundingBox в нормализованных координатах (0..1, y снизу). Перед проекцией на UIKit-координаты нужно инвертировать Y-ось: CGRect(x: box.minX, y: 1 - box.maxY, width: box.width, height: box.height).
На Android с CameraX + ImageAnalysis: результаты детекции в координатах входного изображения, превью — в координатах PreviewView. Используем MappingUtils из ML Kit или считаем трансформацию вручную через матрицу.
Трекинг между кадрами
Детектировать на каждом кадре дорого. Правильный подход: детекция раз в N кадров (обычно каждые 5–10), между кадрами — трекинг через SORT или ByteTrack, либо встроенный VNDetectRectanglesRequest с ObjectTrackerObservation на iOS.
ML Kit Object Detection & Tracking поддерживает трекинг из коробки через .enableMultipleObjects() и .enableClassification(). Каждый трекируемый объект получает стабильный trackingID — это позволяет показывать информацию об объекте без мерцания при потере/появлении в кадре.
NMS (Non-Maximum Suppression) — важный параметр. По умолчанию iouThreshold = 0.5. Если объекты в кадре перекрываются (например, упакованные товары на конвейере), порог нужно снижать до 0.3–0.35. Иначе детектор «склеивает» соседние объекты в один.
Реальный кейс
Приложение для подсчёта количества людей в очереди через статичную камеру (планшет на стойке). YOLOv8n, TFLite, делегат GPU на Android 11+. Проблема: при плотной очереди (>8 человек) детектор пропускал людей в центре — перекрытие выше 60%. Решение: снизили nmsThreshold до 0.3, добавили minDetectionConfidence = 0.4 (вместо 0.5). Количество ложных пропусков упало с 31% до 9%. Дополнительно: дообучили модель на кадрах с перекрытием через Roboflow-датасет.
Сроки
Интеграция готовой детекторной модели с проекцией на превью и NMS-тюнингом — 1–2 недели. Дообучение на кастомных классах + интеграция — 2–3 недели. Стоимость рассчитывается индивидуально.







