Услуги Кейсы Подход Обо мне Обсудить задачу
← Все кейсы
Машинное зрениеALPROpenCVArUco

Своё распознавание номеров на весовой — без единой лицензии

Раньше номер въезжающей машины на весовой вбивал оператор вручную. Собственный сервис читает номер с камеры в реальном времени, а тракторы без читаемых номеров — по ArUco-меткам.

2
камеры — единственная реальная закупка под проект
0
лицензий, подписок и облачных сервисов распознавания
10
единиц техники промаркировано ArUco-метками

01 — Почему не купили готовоеДве категории транспорта — и у каждой свои сложности

Задача звучала просто: машина заезжает на весовую, оператор должен как можно быстрее получить её номер, чтобы взвешивание не превращалось в очередь из-за ручного ввода. Готовые коммерческие системы распознавания номеров решают это — но обычно продаются как канал: лицензия на камеру, подписка на облачное распознавание, сервисный контракт. Для одной весовой с двумя камерами это несоразмерно дорого относительно самой задачи.

На весовую заезжают два типа объектов, и коммерческое ALPR-решение «из коробки» хорошо закрывает только один из них:

  • Грузовой транспорт с обычными номерами. Стандартная задача распознавания: камера, ракурс въезда, номер по ГОСТу — то, для чего и делают коммерческие ALPR-системы.
  • Собственная техника — тракторы. Номер часто заляпан, установлен не по ГОСТу, а то и вовсе отсутствует как класс — техника внутри хозяйства идентифицируется по внутреннему инвентарному номеру. Ни одна коробочная система распознавания номеров эту технику надёжно не читает — она её и не должна читать, это не то, для чего ALPR проектировали.

То есть даже купив коммерческую систему, вторую половину задачи — тракторы — всё равно пришлось бы решать отдельно и вручную. Раз одну половину так или иначе пишем сами, логичнее было спроектировать обе сразу как единый сервис.

Итоговое требование

Сервис должен непрерывно смотреть на поток с камеры и в любой момент — по запросу из 1С — мгновенно отдавать последний распознанный номер. Не «сфотографировать и подождать 5 секунд», а уже иметь готовый ответ к моменту, когда оператор нажал кнопку.

02 — Как устроено решениеОдин сервис, два канала распознавания

В основе — небольшой Python-сервис, который в фоновом потоке постоянно читает кадры с камеры по RTSP и разбирает их одним из двух способов в зависимости от того, что на кадре: обычный номер или трактор.

Машины. Для обычных номеров используется связка из двух моделей: одна находит на кадре прямоугольник номерного знака (детектор), вторая читает символы внутри этого прямоугольника (OCR). Обе модели работают локально, без обращения к внешним сервисам — открытая библиотека fast-alpr, работающая поверх OpenCV. Дальше — простая, но обязательная часть: распознанный текст приводится к валидному виду. Модель иногда путает похожие символы — латинскую O и цифру 0, кириллическую В и цифру 8 — и в коде есть отдельная функция, которая раскладывает строку по позициям российского номера и точечно подставляет наиболее вероятный символ на каждую позицию. Результат сверяется с регулярным выражением формата номера — если не совпало, ответу присваивается более низкая уверенность, а не отбрасывается сразу.

Тракторы. Решили не бороться с OCR на грязном металле, а обойти задачу: на кабину каждого трактора наклеен небольшой ArUco-маркер — чёрно-белый квадрат по принципу QR-кода, спроектированный так, чтобы надёжно читаться под углом, в движении и при плохом освещении. Камера видит маркер тем же кадром, что и обычные номера — просто по нему не гоняется OCR, а сразу декодируется числовой ID. Дополнительно заложена проверка по минимальной площади маркера в кадре — это отсекает случайные ложные срабатывания на бликах рифлёного металла весовой площадки.

весовая — lpr_server.py ============================================================ LPR HTTP-сервер v5.1 — ALPR + ArUco тракторы Камера : подключение установлено Интервал : 1.0 сек Тракторов : 10 (ArUco DICT_4X4_50) Режим : локальный (fast-alpr) ============================================================ 14:32:07 INFO Номер распознан: Н030ТВ32 conf=1.84 source=alpr 14:32:19 INFO ArUco-метка: ТРАКТОР-07 (id=6) conf=9.9 14:33:02 INFO Номер распознан: К512МР34 conf=1.61 source=alpr 14:33:41 WARN RTSPCapture: соединение потеряно. Повтор через 5 сек. 14:33:47 INFO RTSPCapture: соединение установлено

Скользящее окно — защита от «залипшего» номера. Первая версия логики копила голоса за номер всё время, пока машина стоит в кадре. Трактор, простоявший на взвешивании пять минут, успевал накопить сотни голосов — и когда следующая машина подъезжала практически без паузы, её пара кадров не могла перебить эту накопленную массу. Решение — голосование в скользящем окне фиксированного размера: система помнит не всю историю, а только последние несколько кадров. Как только новый номер занимает большинство слотов в этом окне, он немедленно становится текущим — независимо от того, сколько «веса» набрал предыдущий.

Мост в 1С. Распознавание идёт непрерывно в фоне, а не по запросу — это ключевое архитектурное решение. К моменту, когда оператор нажимает кнопку в 1С, ответ уже готов: 1С делает обычный HTTP-запрос к локальному сервису и мгновенно получает последний зафиксированный номер, без задержки на съёмку и распознавание в моменте.

GET /last?consume=1 { "ok": true, "plate": "Н030ТВ32", "confidence": 1.84, "source": "alpr", "is_tractor": false, "consumed": true }

Параметр consume=1 нужен, чтобы один и тот же номер не был случайно взят в обработку дважды, если оператор нажал кнопку повторно.

03 — НадёжностьRTSP рвётся — сервис не должен падать

Отдельное внимание ушло не на распознавание, а на устойчивость самого видеопотока. IP-камеры периодически теряют соединение, а библиотеки для чтения RTSP иногда «зависают» внутри системного вызова так, что поток не возвращает управление и не бросает исключение. Если в этот момент попытаться закрыть и переоткрыть соединение из другого потока — есть риск уронить процесс целиком без единой строки в трейсбеке.

Поэтому чтение кадра выполняется с явным таймаутом в отдельном потоке-наблюдателе: если чтение не укладывается в отведённое время, зависший объект соединения просто помечается как потерянный и больше не трогается — сервис открывает новое соединение, а старое безопасно освобождается сборщиком мусора. Это на порядок скучнее, чем логика распознавания, но именно от таких деталей зависит, будет ли сервис работать месяцами без перезапуска вручную.

04 — Во что это обошлосьЕдинственная статья расходов — сами камеры

Всё программное обеспечение в решении — открытые библиотеки без коммерческих лицензий: OpenCV для работы с видео, открытые модели детекции и распознавания номеров, библиотека ArUco для маркеров. Сервис работает локально, на обычном сервере — облачное распознавание не используется, а значит нет и оплаты по числу запросов или подписки на канал камеры, как это устроено у большинства коммерческих ALPR-провайдеров.

СтатьяКоммерческое ALPR-решениеСвоё решение
Лицензия на канал распознаванияобычно да, помесячно или за каналнет
Идентификация тракторов без читаемых номеровне решает — отдельная задачазакрыта тем же сервисом (ArUco)
Оборудованиекамеры + иногда специальный контроллертолько камеры
Зависимость от облакачасто требуетсянет, всё локально

Это не значит, что самописное решение — всегда правильный выбор. Там, где нужны десятки камер на разных объектах, круглосуточная поддержка вендора или юридически значимая фиксация нарушений, коммерческая система со своей инфраструктурой и SLA может окупиться быстрее, чем содержание своей разработки. Но для одной весовой с понятным, стабильным ракурсом и известным составом техники — задача оказалась по силам одному разработчику за счёт открытых компонентов, без покупки готового продукта под неё.

05 — ИтогКогда такой подход имеет смысл

Подход себя оправдывает там, где условия съёмки предсказуемы (фиксированная камера, известный ракурс, ограниченный и понятный состав объектов), а интеграция с учётной системой — простая по протоколу, но критичная по задержке. В таких рамках написать собственный сервис на открытых компонентах часто дешевле и гибче, чем встраивать в процесс внешний коммерческий продукт целиком.

Похожая задача на вашем производстве?

Если данные уже собираются, но не связаны между собой в реальном времени — разберём, что можно сделать без покупки отдельного продукта под задачу.

Обсудить задачу →