Четверг, 17 января 2019 10:07

Оптимизация OpenCV на Raspberry Pi.

Оцените материал
(0 голосов)

Это руководство предназначено для опытных пользователей Raspberry Pi, которые стремятся получить максимум от возможностей Pi в области компьютерного зрения и обработки изображений с использованием OpenCV.

 Статья нацелена на людей уже знакомых с OpenCV и Raspberry Pi поэтому пишется при условия что Вы уже:

  1. Вы работали с предыдущими руководствами по установке Raspberry Pi + OpenCV (в идеале, несколько раз).
  2. Вы знакомы с командной строкой и средой Unix.

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

К концу урока урок, ваш Raspberry Pi будет на 30% быстрее при выполнении скриптов OpenCV и Python.

 

Оптимизация OpenCV на Raspberry Pi

В прошлом уроке я разбирал, как развернуть глубокую нейронную сеть на вашем Raspberry Pi.

Результаты были вполне удовлетворительными: для классификации изображения с помощью GoogLeNet требовалось приблизительно 1,7 секунды, а для SqueezeNet - 0,9 секунды, соответственно.

Тем не менее, мне было интересно, возможно ли сулучшить эти значения.

Хотя мы не можем обучать нейронные сети на самом Raspberry Pi, мы можем развернуть предварительно обученные сети на нашем Pi - при условии, что мы сможем достаточно оптимизировать работу Raspberry Pi.

В начале мы обсудим варианты оптимизации, которые мы будем использовать во время установки OpenCV, а затем я распишу семь этапов установки.

После того как мы развернем оптимизированную версию OpenCV, мы проведем несколько тестов что бы определить получили ли мы прирост производительность в сравнение с обычной сборкой.

 

NEON и FVPV3

Когда я искал способы, как оптимизировать Raspberry Pi для OpenCV, я наткнулся на прекрасную статью от Саги Зееви.

В своей статье Саги рекомендует использовать:

  1. NEON
  2. VFPV3
  3. И дополнительно Threading Building Blocks (TBB)

Я не большой поклонник TBB, так как (1) прирост производительности скуден, и (2) это существует много проблем с использованием.

Наибольшую выгоду вы получите от NEON и VFPV3.

ARM NEON - это расширение архитектуры для процессоров ARM. Он был разработан инженерами ARM специально для скоростной обработки видео, обработки изображений, распознавания речи и машинного обучения. Эта архитектура поддерживает множественные данные с одной инструкцией (SIMD) (в отличие от SISD, MISD, MIMD), которая описывает архитектуру, в которой несколько элементов обработки в конвейере выполняют операции над несколькими точками данных (аппаратными средствами), которые все выполняются с одной инструкцией.

Инженеры ARM также встроили VFPV3, это оптимизация с плавающей запятой, используемая в чипе, используемый в Raspberry Pi 3. Вы можете ознакомиться со статьей где, описывает функции, используемые в этой архитектуре, такие как настраиваемые режимы округления и настраиваемое поведение по умолчанию, а не число (NaN).

Для нас все это означает, что наша нейронная сеть, должна, будет работать быстрее, потому что процессор ARM на Raspberry Pi 3 имеет аппаратную оптимизацию, которую мы сможем использовать с процессором 4 × ARM Cortex-A53, 1,2 ГГц.

Я думаю, что Вас очень впечатлят результаты работы оптимизированного OpenCV.

 

Шаг #1: Расширение файловой системы и увеличение пустого пространство

Перед началом убедитесть что у Вы сотвествуете следующим пунктам:

  1. Вы работаете с последней версией Raspbian Stretch.
  2. Это не первая Ваша установка OpenCV на Raspberry Pi с использованием вирутальной среды Python. Если это не так, пожалуйста сначала ознакомитесь с одним из моих вводных руководств по установке OpenCV.
  3. Вы знакомы с командной строкой и средой Unix.
  4. Вы знаете, как отладить CMake в распространенных ошибках (виртуальная среда Python не найдена, отсутствуют библиотеки Python и т. д.).

Опять же хочу напомнить что, это руководство является расширенным, поэтому я указываю команды и предоставляю объяснение, если оно необходимо.

