Распознавание жестов с помощью Raspberry Pi и OpenCV


Наверняка все вы хоть раз в своей жизни играли в игру "камень, ножницы, бумага", в которой каждый из игроков с помощью своей руки изображает один из этих предметов. Правила этой игры очень просты:

  • бумага побеждает камень;
  • ножницы побеждают бумагу;
  • камень побеждает ножницы.

Внешний вид проекта распознавания жестов с помощью Raspberry Pi и OpenCVВ данной статье мы рассмотрим как играть в игру "камень, ножницы, бумага" с помощью платы Raspberry Pi и библиотек OpenCV и Tensorflow. Используя данные библиотеки мы будем распознавать жесты пользователя и, таким образом, идентифицировать какой из трех предметов он выбрал. Наш проект будет состоять из трех основных этапов:

  • сбор данных;
  • обучение (тренировка модели);
  • распознавание жестов.

На первом этапе мы соберем изображения, на которых показаны камень, ножницы, бумага (с помощью жестов рук) и изображение без жеста (пустое). Пустое изображение нужно для того, чтобы плата Raspberry Pi не делала ненужных действий. Набор данных для нашего проекта будет состоять из 800 изображений, относящихся к 4-м классам. На втором этапе мы будем тренировать (обучать) наш распознаватель (Recognizer) обнаруживать (распознавать) жесты, сделанные пользователем. После распознавания жеста пользователя плата Raspberry Pi случайным образом выбирает один из этих предметов (камень, ножницы, бумага), после чего сравнивает свой предмет с предметом пользователя и выбирает победителя (она или пользователь).

Также на нашем сайте вы можете посмотреть аналогичные проекты, в которых использовалась обработка изображений с помощью платы Raspberry Pi и библиотеки OpenCV:

Необходимые компоненты

  1. Плата Raspberry Pi (купить на AliExpress).
  2. Камера для Raspberry Pi (купить на AliExpress).

Установка OpenCV и других необходимых пакетов

Перед установкой библиотеки OpenCV на плату Raspberry Pi обновите ее программное обеспечение до последней версии с помощью команды:

Затем установим ряд дополнений, которые будут необходимы для последующей установки OpenCV.

После этого установим библиотеку OpenCV на плату Raspberry Pi с помощью команды:

Затем установим пакет imutils, с помощью которого можно выполнять различные функции обработки изображений, например, перевод, вращение, изменение размера, скелетонизация. Также imutils упрощает отображение изображений Matplotlib. Для установки данного пакета используйте команду:

Далее установим пакет Tensorflow с помощью команды:

Также нам будет необходима библиотека sklearn (Scikit-learn), написанная на python. Она обеспечивает широкий набор контролируемых и неконтролируемых обучающих алгоритмов с помощью совместимого с Python интерфейса. В нашем проекте мы будем использовать ее для построения модели машинного обучения (machine learning) для распознавания жестов руки. Для ее установки используйте следующую команду:

Дополнительно в нашем проекте нам еще понадобится модель глубокой нейронной сети (deep neural network) SqueezeNet для технологии компьютерного зрения (computer vision). SqueezeNet представляет собой модель небольшой нейронной сети, которая работает на основе фреймворка глубокого обучения Caffe. Мы будем использовать SqueezeNet поскольку она отличается от других подобных инструментов маленьким размером и точностью работы. Благодаря маленькому размеру она хорошо подходит для установки на аппаратные средства с ограниченным объемом памяти. Установить keras_squeezenet можно с помощью команды:

Объяснение программы распознавания жестов руки для Raspberry Pi

Полный код всех программ приведен в конце статьи, здесь же мы кратко рассмотрим их основные фрагменты.

Как мы уже отмечали ранее, наш проект будет состоять из 3-х этапов: на первом этапе будет выполняться сбор информации, на втором – обучение (тренировка) модели, а на третьем – распознавание жестов руки пользователя. Каталог нашего проекта будет включать следующие элементы:

  • набор данных (Dataset): он будет содержать изображения камня, ножницы, бумаги и изображение "пустого" жеста;
  • image.py: небольшой скрипт на python для сбора изображений, необходимых для построения набора данных;
  • training.py: этот скрипт будет считывать наш набор данных и производить точную настройку Squeezenet чтобы создать модель распознавания жестов (game-model.h5);
  • game.py: скрипт, который на основе нашей обученной модели и набора данных будет распознавать жесты пользователя (камень, ножницы, бумага) и осуществлять случайный выбор одного из этих предметов платой Raspberry Pi.

Весь каталог для данного проекта можно скачать по следующей ссылке.

Рассмотрим основные этапы работы нашего проекта более подробно.

1. Сбор данных

На первом этапе нашего проекта мы создадим набор данных, содержащий по 200 изображений для каждого класса: камень, ножницы, бумага и пустой жест. Image.py – это простой скрипт на python, который использует OpenCV для сбора изображений жестов. Откройте файл image.py в каталоге Game и вставьте в него ниже приведенный (в конце статьи) фрагмент кода. Затем начните сбор изображений с помощью команды:

Число 200 в этой команде означает число изображений, которые мы будем захватывать. После запуска скрипта нажмите клавишу ‘r’ чтобы захватить изображения с жестом камня (Rock gesture) и затем нажмите ‘a’ чтобы начать процесс захвата изображений. Далее вам необходимо проделать аналогичные операции для захвата изображений бумаги (нажать ‘p’,  paper), ножниц (нажать ‘s’, scissors) и пустого жеста (нажать ‘n’, nothing).

Рассмотрим ключевые фрагменты кода скрипта image.py. Вначале в нем нам необходимо подключить используемые пакеты.

Далее мы задаем число отсчетов, которые мы хотим собрать.

