Распознавание номера авто github
Распознавание номеров. Практическое пособие. Часть 1
Все начиналось банально — моя компания уже год платила ежемесячно плату за сервис, который умел находить регион с номерными знаками на фото. Эта функция применяется для автоматической зарисовки номера у некоторых клиентов.
И в один прекрасный день МВД Украины открыло доступ к реестру транспортных средств. Теперь по номерному знаку стало возможным проверять некоторую информацию про автомобиль (марку, модель, год выпуска, цвет и т.д. )! Скучная рутина линейного программирования померкла перед новой свехзадачей — считывать номера по всей базе фото и валидировать эти данные с теми, что указывал пользователь. Сами знаете как это бывает «глаза загорелись» — вызов принят, все остальные задачи на время стали скучны и монотонны… Мы принялись за работу и получили неплохие результаты, чем, собственно и решили поделиться с сообществом.
Для справки: на сайт AUTO.RIA.com, в день добавляется около 100 000 фото.
Кто еще распознает
Год назад я изучил этот рынок и оказалось, что работать с номерами стран exUSSR умеет не так уж много сервисов и ПО. Ниже представлен список компаний с которыми мы работали:
Automatic License Plate Recognition
Recognitor
Какие инструменты нужны для распознавания номеров
Нахождение объектов на изображении или в видео-потоке это задача из области компьютерного зрения, которая решается разными подходами, но чаще всего с помощью, так-называемых, сверточных нейронных сетей. Нам нужно найти не просто область на фото в которой встречается искомый объект, но и отделить все его точки от других объектов или фона. Эта разновидность задач называется «Instance Segmentation». На иллюстрации ниже визуализированы разные типы задач компьютерного зрения.
Я не буду сейчас писать много теории о том как работает сверточная сеть, этой информации достаточно в сети и докладов на youtube.
Из современных архитектур сверточных серей для задач сегментации часто используют: U-Net или Mask R-CNN. Мы выбрали Mask R-CNN.
Второй инструмент, который нам понадобится — это библиотека по распознаванию текстов, которая бы могла работать с разными языками и которую можно легко настраивать под специфику текстов, которые мы будем распознавать. Тут выбор не так уж велик, самой продвинутой является tesseract от Google.
Так же есть ряд менее «глобальных» инструментов, с помощью которых нам нужно будет нормализовать область с номерным знаком (привести его в такой вид, при котором распознавание текста будет возможным). Обычно для таких преобразований используют opencv.
Так же, можно будет попробовать определить страну и тип, к которой относится найденный номерной знак, чтоб в постобработке применить уточняющий шаблон, характерный для этой страны и этого типа номера. Например, украинский номерной знак, начиная с 2015 года оформлен в сине-желтом оформлении состоит из шаблона «две буквы черыре цифры две буквы».
Кроме того, имея статистику частоты «встречания» в номерных знаках того или иного сочетания букв или цифр можно улучшить качество постобработки в «спорных» ситуациях. «
Nomeroff Net
Все материалы для нашего проекта: размеченные датасеты и натренированные модели, мы выложили в открытый доступ с разрешения RIA.com под лицензией Creative Commons CC BY 4.0
Что нам понадобится
Для того, чтобы ускорить установку планируем создать dockerfile — ожидайте в ближайших апдейтах проекта.
Nomeroff Net «Hello world»
Давайте уже что-то попробуем распознать. Клонируем с github-а репозиторий с кодом. Качаем в папку models, натренированные модели для поиска и классификации номеров, немного подправим под себя переменные с расположением папок.
UPD: Этот код является устаревшим, он будет работать только в ветке 0.1.0, свежие примеры смотрите здесь:
Все, можно распознавать:
Онлайн демка
Набросали простенькую демку для тех кому не хочется все это ставить и запускать у себя :). Будьте снисходительны и терпеливы к скорости работы скрипта.
Если нужны примеры украинских номеров (для проверки работы алгоритмов коррекции), возьмите пример из этой папки.
Что дальше
Я понимаю, что тема очень нишевая и вряд ли вызовет большой интерес у широкого круга программистов, кроме того, код и модели еще достаточно «сыроваты» в плане качества распознавания, быстродействия, потребления памяти и пр. Но все же есть надежда, что найдутся энтузиасты, которым будет интересно натренировать модели под свои нужды, свою страну, которые помогут и подскажут, где есть проблемы и вместе с нами сделают проект не хуже, чем коммерческие аналоги.
Известные проблемы
Анонс
Если это будет кому-то интересно, во второй части собираемся рассказать о том как и чем размечать свой датасет и как тренировать свои модели, которые могут работать лучше для вашего контента (вашей страны, вашего размера фото). Также поговорим о том как создать свой классификатор, который, например, поможет определять не зарисован ли номер на фото.
Распознавание номера авто github
Script that can make detection of a car number-plate and recognize it
Latest commit
Git stats
Files
Failed to load latest commit information.
README.md
Скрипт выполняющий детектирование и распознование автомобильного номера
Настройка окружения для запуска скрипта:
Скрипт для своей работы использует несколько вспомогательных инструментов, а именно:
Для запуска скрипта необходимо выполнить следующие действия:
Выполнить установку tensorflow object detection API
Выполнить установку tesseract tesseract для Windows (не забыть при установки выбрать русский язык), tesseract для Linux или для Linux можно использовать команду:
Установить пакеты для Python:
Cython, Numpy, Opencv, Matplotlib, path.py
необходимо выполнить установку protobuf compiler’а 3-ей версии:
После чего выполнить:
для Windows
скачать Nuget по ссылке
добавить папку с nuget.exe в переменную среды PATH
загрузить Google.Protobuf.Tools с помощью команды:
добавить в переменную среды PATH путь к protoc.exe например D:\Nuget\Google.Protobuf.Tools.3.4.0\tools\windows_x64
Готово! Можно запускать!
В командной строке либо терминале ввести:
Для изображений:
Возможные варианты улучшения:
Иные возможные пути решения задачи:
About
Script that can make detection of a car number-plate and recognize it
Распознавание номеров. Как мы получили 97% точности для Украинских номеров. Часть 2
Тренируем Mask RCNN находить область с номером
Конечно же, находить можно не только номер, а любой другой объект, потребность в поиске которого у вас возникла. Например можно, по аналогии, поискать кредитную карту и считать ее реквизиты. В общем, нахождение маски, в которую вписан объект на изображении называют задачей «Instance Segmentation» (об этом я уже писал в первой части).
Сейчас мы разберемся как натренировать сеть для решения этой задачи. На самом деле тут программирования мало, все сводится к монотонной, нудной, однообразной разметке данных. Да-да, после того как вы разметите свою первую сотню вы поймете о чем я 🙂
Итак, алгоритм подготовки данных следующий:
Обратите внимание — мы не обучаем все «с нуля», мы дотренировываем модель, обученную на данных COCO dataset, которую Mask RCNN закачает при первом запуске
Улучшаем классификатор номерных знаков под свои требования
После того, как области с номерными знаками найдены, нужно попробовать определить какого государства/типа номер мы распознаем. Тут универсализация работает против качества распознавания. Поэтому, в идеале, нужно тренировать классификатор, который не просто определяет какой страны номер, но и разновидность оформления этого номера (расположение символов, варианты символов для заданной разновидности номера).
В нашем проекте мы реализовали поддержку распознавания номеров Украины, РФ и Европейские номера в целом. Качество распознавания европейских номеров немного хуже, так как там номера с разным дизайном и увеличенным количеством встречающихся символов. Возможно, со временем, будут отдельные модули распознавания для «eu-ee», «eu-pl», «eu-nl»,…
Перед классификацией номерного знака его нужно «вырезать» из изображения и нормализировать, другими словами по максимуму убрать все искажения и получить аккуратный прямоугольник, который будет подвергаться дальнейшему анализу. Эта задача оказалась достаточно нетривиальной, мне даже пришлось вспомнить школьную математику и написать специализированную реализацию алгоритма кластеризации k-means :). Модуль, который это все процессит называется RectDetector, вот как выглядят нормализованные номера, которые далее будем классифицировать и распознавать.
Чтоб как-то автоматизировать процесс создания датасета для классификации номеров мы разработали небольшую админку на nodejs. С помощью этой админки вы можете разметить надпись на номерном знаке и класс к которому его относить.
Классификаторов может быть несколько. В нашем случае по типу номера и по тому зарисован/закрашен ли он на фото.
После того как разметили датасет, делим его на тренировочную, валидационную и тестовую выборки. В качестве примера скачайте наш датасет autoriaNumberplateOptions3Dataset-2019-05-20.zip, чтоб посмотреть как там все устроено.
Так как выборка уже размечена (отмодерирована), то вам нужно в рандомных json-файлах поменять «isModerated»:1 на «isModerated»:0 и после этого запустить админку.
Тренируем классификатор:
Скрипт тренировки train/options.ipynb поможет получить Вам свой вариант модели. На нашем примере видно что для классификации регионов/типов номерных знаков мы получили точность 98.8%, для классификации «закрашен ли номер?» 99,4% на нашем датасете. Согласитесь, неплохо получилось.
Тренируем свою OCR (распознавалку текста)
Ну вот мы нашли область с номером и нормализировали ее в прямоугольник, который содержит надпись с номером. Как нам прочитать текст? Проще всего прогнать его через FineReader или Tesseract. Качество будет «не очень», но при хорошем разрешении области с номером сможете получить точность на уровне 80%. На самом деле это неплохая точность, но если я Вам скажу что можете получить 97% и при этом потратите значительно меньше компьютерных ресурсов? Звучит неплохо — попробуем. Для этих целей подойдет немного необычная архитектура, в которой используются как сверточные так и рекуррентные слои. Архитектура этой сети выглядит приблизительно так:
Реализация взята с сайта https://supervise.ly/, мы ее немного модифицировали для тренировки на реальных фото (на сайте supervisely подан вариант для синтетической выборки)
Теперь начинается самая увлекательная часть, разметить хотя бы 5 000, номеров :). Мы разметили около
10 000 РФ. Это была самая сложна часть разработки. Вы даже не представляете сколько раз я засыпал на стуле у компа модерируя по нескольку часов в день очередную порцию номеров. Но настоящий герой разметки dimabendera — он разметил 2/3 всего контента, (поставьте ему плюс если понимаете как скучно было делать всю эту работу 🙂 )
Можно попробовать этот процесс как-то автоматизировать, например, предварительно распознав каждое изображение Tesseract-ом, а потом уже поправить ошибки с помощью нашей админки.
Обратите внимание: для разметки классификатора и OCR на номере используется одна и та же админка. Одни и те же данные вы сможете загрузить и туда и туда, кроме зарисованных номеров, конечно.
Если вы разметите хотя бы 5000 номеров и сможете обучить свою OCR — смело оформляйте себе премию у начальства, уверен, это испытание не для слабаков!
Приступаем к тренировке
Скрипт train/ocr-ru.ipynb тренирует модель для номеров РФ, там же примеры для Украины и Европы.
Обратите внимание, в настройках тренировки там только одна эпоха (один проход).
Особенностью тренировки такого датасета будет очень разный результат при каждой попытке, перед каждой тренировкой данные перемешиваются в случайном порядке, иногда более удачно для тренировки иногда «не очень». Я вам рекомендую пробовать хотя бы 5 раз, при этом контролировать точность на тестовых данных. При разных попытках запуска у нас точность могла «прыгать» от 87% до 97%.
Немного о настройке tensorflow для GPU NVIDIA
Если вы счастливый обладатель GPU от NVIDIA, то вы можете в разы все ускорить: и тренировку моделей и инференс (режим распознавания) номеров. Проблема заключается в том чтоб корректно все установить и скомпилировать.
Мы на своих серверах ML используем Fedora Linux (так сложилось исторически).
Приблизительная последовательность действий для тех кто использует эту OS следующая:
Полезные ссылки
UPD1: Так как мне и Дмитрию пишут в личку стандартные вопросы по распознаванию номеров, связке tensorflow с gpu и т.д. и мы с Дмитрием даем одни и те же ответы, хочется как-то заоптимизировать этот процесс.
Предлагаем сделать переписку в комментариях более структурированной, разделенной по темах. Для этого есть удобный функционал на GitHub. В дальнейшем просьба задавать вопросы не в комментах а в тематических issue на github Nomeroff Net
UPD2: Со временем появились также датасеты: Казахские номера, Грузинские номера
Распознаем номера автомобилей. Разработка multihead-модели в Catalyst
Фиксация различных нарушений, контроль доступа, розыск и отслеживание автомобилей – лишь часть задач, для которых требуется по фотографии определить номер автомобиля (государственный регистрационный знак или ГРЗ).
В этой статье мы рассмотрим создание модели для распознавания с помощью Catalyst – одного из самых популярных высокоуровневых фреймворков для Pytorch. Он позволяет избавиться от большого количества повторяющегося из проекта в проект кода – цикла обучения, расчёта метрик, создания чек-поинтов моделей и другого – и сосредоточиться непосредственно на эксперименте.
Сделать модель для распознавания можно с помощью разных подходов, например, путем поиска и определения отдельных символов, или в виде задачи image-to-text. Мы рассмотрим модель с несколькими выходами (multihead-модель). В качестве датасета возьмём датасет с российскими номерами от проекта Nomeroff Net. Примеры изображений из датасета представлены на рис. 1.
Рис. 1. Примеры изображений из датасета
Общий подход к решению задачи
Необходимо разработать модель, которая на входе будет принимать изображение ГРЗ, а на выходе отдавать строку распознанных символов. Модель будет состоять из экстрактора фичей и нескольких классификационных “голов”. В датасете представлены ГРЗ из 8 и 9 символов, поэтому голов будет девять. Каждая голова будет предсказывать один символ из алфавита “1234567890ABEKMHOPCTYX”, плюс специальный символ “-” (дефис) для обозначения отсутствия девятого символа в восьмизначных ГРЗ. Архитектура схематично представлена на рис. 2.
Рис. 2. Архитектура модели
В качестве loss-функции возьмём стандартную кросс-энтропию. Будем применять её к каждой голове в отдельности, а затем просуммируем полученные значения для получения общего лосса модели. Оптимизатор – Adam. Используем также OneCycleLRWithWarmup как планировщик leraning rate. Размер батча – 128. Длительность обучения установим в 10 эпох.
В качестве предобработки входных изображений будем выполнять нормализацию и преобразование к единому размеру.
Кодирование
Далее рассмотрим основные моменты кода. Класс датасета (листинг 1) в общем обычный для CV-задач на Pytorch. Обратить внимание стоит лишь на то, как мы возвращаем список кодов символов в качестве таргета. В параметре label_encoder передаётся служебный класс, который умеет преобразовывать символы алфавита в их коды и обратно.
Листинг 1. Класс датасета
В классе модели (листинг 2) мы используем библиотеку PyTorch Image Models для создания экстрактора фичей. Каждую из классификационных голов модели мы добавляем в ModuleList, чтобы их параметры были доступны оптимизатору. Логиты с выхода каждой из голов возвращаются списком.
Листинг 2. Класс модели
Центральным звеном, связывающим все компоненты и обеспечивающим обучение модели, является Runner. Он представляет абстракцию над циклом обучения-валидации модели и отдельными его компонентами. В случае обучения multihead-модели нас будет интересовать реализация метода handle_batch и набор колбэков.
Метод handle_batch, как следует из названия, отвечает за обработку батча данных. Мы в нём будем только вызывать модель с данными батча, а обработку полученных результатов – расчёт лосса, метрик и т.д. – мы реализуем с помощью колбэков. Код метода представлен в листинге 3.
Листинг 3. Реализация runner’а
Колбэки мы будем использовать следующие:
CriterionCallback – для расчёта лосса. Нам потребуется по отдельному экземпляру для каждой из голов модели.
MetricAggregationCallback – для агрегации лоссов отдельных голов в единый лосс модели.
OptimizerCallback – чтобы запускать оптимизатор и обновлять веса модели.
SchedulerCallback – для запуска LR Scheduler’а.
AccuracyCallback – чтобы иметь представление о точности классификации каждой из голов в ходе обучения модели.
CheckpointCallback – чтобы сохранять лучшие веса модели.
Код, формирующий список колбэков, представлен в листинге 4.
Листинг 4. Код получения колбэков
Остальные части кода являются тривиальными для Pytorch и Catalyst, поэтому мы не станем приводить их здесь. Полный код к статье доступен на GitHub.
Результаты эксперимента
Рис. 3. График лосс-функции модели в процессе обучения. Оранжевая линия – train loss, синяя – valid loss
В списке ниже перечислены некоторые ошибки, которые модель допустила на тест-сете:
Incorrect prediction: T970XT23- instead of T970XO123
Incorrect prediction: X399KT161 instead of X359KT163
Incorrect prediction: E166EP133 instead of E166EP123
Incorrect prediction: X225YY96- instead of X222BY96-
Incorrect prediction: X125KX11- instead of X125KX14-
Incorrect prediction: X365PC17- instead of X365PC178
Здесь присутствуют все возможные типы: некорректно распознанные буквы и цифры основной части ГРЗ, некорректно распознанные цифры кода региона, лишняя цифра в коде региона, а также неверно предсказанное отсутствие последней цифры.
Заключение
В статье мы рассмотрели способ реализации multihead-модели для распознавания ГРЗ автомобилей с помощью фреймворка Catalyst. Основными компонентами явились собственно модель, а также раннер и набор колбэков для него. Модель успешно обучилась и показала высокую точность на тестовой выборке.
Спасибо за внимание! Надеемся, что наш опыт был вам полезен.
Больше наших статей по машинному обучению и обработке изображений:
Распознавание номеров. Практическое пособие. Часть 1
Все начиналось банально — моя компания уже год платила ежемесячно плату за сервис, который умел находить регион с номерными знаками на фото. Эта функция применяется для автоматической зарисовки номера у некоторых клиентов.
И в один прекрасный день МВД Украины открыло доступ к реестру транспортных средств. Теперь по номерному знаку стало возможным проверять некоторую информацию про автомобиль (марку, модель, год выпуска, цвет и т.д. )! Скучная рутина линейного программирования померкла перед новой свехзадачей — считывать номера по всей базе фото и валидировать эти данные с теми, что указывал пользователь. Сами знаете как это бывает «глаза загорелись» — вызов принят, все остальные задачи на время стали скучны и монотонны… Мы принялись за работу и получили неплохие результаты, чем, собственно и решили поделиться с сообществом.
Для справки: на сайт AUTO.RIA.com, в день добавляется около 100 000 фото.
Кто еще распознает
Год назад я изучил этот рынок и оказалось, что работать с номерами стран exUSSR умеет не так уж много сервисов и ПО. Ниже представлен список компаний с которыми мы работали:
Automatic License Plate Recognition
Recognitor
Какие инструменты нужны для распознавания номеров
Нахождение объектов на изображении или в видео-потоке это задача из области компьютерного зрения, которая решается разными подходами, но чаще всего с помощью, так-называемых, сверточных нейронных сетей. Нам нужно найти не просто область на фото в которой встречается искомый объект, но и отделить все его точки от других объектов или фона. Эта разновидность задач называется «Instance Segmentation». На иллюстрации ниже визуализированы разные типы задач компьютерного зрения.
Я не буду сейчас писать много теории о том как работает сверточная сеть, этой информации достаточно в сети и докладов на youtube.
Из современных архитектур сверточных серей для задач сегментации часто используют: U-Net или Mask R-CNN. Мы выбрали Mask R-CNN.
Второй инструмент, который нам понадобится — это библиотека по распознаванию текстов, которая бы могла работать с разными языками и которую можно легко настраивать под специфику текстов, которые мы будем распознавать. Тут выбор не так уж велик, самой продвинутой является tesseract от Google.
Так же есть ряд менее «глобальных» инструментов, с помощью которых нам нужно будет нормализовать область с номерным знаком (привести его в такой вид, при котором распознавание текста будет возможным). Обычно для таких преобразований используют opencv.
Так же, можно будет попробовать определить страну и тип, к которой относится найденный номерной знак, чтоб в постобработке применить уточняющий шаблон, характерный для этой страны и этого типа номера. Например, украинский номерной знак, начиная с 2015 года оформлен в сине-желтом оформлении состоит из шаблона «две буквы черыре цифры две буквы».
Кроме того, имея статистику частоты «встречания» в номерных знаках того или иного сочетания букв или цифр можно улучшить качество постобработки в «спорных» ситуациях. «
Nomeroff Net
Все материалы для нашего проекта: размеченные датасеты и натренированные модели, мы выложили в открытый доступ с разрешения RIA.com под лицензией Creative Commons CC BY 4.0
Что нам понадобится
Для того, чтобы ускорить установку планируем создать dockerfile — ожидайте в ближайших апдейтах проекта.
Nomeroff Net «Hello world»
Давайте уже что-то попробуем распознать. Клонируем с github-а репозиторий с кодом. Качаем в папку models, натренированные модели для поиска и классификации номеров, немного подправим под себя переменные с расположением папок.
UPD: Этот код является устаревшим, он будет работать только в ветке 0.1.0, свежие примеры смотрите здесь:
Все, можно распознавать:
Онлайн демка
Набросали простенькую демку для тех кому не хочется все это ставить и запускать у себя :). Будьте снисходительны и терпеливы к скорости работы скрипта.
Если нужны примеры украинских номеров (для проверки работы алгоритмов коррекции), возьмите пример из этой папки.
Что дальше
Я понимаю, что тема очень нишевая и вряд ли вызовет большой интерес у широкого круга программистов, кроме того, код и модели еще достаточно «сыроваты» в плане качества распознавания, быстродействия, потребления памяти и пр. Но все же есть надежда, что найдутся энтузиасты, которым будет интересно натренировать модели под свои нужды, свою страну, которые помогут и подскажут, где есть проблемы и вместе с нами сделают проект не хуже, чем коммерческие аналоги.
Известные проблемы
Анонс
Если это будет кому-то интересно, во второй части собираемся рассказать о том как и чем размечать свой датасет и как тренировать свои модели, которые могут работать лучше для вашего контента (вашей страны, вашего размера фото). Также поговорим о том как создать свой классификатор, который, например, поможет определять не зарисован ли номер на фото.