Как мы учили камеры видеть парковку
Эта часть TPS Gate не поместилась на страницу проекта. Мы сами собирали датасеты, обучили детектор белорусских номеров, сделали устройство распознавания на Raspberry Pi и сервис, который по обычным камерам считает свободные места.
- Период
- С 2014 по 2020 год
- Номер на въезде
- PR1: Raspberry Pi и IP-камера
- Свободные места
- PR 2.0: камеры и нейросеть на GPU
- Первый датасет
- 982 снимка, осень 2014
- Детектор номеров
- Свой, для номеров Беларуси
- Где работало
- Минск, пилот в Вильнюсе


Коротко
Распознавание было отдельным большим направлением, а не надстройкой над шлагбаумами. Начали около 2013 года. Первый датасет я собрал осенью 2014-го: ездил по парковкам с камерой в машине и снимал номера.
К 2019 году у нас было два продукта. PR1 стоит у шлагбаума: Raspberry Pi с камерой находит номер и передаёт его контроллеру. PR 2.0 по обычным камерам парковки считает свободные места и показывает их на карте в приложении.
Готового детектора для белорусских номеров не было, поэтому мы обучили свой: 3 430 примеров номеров и 8 404 снимка без них. Команда обучения сохранилась внутри устройства. Машины на кадрах находила нейросеть, которую мы обучали на своих серверах с GPU.
Не сверено: точность в реальной работе. В требованиях стояла цель от 90 до 95% по числу мест, в презентации декабря 2019 года: не ниже 95%. Замеров в архиве я не нашёл.
- 982снимка номеров за 16 дней, 2014
- 3 430номеров в обучении детектора
- 200камер на сервер: цель PR 2.0
- 10парковок в Минске, декабрь 2019
Датасет, который я собрал сам
Осень 2014 года, Минск.
Готовых наборов белорусских номеров не было. Поэтому я закрепил камеру в машине и поехал по парковкам.
Съёмка заняла 16 дней, с 21 октября по 6 ноября 2014 года: 982 кадра на Nikon D5100, почти 6 ГБ. Парковки у торговых центров, дворы, стоянки у офисов. На многих кадрах видна стойка лобового стекла: снимал прямо из машины.
Из таких снимков собирают обучающую выборку: на них отмечают, где номер, а где фон, и на этом учится детектор.


Как это было устроено
Два продукта на одной платформе.
Схему можно листать вбок.
PR1: номер на въезде
Устройство у шлагбаума, 2019.
PR1 ставился у шлагбаума вместе с IP-камерой. Он узнавал номер подъезжающей машины и передавал его контроллеру PMCN. Контроллер открывал проезд, если номер был в списке.
- Железо. Raspberry Pi на Raspbian. Образ системы от 11 мая 2019 года сохранился в архиве, версия нашего ПО 01.03.01.
- Распознавание. Кадры с камеры забирает ffmpeg, номер ищет OpenALPR, открытая библиотека распознавания номеров. Своего региона для Беларуси в ней не было, поэтому мы добавили регион «by»: собственный детектор и настройки под размеры и формат белорусских номеров.
- Скорость. Номер распознавался прямо на устройстве, без отправки кадров на сервер, примерно за 0,3 секунды. На Raspberry Pi мы смогли запустить и нашу нейросеть.
- Наш код. На Python: разбор результатов, журнал на флешке, отправка номера и фото на сервер, сторож процессов. Если что-то падает, сервис перезапускается сам.
- Связь с контроллером. По UART, на своём протоколе с канальным, сетевым и прикладным уровнями. Контрольная сумма такая же, как во всей системе: CRC16.
- Сервер. Сравнивает номер с допуском на ошибки распознавания, отбрасывает повторы в течение заданного времени, умеет пускать гостей по номеру.
Как обучали детектор
Внутри образа PR1 сохранилась команда, которой обучали детектор белорусских номеров:
opencv_traincascade -data …/PlateDetector/OpenAlpr/train-detector-master/out -vec …/positive/vecfile.vec -bg …/negative/negative.txt -w 68 -h 15 -numPos 3430 -numNeg 8404 -featureType LBP -numStages 12 -minHitRate 0.9999 -maxFalseAlarmRate 0.3
3 430 примеров номеров, 8 404 снимка без номеров, 12 стадий, признаки LBP. Такой детектор быстро работает на слабом процессоре, поэтому его можно было запускать прямо на Raspberry Pi.
plate_width_mm = 480 plate_height_mm = 110 char_height_mm = 80 postprocess_min_characters = 5 postprocess_max_characters = 8 detector_file = by.xml ocr_language = leu