Затем укажем путь, по которому будут сохраняться все изображения.

После этого создадим каталог, в котором будут сохраняться изображения.

Затем создадим прямоугольник с помощью функции cv2.rectangle. После запуска скрипта на выполнение вам необходимо будет поместить свои руки внутрь этого созданного прямоугольника.

В следующем фрагменте кода мы будем обрабатывать нажатия клавиш. Если пользователь нажимает клавишу ‘r’, то мы имени метки (label name) будем присваивать значение ‘rock’ и создавать каталог с именем rock внутри каталога image. Если пользователь нажимает клавишу ‘p’, то имени метки присваивается значение ‘paper’ и т.д.

Если нажата кнопка начала процесса (start button), то мы создаем интересующую нас область (Region of Interest, ROI) вокруг прямоугольника, который мы создали ранее, и сохраняем все изображения внутри каталога используя путь определенный ранее.

2. Обучение (тренировка) модели

Теперь, когда мы собрали необходимые нам изображения, нам нужно передать их в нейронную сеть и начать процесс ее обучения чтобы в дальнейшем автоматически распознавать жесты пользователя. Для этого откройте файл training.py в каталоге Game и вставьте в него фрагмент кода, приведенный в конце данной статьи. Затем начните процесс обучения с помощью команды:

В скрипте training.py мы первым делом подключим (импортируем) необходимые библиотеки. Далее мы укажем путь к каталогу, в котором находятся необходимые нам изображения, и определим класс (class map), с которым мы далее будем работать в программе.

В следующих строках кода мы сконструируем головную часть модели, которая будет помещена на верх базовой модели. Функция (слой) AveragePooling2D рассчитывает среднее выходное значение каждой характеристической карты (feature map) изображения на предыдущем слое. Чтобы избежать переполнения мы используем 50% процент отсева.

Далее в цикле мы будем считывать все изображения, находящиеся в нашем каталоге image. После считывания изображений мы можем начать обучение модели. Но вначале необходимо выполнить шаги предварительной обработки изображений: конвертирование их из формата BGR в формат RGB, изменение их размера до 227×227 пикселов, преобразование их в формат массива (array format).

После того как наша модель распознавания будет готова мы будем компилировать ее с помощью оптимизатора Adam.

Затем мы начнем тренировку (обучение) модели и после того как обучение будет закончено, мы сохраним модель под именем “game-model.h5”.

3. Распознавание жестов рук

В заключительной части нашего проекта мы будем использовать тренировочные данные для распознавания каждого жеста рук из видеопотока реального времени. Для этого откройте файл game.py в каталоге Game и вставьте в него фрагмент кода, приведенный в конце статьи.

В начале скрипта game.py мы подключим все необходимые пакеты. Затем создадим необходимый нам класс.

Функция calculate_winner в качестве входных аргументов будет использовать ход пользователя (то есть какой из трех предметов он показал с помощью жеста – камень, ножницы или бумага) и ход платы Raspberry Pi и затем на основании этого определять победителя – пользователя или плату.

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

Затем внутри цикла мы будем создавать два прямоугольника – на левой и правой стороне кадра. В прямоугольнике на левой стороне будет отображаться ход пользователя, а в прямоугольнике на правой стороне – ход платы Raspberry Pi. После этого мы будем извлекать часть изображения кадра, находящуюся в прямоугольнике с ходом пользователя, преобразовывать ее в формат RGB и сжимать ее до размера 227×227.

После этого мы будем использовать модель, которую натренировали ранее, и распознавать жест руки. Затем мы будем сравнивать полученный код с кодом в нашем классе (class map) и, таким образом, получать название жеста пользователя.

В следующем фрагменте кода мы будем проверять сделал ли пользователь ход или нет. Если он сделал ход, то мы будем делать случайный ход платой Raspberry Pi и затем определять победителя. Если пользователь не сделал ход (то есть его ход равен ‘nothing’), то мы будем ждать пока пользователь сделает ход.

Далее мы будем использовать функцию cv2.putText чтобы отобразить ходы пользователя и платы на экране, а также отобразить победителя.

Мы будем отображать ход платы Raspberry Pi внутри прямоугольника, который мы создали ранее. Плата будет случайным образом выбирать изображение, хранящееся в каталоге ‘test_img’.

Тестирование работы проекта

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

Подключение модуля камеры к плате Raspberry Pi

После этого запустите на выполнение скрипт game.py. Спустя несколько секунд после этого вы должны увидеть на экране всплывающее окно с двумя прямоугольниками. В левом прямоугольнике будет отображаться ход пользователя, а в правом – ход платы. Отрегулируйте положение своей руки внутри прямоугольника и сделайте ход. После того ка плата распознает ваш жест, она сделает свой ход и определит победителя, сравнив ваш ход и свой.

Тестирование работы проекта распознавания жестов

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

Исходный код программ проекта на Python

Видео, демонстрирующее работу проекта

Источник статьи

(Проголосуй первым!)
Загрузка...
2 702 просмотров

Комментарии

Распознавание жестов с помощью Raspberry Pi и OpenCV — 3 комментария

  1. Добрый день!
    При импорте keras_squeezenet выдает ошибку:
    ImportError: cannot import name 'get_config' from 'tensorflow.python.eager.context' (/usr/local/lib/python3.7/dist-packages/tensorflow/python/eager/context.py)
    Не знаете ли вы, как её разрешить.
    Заранее спасибо.

    • Добрый вечер, пока нахожусь в отпуске, к сожалению, не могу помочь вам в вашем вопросе

    • Добрый день! Можно задать вопрос? У вас разрешилась эта проблема? Я сейчас пытаюсь ее решить

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *