Реализация AI-классификации фотографий в галерее мобильного приложения

TRUETECH занимается разработкой, поддержкой и обслуживанием мобильных приложений iOS, Android, PWA. Имеем большой опыт и экспертизу для публикации мобильных приложений в популярные маркеты Google Play, App Store, Amazon, AppGallery и другие.
Разработка и поддержка любых видов мобильных приложений:
Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

Это лишь некоторые из типы мобильных приложений, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента.

Предлагаемые услуги
Показано 1 из 1 услугВсе 1735 услуг
Реализация AI-классификации фотографий в галерее мобильного приложения
Средняя
~5 рабочих дней
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    756
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    624
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1054
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    874
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    445

Реализация AI-классификации фотографий в галерее мобильного приложения

Классификация фотографий в галерее — это одна из немногих AI-задач, где on-device обработка является стандартом, а не исключением. Apple Photos, Google Photos — оба используют on-device ML. Загружать личные фото пользователей на сервер ради классификации — это технически избыточно и неправильно с точки зрения приватности.

On-device классификация: что доступно из коробки

На iOS работает Vision framework с VNClassifyImageRequest. Не нужны сторонние модели — встроенная классификация покрывает 1000+ категорий:

import Vision

func classifyPhoto(cgImage: CGImage, completion: @escaping ([String]) -> Void) {
    let request = VNClassifyImageRequest { request, error in
        guard let results = request.results as? [VNClassificationObservation] else { return }
        // Берём категории с confidence > 0.5
        let labels = results
            .filter { $0.confidence > 0.5 }
            .map { $0.identifier }
        completion(labels)
    }
    try? VNImageRequestHandler(cgImage: cgImage, options: [:]).perform([request])
}

Время инференса — 5–15 ms на фото в зависимости от устройства. На iPhone 13+ Neural Engine обрабатывает всю галерею в 1000 фото за ~15–20 секунд фоновой задачи.

На Android: ML Kit ImageLabeler с ImageLabelerOptions:

val labeler = ImageLabeling.getClient(
    ImageLabelerOptions.Builder()
        .setConfidenceThreshold(0.5f)
        .build()
)

labeler.process(InputImage.fromBitmap(bitmap, 0))
    .addOnSuccessListener { labels ->
        val categories = labels.map { it.text }
        // "Dog", "Outdoor", "Sky", "Food", etc.
    }

ML Kit поддерживает 400+ категорий на устройстве без сети.

Обработка всей галереи: PHFetchResult и батчинг

Проблема: галерея может содержать 50 000+ фотографий. Обходить их все сразу — заблокируем main thread и убьём батарею.

Правильный подход: PHFetchResult + инкрементальная обработка через DispatchQueue.global(qos: .background):

func classifyGallery() {
    let fetchOptions = PHFetchOptions()
    fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
    let allPhotos = PHAsset.fetchAssets(with: .image, options: fetchOptions)

    let batchSize = 50
    let processingQueue = DispatchQueue(label: "photo.classification", qos: .background)

    processingQueue.async {
        var offset = 0
        while offset < allPhotos.count {
            let batch = (offset..<min(offset + batchSize, allPhotos.count))
                .map { allPhotos.object(at: $0) }
            self.processBatch(assets: batch)
            offset += batchSize
            Thread.sleep(forTimeInterval: 0.1) // Даём системе отдышаться
        }
    }
}

Thread.sleep(0.1) между батчами критичен — без него CPU throttle через 2–3 минуты и скорость падает в 3–5 раз.

Хранение результатов классификации

Результаты сохраняем локально — не на сервер. Core Data с NSPersistentContainer:

// Entity: PhotoClassification
// Attributes: assetLocalIdentifier (String), labels (Transformable: [String]), classifiedAt (Date)

Индекс на assetLocalIdentifier + индекс на labels для быстрого поиска. При 50k фото таблица весит ~5–10 MB.

При открытии галереи — подтягиваем классификации из локальной БД, отображаем. Новые фото (добавленные после последней сессии) — классифицируем инкрементально через PHPhotoLibraryChangeObserver.

Кастомные категории через CoreML

Встроенный Vision не всегда покрывает нужные категории. Для кастомных (например, «рецепт», «скриншот документа», «чек», «виза») — обучаем CreateML модель:

// CreateML: 5–10 примеров на категорию достаточно для базовой точности
let dataSource = MLImageClassifier.DataSource.labeledDirectories(at: trainingDir)
let model = try MLImageClassifier(trainingData: dataSource)
try model.write(to: modelURL)

Точность на кастомных категориях при 20+ примерах — 85–95%. Модель в CoreML формате — 5–15 MB. Можно доставлять через Core ML Model Deployment без обновления приложения.

Типичные ошибки

Classifying на main thread — самое частое. VNImageRequestHandler.perform выполняется синхронно. Всегда в background queue.

Запрашивать full-resolution для классификации — лишнее. PHAsset requestImage с targetSize: CGSize(width: 224, height: 224) достаточно — это стандартный input для большинства моделей классификации.

Не обновлять классификации при изменении галереиPHPhotoLibraryChangeObserver должен запускать инкрементальную обработку только для новых/изменённых фото.

Сроки

Базовая классификация с Vision + хранение в Core Data — 4–6 дней. Полная реализация с кастомными категориями, инкрементальными обновлениями и быстрым поиском по тегам — 2–3 недели. Стоимость рассчитывается индивидуально.