Реалізація AI-розпізнавання номерних знаків (ANPR/LPR) у мобільному застосунку

TRUETECH займається розробкою, підтримкою та обслуговуванням мобільних додатків iOS, Android, PWA. Маємо великий досвід та експертизу для публікації мобільних додатків до популярних маркетів Google Play, App Store, Amazon, AppGallery та інші.

Розробка та підтримка будь-яких видів мобільних додатків:

Інформаційні та розважальні мобільні програми
Новинки, ігри, довідники, онлайн-каталоги, погодні, фітнес та здоров'я, туристичні, освітні, соціальні мережі та месенджери, квіз, блоги та подкасти, форуми, агрегатори
Мобільні програми електронної комерції
Інтернет-магазини, B2B-додатки, маркетплейси, онлайн-обмінники, кешбек-сервіси, біржі, дропшиппінг-платформи, програми лояльності, доставка їжі та товарів, платіжні системи
Мобільні програми для управління бізнес-процесами
CRM-системи, ERP-системи, управління проектами, інструменти для команди продажів, облік фінансів, управління виробництвом, логістика та доставка, управління персоналом, системи моніторингу даних
Мобільні програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, платформи надання електронних послуг, платформи кешбеку, відеохостинги, тематичні портали, платформи онлайн-бронювання та запису, платформи онлайн-торгівлі

Це лише деякі з типів мобільних додатків, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1735 послуг
Реалізація AI-розпізнавання номерних знаків (ANPR/LPR) у мобільному застосунку
Складний
~1-2 тижні
Часті запитання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_mobile-applications_feedme_467_0.webp
    Розробка мобільного додатка для компанії FEEDME
    792
  • image_mobile-applications_xoomer_471_0.webp
    Розробка мобільного додатку для компанії XOOMER
    671
  • image_mobile-applications_rhl_428_0.webp
    Розробка мобільного додатку для компанії RHL
    1097
  • image_mobile-applications_zippy_411_0.webp
    Розробка мобільного додатку для компанії ZIPPY
    969
  • image_mobile-applications_affhome_429_0.webp
    Розробка мобільного додатку для компанії Affhome
    914
  • image_mobile-applications_flavors_409_0.webp
    Розробка мобільного додатку для компанії FLAVORS
    495

ANPR/LPR Розпізнавання номерних знаків у мобільних застосунках

ANPR (Automatic Number Plate Recognition) на мобільному пристрою—зріла задача з зрозумілими інструментами. Основна інженерна проблема не в самому OCR, а в конвеєрі від захоплення кадру до надійного прочитаного номера: детекція пластини в реальних умовах (ніч, брудь, відблиски, нестандартні шрифти СНД).

Вибір підходу

Два шляхи в залежності від вимог:

On-device—для задач з високою частотою сканувань (паркінг, пропускний пункт) або без гарантованого інтернету. Моделі: OpenALPR (open source, підтримує 60+ країн, включаючи RU/BY/UA), Plate Recognizer Edge SDK, Google ML Kit Text Recognition v2 (для простих стандартних номерів).

Cloud API—Plate Recognizer API, OpenALPR Cloud, AWS Rekognition. Точніші на складних кейсах (нестандартний кут, нечіткий шрифт), краще справляються з різними регіонами СНД.

// iOS: on-device ANPR через Vision + кастомна YOLOv8 для детекції пластини
class LicensePlateRecognizer {

    // Крок 1: детекція пластини через CoreML (YOLOv8n—швидкий варіант)
    private let plateDetector: VNCoreMLModel

    // Крок 2: OCR через Vision Text Recognition
    private func recognizeText(in croppedImage: CGImage,
                               completion: @escaping (String?) -> Void) {
        let request = VNRecognizeTextRequest { request, _ in
            let text = (request.results as? [VNRecognizedTextObservation])?
                .compactMap { $0.topCandidates(1).first?.string }
                .joined()
            completion(text)
        }
        request.recognitionLevel = .accurate
        request.usesLanguageCorrection = false  // відключити—номери не слова
        request.minimumTextHeight = 0.1

        try? VNImageRequestHandler(cgImage: croppedImage).perform([request])
    }

