Водій паркується, камера зчитує номер, але система видає «О00Р777» замість «О 777 РР 777» — така ситуація знайома багатьом. Ми стикаємося з такими кейсами регулярно і знаємо, як перетворити сирий OCR-вивід на надійний результат. ANPR (Automatic Number Plate Recognition) на мобільному пристрої — зріла задача, але ключова інженерна проблема не в самому OCR, а в pipeline: від захоплення кадру до валідованого номера. Ніч, бруд, відблиски, нестандартні шрифти СНД — кожен фактор потребує окремої обробки. Ми розробляємо ANPR-рішення під ключ для iOS та Android, використовуючи сучасні моделі комп'ютерного зору. Наш багаторічний досвід у відеоаналітиці гарантує стабільну роботу навіть у складних умовах. Оцінимо ваш проект та запропонуємо оптимальний підхід — on-device, хмарний або гібридний. Замовте попередню оцінку вашого проекту.
Як досягти точності розпізнавання в складних умовах?
Вибір підходу залежить від вимог до швидкості, автономності та точності. Порівняємо два основні варіанти:
| Критерій | On-device (CoreML / ML Kit) | Cloud API (OpenALPR / AWS) |
|---|---|---|
| Затримка | <50 мс | 200–800 мс + мережа |
| Автономність | Повна | Потрібен інтернет |
| Точність на складних номерах | 85–92% | 93–97% |
| Вартість експлуатації | Безкоштовно після розробки | Залежить від обсягу запитів |
Для паркінгів і КПП з високою частотою сканувань ми рекомендуємо on-device. Якщо потрібна максимальна точність (наприклад, для верифікації на в'їзді) — використовуємо хмарний fallback.
On-device ANPR: стек та приклад
На iOS використовуємо Vision + кастомну YOLOv8 для детекції пластини. Модель навчена на датасетах з номерами СНД. Приклад коду вже показано вище — він включає детекцію, crop та OCR.
import Vision import CoreML let detectionRequest = VNCoreMLRequest(model: try VNCoreMLModel(for: YOLOv8(configuration: MLModelConfiguration()).model)) { request, error in guard let results = request.results as? [VNRecognizedObjectObservation] else { return } for result in results { let plateRect = result.boundingBox // Crop and run OCR let ocrRequest = VNRecognizeTextRequest { ocrRequest, error in guard let ocrResults = ocrRequest.results as? [VNRecognizedTextObservation] else { return } let plateNumber = ocrResults.compactMap { $0.topCandidates(1).first?.string }.joined() let normalized = normalizePlate(plateNumber) print("Detected: \(normalized)") } ocrRequest.recognitionLevel = .accurate // ... process cropping from plateRect } } На Android використовуємо CameraX + ML Kit Object Detection та Text Recognition:
val detector = ObjectDetector.create(context, objectDetectorOptions) val ocr = TextRecognition.getClient(TextRecognizerOptions.DEFAULT_OPTIONS) cameraView.cameraController.imageAnalysis.setAnalyzer(executor) { image -> val detectionResults = detector.detect(image) for (detected in detectionResults) { val plateRect = detected.boundingBox // Crop region and run OCR val inputImage = InputImage.fromBitmap(croppedBitmap, 0) ocr.process(inputImage).addOnSuccessListener { ocrResult -> val plateNumber = ocrResult.text.trim() val normalized = normalizePlate(plateNumber) Log.d("ANPR", "Detected: $normalized") } } } Нормалізація номерів СНД
OCR дає сирий текст. Для номерів СНД обов'язкова постобробка: заміна візуально схожих символів (0→O, 1→I, 8→B) та перевірка за регулярними виразами для кожної країни. Ми підготували нормалізатор для RU, BY, UA, KZ. Якщо номер не пройшов жоден патерн — повертаємо низьку впевненість.
Що робити, якщо номер не пройшов валідацію?
У режимі безперервного сканування (наприклад, для КПП) ми використовуємо кадровий фільтр: 3 послідовних однакових результати — тільки тоді вважаємо номер валідним. Це знижує хибні спрацьовування на випадкових об'єктах, схожих на пластину. Реалізація на Android з CameraX показана у вихідному коді.
Чому on-device ANPR вигідніше хмарного?
On-device обробка виконується за <50 мс, що в 4–10 разів швидше за хмарний запит. Повна автономність виключає залежність від мережі та витрати на серверні ресурси. При цьому точність on-device моделей (сертифіковані рішення) досягає 92–96% на чистих кадрах, а з хмарним fallback — до 97%. Це робить on-device ANPR ідеальним для масштабних розгортань з високим навантаженням.
Типові етапи впровадження ANPR
| Етап | Опис | Термін |
|---|---|---|
| Аналіз вимог | Збір даних, визначення регіону номерів | 1 день |
| Розробка детекції | Навчання або адаптація YOLO | 2–3 дні |
| OCR та нормалізація | Інтеграція OCR, написання правил | 1–2 дні |
| Інтеграція та тестування | Впровадження в додаток, регресійне тестування | 1–2 дні |
Що входить в роботу
- Архітектура ANPR-модуля: вибір моделі, pipeline, нормалізація
- Реалізація детекції та OCR для iOS та/або Android
- Підтримка номерів до 5 країн (розширюється)
- Інтеграція з вашою базою через REST API
- Тестування на реальних відеопотоках (нічний режим, дощ, сніг)
- Документація та інструкція з експлуатації
- Післягарантійна підтримка
Типові помилки при впровадженні ANPR
- Нехтування нормалізацією: OCR бачить «0» замість «O» — результат не сходиться з БД
- Надто висока частота кадрів: 30 FPS марні, навантаження на процесор зростає, а точність не збільшується. Оптимум — 5 кадрів/с
- Відсутність фільтрації шумів: один неправильний кадр може заблокувати в'їзд
- Ігнорування регіональних особливостей: у Казахстані номер складається з цифр та латиниці, а в Росії — з кирилиці та цифр
Орієнтири за термінами
Базова on-device реалізація для однієї країни — 3–5 днів. Повноцінна багатокраїнна система з безперервним відеоаналізом та інтеграцією — 1–2 тижні. Зв'яжіться з нами для точної оцінки. Ми на ринку більше 10 років, реалізували 40+ проектів з відеоаналітикою — знаємо, як уникнути підводних каменів. Гарантуємо якість на всіх етапах.
Більше інформації про ANPR можна знайти в Wikipedia.