Первым шагом является запуск, raspi-config и расширение вашей файловой системы:

$ sudo raspi-config

Затем перезагрузите свой Raspberry Pi:

$ sudo reboot

Удалите Wolfram Engine, и LibreOffice, чтобы освободить около 1 ГБ свободного места на Raspberry Pi:

$ sudo apt-get purge wolfram-engine
$ sudo apt-get purge libreoffice*
$ sudo apt-get clean
$ sudo apt-get autoremove

 

Шаг #2: Установка зависимостей

Следующие команды обновят и улучшат все существующие пакеты с последующей установкой зависимостей, библиотек ввода-вывода и пакетов оптимизации для OpenCV:

$ sudo apt-get update && sudo apt-get upgrade
$ sudo apt-get install build-essential cmake pkg-config
$ sudo apt-get install libjpeg-dev libtiff5-dev libjasper-dev libpng12-dev
$ sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev
$ sudo apt-get install libxvidcore-dev libx264-dev
$ sudo apt-get install libgtk2.0-dev libgtk-3-dev
$ sudo apt-get install libcanberra-gtk*
$ sudo apt-get install libatlas-base-dev gfortran
$ sudo apt-get install python2.7-dev python3-dev

Весь этот процесс должен занять около 5 минут.

Примечание: я добавил libcanberra-gtk *, который охватывает специфичный ARM GTK для предотвращения предупреждений от GTK (не ошибок; а предупреждений), с которыми вы можете столкнуться при запуске скриптов Python + OpenCV на Raspberry Pi.

 

Шаг #3: Загрузка исходного кода OpenCV

Далее необходимо загрузите исходный код OpenCV из репозиториев opencv и opencv_contrib, а затем разархивировать их:

$ cd ~
$ wget -O opencv.zip https://github.com/opencv/opencv/archive/3.3.0.zip
$ unzip opencv.zip
$ wget -O opencv_contrib.zip https://github.com/opencv/opencv_contrib/archive/3.3.0.zip
$ unzip opencv_contrib.zip

В этом уроке мы будем использовать OpenCV 3.3; однако по мере выпуска новых версий OpenCV Вы можете обновить  номера версий OpenCV на актуальные.

 

Шаг #4: Загрузка исходного кода OpenCV

Мы будем использовать виртуальную среду Python, что будет является наилучшей практикой при работе с Python.

Вы можете установить pip, virtualenv и virtualenvwrapper с помощью следующих команд:

$ wget https://bootstrap.pypa.io/get-pip.py
$ sudo python get-pip.py
$ sudo python3 get-pip.py
$ sudo pip install virtualenv virtualenvwrapper
$ sudo rm -rf ~/.cache/pip

Как только virtualenv и virtualenvwrapper установлены, откройте ~ / .profile и добавьте следующие строки в конец файла, используя ваш любимый текстовый редактор на основе терминала, к примеру vim, emacs или nano:

# virtualenv and virtualenvwrapper
export WORKON_HOME=$HOME/.virtualenvs
export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3
source /usr/local/bin/virtualenvwrapper.sh

Перезагрузите файл ~ / .profile, чтобы применить изменения к текущей сессии bash:

$ mkvirtualenv cv -p python3

Вам нужно будет запускать source ~ / .profile каждый раз, когда вы открываете новый терминал / SSH в Pi, чтобы убедиться, что системные переменные установлены правильно (он также загружает этот файл при загрузке).

Затем создайте виртуальную среду Python 3:

$ mkvirtualenv cv -p python3

В данном уроке я создаю виртуальную среду Python с именем cv, используя Python 3 (в качестве альтернативы Вы также можете использовать Python 2.7, изменив ключ -p на python2).

Вы можете назвать виртуальную среду как хотите, но я использую cv в качестве стандартного правила об именах, которые я вывел для себя.

Наконец, установите NumPy в виртуальную среду Python:

$ pip install numpy

 

Шаг #5: Скомпилируйте и установите оптимизированную библиотеку OpenCV для Raspberry Pi

Теперь мы готовы скомпилировать и установить оптимизированную версию OpenCV.