    func recognize(sampleBuffer: CMSampleBuffer) async -> PlateResult? {
        guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return nil }

        // Детектуємо пластину
        let plateBBox = await detectPlate(in: pixelBuffer)
        guard let bbox = plateBBox else { return nil }

        // Crop та OCR
        let croppedCGImage = cropCGImage(pixelBuffer: pixelBuffer, rect: bbox)
        let rawText = await recognizeTextAsync(croppedCGImage)

        // Нормалізація й валідація
        return normalizePlate(rawText)
    }
}

Нормалізація номерів СНД

OCR дає сирий текст. Для СНД-номерів важлива постобробка:

struct PlateNormalizer {

    // Заміна візуально подібних символів (типові помилки OCR)
    static let ocrCorrections: [Character: Character] = [
        "0": "O",   // іноді навпаки
        "1": "I",
        "8": "B",
    ]

    // Паттерни для різних країн
    static let patterns: [(country: String, regex: String)] = [
        ("RU", #"^[АВЕКМНОРСТУХ]{1}\d{3}[АВЕКМНОРСТУХ]{2}\d{2,3}$"#),
        ("BY", #"^\d{4}[ABCEHIKMOPTX]{2}-\d{1}$"#),
        ("UA", #"^[АВСЕКМНРОТХBCEKMNOPTX]{2}\d{4}[АВСЕКМНРОТХBCEKMNOPTX]{2}$"#),
        ("KZ", #"^\d{3}[A-Z]{3}\d{2}$"#)
    ]

    func normalize(_ rawText: String) -> PlateResult? {
        let cleaned = rawText.uppercased()
            .replacingOccurrences(of: " ", with: "")
            .replacingOccurrences(of: "-", with: "")

        for (country, pattern) in Self.patterns {
            if cleaned.range(of: pattern, options: .regularExpression) != nil {
                return PlateResult(text: cleaned, country: country, confidence: .high)
            }
        }

        // Не совпало з паттернами—low confidence, повернути як є
        return PlateResult(text: cleaned, country: nil, confidence: .low)
    }
}

Режим безперервного відеопотоку

Для паркінгу або КПП—безперервне сканування кадрів без натиску кнопки:

// Android: CameraX + безперервний аналіз через ImageAnalysis
class ContinuousPlateAnalyzer(
    private val onPlateDetected: (PlateResult) -> Unit
) : ImageAnalysis.Analyzer {

    private val frameThrottler = FrameThrottler(maxFps = 5) // 5 кадрів/сек достатньо
    private val consecutiveMatchThreshold = 3               // 3 підряд однакових

    private val recentResults = ArrayDeque<String>(maxOf = 5)

    override fun analyze(image: ImageProxy) {
        if (!frameThrottler.shouldProcess()) { image.close(); return }

        val bitmap = image.toBitmap()
        val result = plateRecognizer.recognize(bitmap)
        image.close()

        result?.let { plate ->
            recentResults.add(plate.text)
            if (recentResults.size >= consecutiveMatchThreshold &&
                recentResults.takeLast(consecutiveMatchThreshold).all { it == plate.text }) {
                onPlateDetected(plate)
                recentResults.clear()
            }
        }
    }
}

Поріг 3 послідовних однакових результатів усуває ложні спрацьовування на випадкових об'єктах, схожих на пластину.

Орієнтири за часом

On-device ANPR з Vision/ML Kit, нормалізацією для однієї країни й базовим UI—3–5 днів. Мультистрановая система з підтримкою RU/BY/UA/KZ, безперервним відеоаналізом, історією сканувань, інтеграцією з зовнішньою базою (база угнаних авто, база клієнтів) й iOS + Android—1–2 тижні.