Реализация AI-распознавания растений по фотографии в мобильном приложении
Пользователь фотографирует незнакомый цветок в парке и через секунду видит название, описание и предупреждение о токсичности. Технически задача несложная — у PlantNet API и Google Cloud Vision есть готовые endpoints. Но разница между «работает в демо» и «работает в продакшн» обычно скрывается в обработке плохих фото и UX при низкой уверенности модели.
Варианты реализации
Два пути: облачное API или on-device модель.
Облачные API (PlantNet, iNaturalist, Plant.id) дают высокую точность и регулярно обновляемую базу (PlantNet — 30 000+ видов). Плата — интернет-зависимость и задержка 1–3 секунды. Для большинства приложений это приемлемо.
On-device через CoreML (iOS) или TensorFlow Lite (Android) — работает офлайн, мгновенный отклик, но модель нужно обновлять через OTA, а точность на редких видах заметно ниже. Размер модели EfficientNet-B4, дообученной на PlantCLEF датасете — около 20 МБ в формате .mlmodel.
Для большинства проектов оптимально: CoreML/TFLite для быстрого офлайн-результата (топ-3 кандидата) + облако для уточнения при наличии сети.
Как работает интеграция с Plant.id API
struct PlantIdentificationService {
func identify(image: UIImage) async throws -> [PlantMatch] {
guard let imageData = image.jpegData(compressionQuality: 0.8) else {
throw PlantError.invalidImage
}
let base64 = imageData.base64EncodedString()
let request = PlantIdentifyRequest(
images: [base64],
modifiers: ["crops_fast", "similar_images"],
plant_language: "ru",
plant_details: ["common_names", "url", "description",
"taxonomy", "edible_parts", "toxicity"]
)
let response = try await apiClient.post("/identify", body: request)
return response.suggestions
.filter { $0.probability >= 0.1 } // отфильтровать очень слабые совпадения
.prefix(5)
.map { PlantMatch(from: $0) }
}
}
Поле toxicity — важно. Для приложений с аудиторией родителей или грибников предупреждение о токсичности должно быть визуально выделено — не пятым пунктом в списке деталей.
Обработка плохого фото
Частая причина плохих результатов — размытый снимок, неудачный ракурс (только стебель без листьев/цветка), тёмный фон. Детектировать это нужно до запроса в API:
func assessImageQuality(_ image: UIImage) -> ImageQualityResult {
// Blurriness через Laplacian variance
let laplacianVariance = computeLaplacianVariance(image)
if laplacianVariance < 50 {
return .tooBlurry
}
// Проверка, что в кадре есть растение — через CoreML Vision classifier
let plantPresenceScore = runPlantPresenceClassifier(image)
if plantPresenceScore < 0.3 {
return .noPlantDetected
}
return .acceptable
}
При tooBlurry — сразу просим переснять, не тратим API-запрос.
Ориентиры по срокам
Интеграция с одним облачным API (Plant.id или PlantNet), обработка результатов, базовый UI с карточками растений — 1–2 дня. Добавление on-device модели, обработки качества изображения, истории распознаваний, офлайн-режима и поддержки обеих платформ — 1–1.5 недели.