Убедитесь, что вы находитесь в виртуальной среде cv, используя команду workon:

$ workon cv

Настройте свою сборку:

$ cd ~/opencv-3.3.0/
$ mkdir build
$ cd build
$ cmake -D CMAKE_BUILD_TYPE=RELEASE \
    -D CMAKE_INSTALL_PREFIX=/usr/local \
    -D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib-3.3.0/modules \
    -D ENABLE_NEON=ON \
    -D ENABLE_VFPV3=ON \
    -D BUILD_TESTS=OFF \
    -D INSTALL_PYTHON_EXAMPLES=OFF \
    -D BUILD_EXAMPLES=OFF ..

Обратите внимание, как отмечены флаги NEON и VFPV3.

Если вы используете Python 2.7, ваш раздел «Python 2» должен выглядеть следующим образом:

оптимизация opencv cmake cv33 python2 box

CMake запустит генерацию файлов сборки для OpenCV 3.3. OpenCV будет правильно собран с Python 2.7 и NumPy из нашего cv virtualenv.

 

Если вы компилируете OpenCV для Python 3, проверьте вывод «Python 3» CMake:

оптимизация opencv cmake cv33 python3 box

После запуска CMake Python 3 + NumPy будет правильно настроен из нашего cv virtualenv на Raspberry Pi.

 

Обратите внимание, как правильно должны быть установлены переменные пути Interpreter, Libraries, numpy и packages.

Перед началом компиляции я бы предложил увеличить объем файла подкачки. Это позволит вам скомпилировать OpenCV для работы со всеми четырьмя ядрами Raspberry Pi без зависания компиляции из-за истощения памяти.

Откройте файл / etc / dphys-swapfile и отредактируйте переменную CONF_SWAPSIZE:

# set size to absolute value, leaving empty (default) then uses computed value
#   you most likely don't want this, unless you have an special disk situation
# CONF_SWAPSIZE=100
CONF_SWAPSIZE=1024

Обратите внимание, что я увеличиваю объем подкачки с 100 МБ до 1024 МБ. Это «секретный соус» для компиляции OpenCV с несколькими ядрами на Raspbian Stretch.

Если вы не выполните этот шаг, очень вероятно, что ваш Pi зависнет при компеляции.

Перезапустите сервис подкачки:

$ sudo /etc/init.d/dphys-swapfile stop
$ sudo /etc/init.d/dphys-swapfile start

Примечание. Увеличение размера swap - это отличный способ сжечь карту Raspberry Pi microSD. Флэш-память имеет ограниченное количество операций записи, которые вы можете выполнять до тех пор, пока карта больше не сможет удерживать 1 и 0. Мы lдаем разрешение на большой обмен только в течение короткого периода времени, так что это не имеет большого значения. Независимо от этого, обязательно сделайте резервную копию вашего .img файла после установки OpenCV + Python на тот случай, если ваша карта неожиданно умрет. Вы можете узнать больше о больших размерах подкачки карт памяти на этой странице.

Теперь, когда мы обновили размер файла подкачки, запустите компиляцию OpenCV, используя все четыре ядра:

$ make -j4

успешная Оптимизация OpenCV

Не забудьте вернуться к файлу / etc / dphys-swapfile и:

  1. Сбросьте CONF_SWAPSIZE до 100 МБ.
  2. Перезапустите сервис подкачки.

 

Шаг #6: Завершите установку оптимизированного OpenCV на Raspberry Pi

Если вы скомпилировали OpenCV для Python 3, Вам нужно выполнить следующие команды для символической привязки cv2.so к вашей виртуальной среде cv:

$ cd /usr/local/lib/python3.5/site-packages/
$ sudo mv cv2.cpython-35m-arm-linux-gnueabihf.so cv2.so
$ cd ~/.virtualenvs/cv/lib/python3.5/site-packages/
$ ln -s /usr/local/lib/python3.5/site-packages/cv2.so cv2.so

Имейте в виду, что пути нужно будет обновлять в зависимости от того, какую версию Python Вы используете -  Python 3.4, Python 3.5, Python 3.6 и т. д.

