Research · технический кейс

Как мы учили камеры видеть парковку

Эта часть TPS Gate не поместилась на страницу проекта. Мы сами собирали датасеты, обучили детектор белорусских номеров, сделали устройство распознавания на Raspberry Pi и сервис, который по обычным камерам считает свободные места.

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

Коротко

Распознавание было отдельным большим направлением, а не надстройкой над шлагбаумами. Начали около 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
Откуда фактыИз моего архива: снимки с метаданными камеры, образ системы устройства PR1, требования и презентации с 2018 по 2021 год, серверный код платформы.
Проект целикомКонтроллер, история и что дальше: TPS Gate Europe.

Датасет, который я собрал сам

Осень 2014 года, Минск.

Готовых наборов белорусских номеров не было. Поэтому я закрепил камеру в машине и поехал по парковкам.

Съёмка заняла 16 дней, с 21 октября по 6 ноября 2014 года: 982 кадра на Nikon D5100, почти 6 ГБ. Парковки у торговых центров, дворы, стоянки у офисов. На многих кадрах видна стойка лобового стекла: снимал прямо из машины.

Из таких снимков собирают обучающую выборку: на них отмечают, где номер, а где фон, и на этом учится детектор.

24 уменьшенных кадра датасета 2014 года: машины на парковках, часть снята через лобовое стекло
Фрагменты датасета 2014 года. Снимки нарочно огрублены, чтобы номера нельзя было прочитать.
Кадр из датасета: задняя часть машины на парковке, снято из салона через лобовое стекло
Кадр из датасета: съёмка из машины, 6 ноября 2014. Номера и прохожая размыты.

Как это было устроено

Два продукта на одной платформе.

PR1 узнаёт номер у шлагбаума и передаёт его контроллеру; PR 2.0 по камерам парковки находит машины и считает свободные места Номер на въезде · PR1 обучали сами IP-камера у шлагбаума PR1 · Raspberry Pi ffmpeg → OpenALPR свой детектор номеров BY Контроллер PMCN свой список номеров Шлагбаум открывает реле видео UART реле Сервер ParkMyCar журнал: номер и фото HTTP Свободные места · PR 2.0 Камеры парковки уже на объекте Менеджер PR 2.0 кадры, архив, зоны Нейросеть на GPU находит каждую машину Свободные места приложение водителя LED-табло тепловая карта кадры кадр машины результаты

Схему можно листать вбок.

Ярко-синей рамкой отмечено то, что мы обучали сами. Остальное: готовые компоненты и наш код вокруг них.

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
Файл conf.txt в образе PR1. Пути сокращены.

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
Настройки региона «by»: размеры номера и символов, длина номера, свой детектор. Символы читал стандартный европейский OCR из OpenALPR.
Кадр камеры у шлагбаума: опущенная стрела, тумба привода, за ней двор и машина такси
Кадр из журнала распознавания у шлагбаума, 5 июня 2019. Контакты на стреле и тумбе размыты.

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 года переносить нет смысла. Ценность архива в данных, требованиях и опыте эксплуатации на реальных парковках.

К странице TPS Gate Europe

Источники в архиве

Что лежит за каждым фактом.

  • Датасет номеров, октябрь и ноябрь 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 год: приём распознанных номеров и подсчёт мест.