PR 2.0: свободные места
Видеоаналитика по камерам, 2019.
Вторая задача: понять, сколько на парковке свободных мест, не ставя датчик на каждое место. Мы подключались к камерам, которые уже висят на объекте, и считали места по кадрам.
Это было нужно для двух вещей: подсказывать водителям, где свободно, и считать цену в зависимости от загрузки, то есть для динамического ценообразования. Требования мы записали в апреле 2019 года:
- данные обновляются с интервалом от 15 до 60 секунд;
- число свободных мест определяется с точностью от 90 до 95%;
- до 200 камер на один сервер;
- алгоритм можно перенести на Raspberry Pi или похожий контроллер;
- несколько камер на одной парковке с перекрытием кадров;
- разметка на каждой камере: дорога, недоступные зоны, места для парковки;
- архив кадров до 6 месяцев с шагом в минуту, тепловая карта и подсказка водителю, где искать место.
Сервис делился на две части. Менеджер принимает кадры с камер, хранит их и держит разметку. Модуль распознавания получает кадр с настройками камеры и возвращает, где стоят машины. Результат идёт на основной сервер, а оттуда в приложение и на табло.




Нейросети и серверы
Своё обучение на своём железе.
Машины на кадрах находила нейросеть. Мы обучали такие сети сами, на своих серверах с GPU: разбирались, как их строить, как обучать и как собирать для них данные.
Для обучения нужны были большие парковки, снятые сверху. В августе 2019 года мы снимали с высоты парковку у офиса EPAM: больше сотни кадров на тот же Nikon D5100. Два таких кадра открывают эту страницу.


В архитектуре ParkMyCarNow под это был отдельный блок: серверы видеоаналитики на GPU рядом с основными серверами платформы.
Как именно была устроена сеть, я сейчас не вспомню, а модели и код обучения в архиве не сохранились: они остались на серверах команды. Помню главное: сеть работала очень хорошо, и мы смогли запустить её прямо на Raspberry Pi.
Что из этого вышло
По документам с 2019 по 2021 год и по моей памяти.
- Октябрь 2019: первая парковка в Вильнюсе.
- Декабрь 2019: 10 парковок в Минске, пилот в Литве, проект с администрацией Вильнюса.
- Отдельный продукт: видеоаналитика по любым уличным камерам: поиск свободных мест и фиксация нарушений правил парковки.
- Данные для города: сколько стоит машина и где есть свободные места. Администрации Вильнюса и Каунаса были готовы покупать такие данные, чтобы управлять трафиком и тарифами.
- Велогараж: пилот с солнечными панелями на движке ParkMyCarNow. Наш контроллер, наша камера и полный комплект управления. Работали платежи и динамическое ценообразование.
- 2021 год: PR1 с камерой входил в комплект, который мы предлагали производителям шлагбаумов.
В архиве есть и неудачи: отдельные папки «не распознан» и «проблемы камер». По ним можно восстановить, где система ошибалась.


Всё это действительно работало. Но законченный продукт для продажи мы так и не собрали: пошли вширь, пытаясь решить все задачи клиентов сразу. Мой вывод: реальные задачи решаются только с фокусом. Подробнее в истории TPS Gate Europe.
Что это значит сейчас
Для TPS Gate Europe.
- Номера и GDPR. В Европе номер машины обычно считается персональными данными. Для распознавания номеров на въезде нужны правовое основание и оценка рисков по GDPR.
- Места без номеров. Свободные места можно считать, вообще не читая номера: сети достаточно видеть машины. Для развилок про распределение мест и велопарковки это главный задел.
- Код не переносится, опыт переносится. Сегодня такие задачи решают современные открытые модели, поэтому код 2019 года переносить нет смысла. Ценность архива в данных, требованиях и опыте эксплуатации на реальных парковках.
Источники в архиве
Что лежит за каждым фактом.
- Датасет номеров, октябрь и ноябрь 2014: 982 кадра с метаданными камеры.
- Образ системы PR1 от 11 мая 2019: ПО версии 01.03.01, регион «by», команда обучения детектора.
- Требования к PR 2.0, апрель 2019.
- Кадры камер и скриншоты PR 2.0 с апреля по июнь 2019; съёмка парковки сверху, август 2019.
- Материалы для EPAM с архитектурой и результатами сети, октябрь 2019.
- Презентации ParkMyCarNow с 2019 по 2021 год и черновик статьи для dev.by, декабрь 2019.
- Серверный код платформы ParkMyCar с 2016 по 2020 год: приём распознанных номеров и подсчёт мест.