Если Вы вместо OpenCV для Python 3 скомпилировали OpenCV для Python 2.7, Вы можете использовать следующие команды для символической ссылки вашего файла cv2.so на виртуальную среду cv:

$ cd ~/.virtualenvs/cv/lib/python2.7/site-packages/
$ ln -s /usr/local/lib/python2.7/site-packages/cv2.so cv2.so

 

Шаг #7: Тестирование оптимизированного OpenCV на Raspberry Pi

Для начала быстро проверим все ли у нас работает правильно. Откройте виртуальную среду cv, запустите оболочку Python и попробуйте импортировать библиотеку OpenCV:

$ source ~/.profile
$ workon cv
$ python
>>> import cv2
>>> cv2.__version__
'3.3.0'
>>>

Поздравляем! Вы только успешно установили оптимизированный OpenCV 3.3 на Raspberry Pi 3.

 

Итак, какой прирост производительности мы получили?

После прочтения этого урока Вам, вероятно, будет интересно узнать, какой прирост производительности вы получили от OpenCV на Raspberry Pi.

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

Используйте github, чтобы загрузить предварительно подготовленные сверточные нейронные сети + пример изображений + сценарий классификации.

Запустите оболочку и выполните следующие команды:

$ python pi_deep_learning.py --prototxt models/bvlc_googlenet.prototxt \
	--model models/bvlc_googlenet.caffemodel --labels synset_words.txt \
	--image images/barbershop.png
[INFO] loading model...
[INFO] classification took 0.87173 seconds
[INFO] 1. label: barbershop, probability: 0.78055
[INFO] 2. label: barber chair, probability: 0.2194
[INFO] 3. label: rocking chair, probability: 3.4663e-05
[INFO] 4. label: restaurant, probability: 3.7258e-06
[INFO] 5. label: hair spray, probability: 1.4715e-06

 оптимизация opencv googlenet для фото

Здесь вы можете видеть, что GoogLeNet классифицировал наше изображение за 0,87 секунды, что является быстрее на 48,82% по сравнению с 1,7 секундами в прошлом уроке.

Давайте попробуем SqueezeNet:

$ python pi_deep_learning.py --prototxt models/squeezenet_v1.0.prototxt \
	--model models/squeezenet_v1.0.caffemodel --labels synset_words.txt \
	--image images/barbershop.png
[INFO] loading model...
[INFO] classification took 0.4777 seconds
[INFO] 1. label: barbershop, probability: 0.80578
[INFO] 2. label: barber chair, probability: 0.15124
[INFO] 3. label: half track, probability: 0.0052872
[INFO] 4. label: restaurant, probability: 0.0040124
[INFO] 5. label: desktop computer, probability: 0.0033352

 оптимизация opencv squeezenet для фото

Здесь мы видим, что SqueezeNet правильно классифицировал входное изображение за 0,47 секунды, что является еще одним значительным улучшением по сравнению с 0,9 секундами с прошлой недели (47,78%).

Исходя из наших результатов, ясно, что наша оптимизация над OpenCV оказала значительное влияние.

 

Итог

В это уроке вы узнали, как оптимизировать установку OpenCV на Raspberry Pi.

Эти оптимизации произошли из-за обновления нашей команды CMake для включения NEON и VFPV3. При тестировании OpenCV это приводит к увеличению скорости примерно на 30%. Тем не менее, если применять его строго к новому модулю dnn в OpenCV 3, мы видим увеличение более чем на 48%!

Надеюсь, вам понравился этот урок.

Источник

Author

Bender

Я поделюсь с тобой всеми знаниями, которые доступны мне.

Комментарии (0)

There are no comments posted here yet

Оставьте свой комментарий

  1. Posting comment as a guest. Sign up or login to your account.
Вложения (0 / 3)
Share Your Location

О нас

Основой деятельностью портала является показ и объяснение что представляет собой выражени "Робот", "Робототехника", "Законы робототехники", "Мехатроника", "Искусственный интеллект(ИИ)". 

 Если у Вас есть интересная информация по тематике сайта и Вы готовы ей поделиться, - обращайтесь на емайл через форму обратной связи. И мы опубликуем Вашу статью