Автоматическое распознавание автомобильных номеров на Raspberry Pi

Рассказываем, как самостоятельно создать компактную систему автоматического распознавания номеров автомобилей на одной плате Raspberri Pi с библиотекой OpenALPR.

Рассмотрим задачу создания собственной системы автоматического детектирования и распознавания автомобильных номеров на основе открытой библиотеки OpenALPR. Такие системы применяются не только в карательных целях, чтобы штрафовать водителей, превышающих разрешенную скорость. Так, установленная на контрольном пункте система распознавания сокращает время ожидания водителей перед шлагбаумом и снижает нагрузку постового. Программа сверяет распознанный номер с базой, разрешая или запрещая въезд транспорта. Другое применение – оптимизация городского или локального трафика через трекинг передвижения автомобилей и общественного транспорта по камерам наружного наблюдения. Мы будем рады, если вы поделитесь своими идеями применения таких систем в комментариях.

Что мы хотим сделать?

Итак, когда в кадре видеонаблюдения оказывается автомобиль, система должна обнаружить знак и распознавать его в виде строки, состоящей из набора символов. Нахождение объектов в видеопотоке – задача из области компьютерного зрения. При беглом поиске в интернете можно найти множество публикаций, посвященных распознаванию номеров, но... чаще всего на одном единственном примере. Такие решения, конечно, не универсальны. Автомобильные номера в поле зрения камеры оказываются под разными углами, в меняющихся условиях освещения, могут иметь загрязнения и повреждения. Кроме того, в кадре может одновременно находиться несколько автомобилей.

Универсальные системы требуют обучения на сотнях тысяч предварительно распознанных примеров. Для этого, кроме предообработки изображений, используется глубокое обучение на основе нейросетей. Процесс их тренировки требует наличия мощных видеокарт или распределенных вычислительных систем. В то же время результат в виде предобученной нейросети для распознавания символов вполне может работать и на одноплатных компьютерах, например, Raspberry Pi. Это снижает издержки внедрения и использования технологии.

Таким образом, кроме самой платы, понадобятся следующие инструменты:

  1. Библиотека для предобработки изображений OpenCV.
  2. Библиотека распознавания текста Tesseract OCR.
  3. Библиотека OpenALPR, учитывающая предполагаемый объект распознавания (табличку автомобильного номера) и использующая методы вышеуказанных библиотек.

OpenALPR – это библиотека для автоматического распознавания табличек с буквенно-численными символами, написанная на C++ с интерфейсом для Node.js, Python, Java, Go и C#. Под аббревиатурой OpenALPR скрывается Automatic License Plate Recognition (автоматическое распознавание автомобильных номеров). Пакет предоставляет как открытую библиотеку для разработки собственных приложений, так и платный агент (при желании использовать готовое решение). Библиотека работает как со статичными изображениями, так и с видеопотоком. Документация проекта.

Ниже мы подробно рассмотрим установку OpenALPR на примере Raspberry Pi третьей модели с учетом нюансов. Обратите внимание: при установке важно учитывать зависимости и конкретные версии библиотек.

1. Выполняем update и upgrade ОС

По умолчанию мы предполагаем, что на плате стоит наиболее популярная операционная система для рассматриваемой платы – Raspbian. Все шаги выполняются на правах администратора (root). Начать нужно с двух стандартных команд, обновляющих операционную систему:

apt-get update  
apt-get upgrade 

2. Устанавливаем необходимые пакеты

Перед установкой OpenALPR необходимо разобраться со всеми необходимыми зависимостями:

apt-get install autoconf automake libtool  
apt-get install libleptonica-dev  
apt-get install libicu-dev libpango1.0-dev libcairo2-dev  
apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev  
apt-get install python-dev python-numpy libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev  
apt-get install virtualenvwrapper  
apt-get install liblog4cplus-dev  
apt-get install libcurl4-openssl-dev

То же можно выполнить в виде однострочной команды:

apt-get install autoconf automake libtool libleptonica-dev libicu-dev libpango1.0-dev libcairo2-dev cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev python-dev python-numpy libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev virtualenvwrapper liblog4cplus-dev libcurl4-openssl-dev

В случае, если apt-get install для какого-либо из пакетов закончится неудачей (no package found), необходимо вручную найти отсутствующий пакет, используя apt-cache search.

Tesseract использует библиотеку leptonica версии 1.71, поэтому предварительно ее установим:

cd /usr/src  
wget http://www.leptonica.org/source/leptonica-1.71.tar.gz  
tar xf leptonica-1.71.tar.gz
cd /usr/src/leptonica-1.71
./configure
make  
make install

3. Устанавливаем основные библиотеки нужных версий

Как было сказано выше, в основе OpenALPR лежат две библиотеки:

  • Tesseract OCR v3.0.4 (важно: OpenALPR не использует Tesseract последней версии) 
  • OpenCV v2.4.8+

Чтобы предупредить возможные трудности, опишем процесс установки подробнее.

3.1. Tesseract OCR

Скачиваем (клонируем) пакет с git:

cd /usr/src/  
git clone https://github.com/tesseract-ocr/tesseract
cd /usr/src/tesseract
git tag
git checkout 3.04.01 
./autogen.sh 

Если все прошло успешно, вы получите сообщение:

All done.  
To build the software now, do something like:

$ ./configure [--enable-debug] [...other options]

На следующем шаге нужно настроить библиотеку, как предложено в сообщении выше, то есть запустить ./configure. Запустим с опцией отладки. 

./configure --enable-debug

После того как мы настроили библиотеку, запустим компиляцию:

make -j2

На Raspberry процесс занимает много времени. Поэтому запускаем команду с опцией j2(в два потока).  В случае если это вызовет проблемы, запускайте команду make без дополнительных параметров. Устанавливаем скомпилированное:

make install

Проверяем результат компиляции:

root@raspberrypi:/usr/local/src/tesseract# tesseract  
tesseract: error while loading shared libraries: libtesseract.so.3: cannot open shared object file: No such file or directory

Если вы получили схожую ошибку (на этом или следующих этапах) запустите ldconfig. Вновь проверим результат, теперь всё работает:

root@openalpr-tst01:/usr/src/tesseract# tesseract -v  
tesseract 3.04.01  
 leptonica-1.71
  libjpeg 6b : libpng 1.2.50 : libtiff 4.0.3 : zlib 1.2.8

Видим номер версии, библиотека установлена.

3.2. OpenCV

Загрузим OpenCV. Разархивируем zip-файл. При этом будет создана директория /usr/src/opencv-2.4.13.   

cd /usr/src  
wget https://github.com/opencv/opencv/archive/2.4.13.zip  
unzip  2.4.13.zip  

Далее создаем внутри каталог release, переходим в него и настраиваем проект.

cd opencv-2.4.13  
mkdir release  
cd release
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local ..  

Если всё закончится хорошо, мы получим следующее сообщение:

-- Configuring done
-- Generating done
-- Build files have been written to: /usr/local/src/opencv-2.4.13/release

Если вы получите ошибку вида libdc1394 error: Failed to initialize libdc1394, запустите следующий код:

ln /dev/null /dev/raw1394
apt-get install libdc1394-22-dev  
apt-get install libdc1394-22 libdc1394-utils  

Далее нужно скомпилировать результат, лучше, как и прежде, с параметром j2, чтобы сократить время компиляции. То есть в окне терминала это будет выглядеть примерно так:

root@raspberrypi:/usr/src/opencv-2.4.13/release# make -j2

В первый раз процесс может закончиться следующей ошибкой:

[ 47%] Building CXX object modules/ocl/CMakeFiles/opencv_ocl.dir/src/cl_runtime/clamdfft_runtime.cpp.o
c++: internal compiler error: Segmentation fault (program cc1plus)  
Please submit a full bug report,  
with preprocessed source if appropriate.  
See <file:///usr/share/doc/gcc-4.9/README.Bugs> for instructions.  
modules/ocl/CMakeFiles/opencv_ocl.dir/build.make:719: recipe for target 'modules/ocl/CMakeFiles/opencv_ocl.dir/src/cl_runtime/clamdfft_runtime.cpp.o' failed  
make[2]: *** [modules/ocl/CMakeFiles/opencv_ocl.dir/src/cl_runtime/clamdfft_runtime.cpp.o] Error 4  
CMakeFiles/Makefile2:4734: recipe for target 'modules/ocl/CMakeFiles/opencv_ocl.dir/all' failed  
make[1]: *** [modules/ocl/CMakeFiles/opencv_ocl.dir/all] Error 2  
make[1]: *** Waiting for unfinished jobs....  

Это может быть вызвано нехваткой памяти. Срабатывает следующий набор действий:

  • Перезагрузить плату
  • Увеличить файл подкачки (swap)
  • Запустить make clean и вновь make

Чтобы увеличить файл подкачки, выполняем следующую последовательность:

fallocate --length 2GiB /root/2G.swap  
chmod 0600 /root/2G.swap  
mkswap /root/2G.swap  
swapon /root/2G.swap 

После того как удастся успешно скомпилировать OpenCV, производим установку:

make install

4. Устанавливаем OpenALPR

Наконец, мы можем установить саму OpenALPR. Клонируем репозиторий и проверяем версию:

cd /usr/src
git clone https://github.com/openalpr/openalpr.git
cd openalpr/src
git describe --tags

Например, в нашем случае ответом на последний запрос было v2.1.0-513-gcd2aab0, то есть версия 2.1.0. Если вы хотите использовать ту же версию, что в нашем примере, используйте git checkout v2.1.0

mkdir build  
cd build  
cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr -DCMAKE_INSTALL_SYSCONFDIR:PATH=/etc ..  
make  
make install  

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

apt-get install cmake  
apt-get install liblog4cplus-dev libcurl3-dev  
sudo apt-get install beanstalkd  
apt-get install openjdk-7-jdk  
export JAVA_HOME=/usr/lib/jvm/java-1.7.0-openjdk-amd64/  

Протестируем полученный результат:

wget http://plates.openalpr.com/h786poj.jpg -O lp.jpg  
alpr lp.jpg 
plate0: 8 results  
    - 786P0      confidence: 90.1703
    - 786PO      confidence: 85.579
    - 786PQ      confidence: 85.3442
    - 786PD      confidence: 84.4616
    - 7B6P0      confidence: 69.4531
    - 7B6PO      confidence: 64.8618
    - 7B6PQ      confidence: 64.627
    - 7B6PD      confidence: 63.7444

Всё работает. Слева — распознанный номер, справа — вероятность его соответствия реальному номеру на изображении. 

Чтобы настроить связку библиотеки с С/С++Java, C#, Java или Python, ознакомьтесь с соответствующим разделом официальной документации. Например, использов связку с Python, вы можете построить систему из нескольких веб-камер, взаимодействующих с общим сервером, обращаясь к отдельным камерам только в случае нестандартных ситуаций, когда номер оказался не распознан.  

Какие способы распознавания автомобильных номеров знаете вы?

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ

matyushkin
07 апреля 2020

ТОП-15 книг по Python: от новичка до профессионала

Книги по Python (и связанным с ним специальным темам) на русском языке. Рас...
admin
14 июля 2017

Пишем свою нейросеть: пошаговое руководство

Отличный гайд про нейросеть от теории к практике. Вы узнаете из каких элеме...