Отслеживание лиц с помощью Arduino и OpenCV


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

В данной статье мы рассмотрим отслеживание человеческих лиц с помощью платы Arduino, библиотеки OpenCV и языка программирования Python. Для обнаружения лица человека в видеопотоке мы будем использовать каскады (классификаторы) Хаара (Harr cascade classifiers) из библиотеки OpenCV, а для отслеживания его местоположения мы применим сервомотор, который будет управлять движениями камеры. Управляться сервомотор будет с помощью команд от платы Arduino.

Пример отслеживания лицРанее на нашем сайте мы уже рассматривали проект робота на Arduino, распознающего и отслеживающего лица, в основе работы которого лежало специальное приложение для Android. Но данный проект отслеживания лиц с помощью Arduino является по сравнению с ним более “продвинутым”, поскольку использует возможности такой общепризнанной и весьма мощной библиотеки для обработки изображений как OpenCV.

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

Аппаратное обеспечение

  1. Плата Arduino Uno (купить на AliExpress).
  2. USB камера.
  3. Сервомотор SG90 (2 шт.) (купить на AliExpress).
  4. Макетная плата.
  5. Соединительные провода.

Программное обеспечение

  1. Arduino IDE.
  2. Python 3.8.

Общие принципы работы проекта

Алгоритмы обнаружения человеческих лиц идентифицируют и локализуют местоположение лиц, игнорируя при этом все фоновые объекты: занавески, ока, деревья и др. Библиотека OpenCV для обнаружения лиц использует так называемые классификаторы Хаара. В процессе анализа каждый кадр видео потока последовательно проходит через несколько классификаторов и если он прошел через все классификаторы, то лицо считается обнаруженным, иначе кадр отбрасывается, то есть обнаружение лица на нем не фиксируется.

Библиотека OpenCV возвращает декартовы координаты (x и y) фрагмента изображения с обнаруженным лицом с высотой (height) и шириной (width) изображения. После этого вычислить координаты центра этого фрагмента изображения можно в соответствии с выражениями: x+width/2 и y+height/2.

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

Разумеется, вычислительные возможности платы Arduino Uno значительно скромнее, чем у платы Raspberry Pi, поэтому библиотеку OpenCV на ней непосредственно использовать нельзя. Да и объем памяти не получит. Поэтому в нашем случае использование библиотеки OpenCV для обнаружения лиц производится с помощью программы на Python, запущенной на персональном компьютере или ноутбуке. В этом случае принцип работы нашего проекта можно изобразить следующим рисунком:

Принцип работы нашего проекта по отслеживанию лицДалее координаты фрагмента изображения с обнаруженным лицом человека по последовательному каналу связи передаются с компьютера в плату Arduino Uno с помощью библиотеки pyserial. На основе значений этих координат плата Arduino Uno управляет двумя подключенными к ней сервомоторами (как подключить сервомотор к плате Arduino можно прочитать в этой статье), которые и реализуют механизм поворота/наклона USB камеры, с которой осуществляется считывание видео потока. Если координаты центра обнаруженного лица находятся далеко от центра изображения, то производится коррекция положения камеры на 2 градуса в сторону, обеспечивающую приближение центра лица к центру изображения.

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

Обнаружение лица

Автор проекта (ссылка на оригинал приведена в конце статьи) для обнаружения лиц использовал файл 'haarcascade_frontalface_default.xml'. Этот файл представляет собой заранее обученную модель для распознавания человеческих лиц и его можно скачать по этой ссылке.

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

После этого для обнаружения лиц в программе можно использовать функцию cv2.CascadeClassifier.detectMultiScale(), в которой значение 'scale factor' установлено равным 1.1 (значение по умолчанию), а значение 'minNeighbour' равно 6. Эта функция возвращает декартовы координаты изображения вместе с его высотой и шириной (height и width). Увеличение значения 'minNeighbour' может улучшить качество обнаружения (точность) лиц, однако приведет к уменьшению скорости работы программы, что, в свою очередь, приведет к задержке команды, подаваемой на сервомоторы. Автор проекта в результате проведенных экспериментов определил, что значение 6 параметра 'minNeighbour' в данном случае является оптимальным.

Для улучшения точности определения положения лиц желательно чтобы фон на заднем плане изображения был по возможности однородным.

Расчет координат

Библиотека OpenCV возвращает координаты обнаруженного лица в пикселах. По умолчанию разрешение видео устанавливается равным 640*480. Возвращаемые координаты определяют верхний левый угол изображения вместе со значениями его высоты и ширины (height и width). Мы будем рассчитывать координаты центра изображения по формулам x+width/2 и y+height/2 и показывать его на изображении зеленой точкой. Далее эти координаты передаются плате Arduino, которая дает команды сервомоторам на перемещение камеры вверх/вниз и влево/вправо.

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

Пример работы программы по отслеживанию лицПередача последовательных данных плате Arduino

Автор проекта провел много экспериментов прежде чем нашел быстрый способ последовательной передачи найденных значений координат в плату Arduino. В результате он решил использовать функцию Serial.parseInt(), которая извлекает числа целого типа (integer) из поступающего последовательного потока байтов. Описание этой функции можно посмотреть здесь.

Программа на python в нашем проекте передает координаты центра изображения в виде строки, например, в строке "X100Y200" значение 100 будет соответствовать координате x, а значение 200 – координате y.

Управление сервомоторами

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

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

Используемые библиотеки

Для проекта требуются библиотеки pyserial и opencv, которые можно скачать с помощью установщика pip. Автор проекта использовал версию python 3.8 и версию OpenCV 4.4.0, поэтому перед реализацией проекта убедитесь в том, что у вас такие же версии python и OpenCV, или выше. Также удостоверьтесь в том, что скачанный XML файл с моделью обнаружения лиц помещен в тот же самый каталог, откуда вы будете запускать скрипт на python.

Также вам необходимо внести изменения в строку 9 представленного далее кода программы – в ней вы должны изменить номер COM порта компьютера, к которому подключена плата Arduino, на свой.

Пример работы проекта вы можете посмотреть на следующем gif изображении.

Пример работы проекта отслеживания лиц на Arduino

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

Код скетча для Arduino

Код программы на python

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

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

Комментарии

Отслеживание лиц с помощью Arduino и OpenCV — 18 комментариев

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

  1. Здравствуйте! Эта плата ардуино подойдет?
    Ссылка: ozon.ru/product/plata-kontrollera-arduino-uno-r3-atmega-328-ch340g-arduino-ide-sovmestimaya-622002433/?sh=darqblYljw&reviewsVariantMode=2

    • Добрый день. Да, должна подойти если описание соответствует действительности

      • Здравствуйте еще раз! Все заказал плату, пришла
        Только куда подключать два желтых кабелей сервомоторов?
        И можно ли их вместе питать подключив в порты 5V и GND?

        • Добрый вечер. Вот, посмотрите статью про подключение серводвигателя к Arduino Uno, многие вопросы у вас отпадут. Два сервомотора нежелательно питать от платы Arduino если она получает питание по USB кабелю, в статье написано что в этом случае желательно запитать плату Arduino от адаптера 9V.

          • Спасибо все подключил!
            Вы не знаете как решить проблему, что сервомоторчики досих пор двигаются когда зелёная точка в белом квадрате?
            Сервомоторчики: MicroServo9G SG90
            И как убавить скорость их вращения?

            • Рад за вас. Но обозначенную вами проблему как решить, к сожалению, не знаю, лично ни я, ни мои ученики этот проект не собирали. Хотя скорость вращения сервомоторов вроде от частоты ШИМ сигнала зависит. Для Arduino Uno, насколько я знаю, эту частоту можно изменить с помощью настройки таймеров. У меня на сайте такой информации нет, но в сети она есть, найти несложно.

  2. вопрос такой, когда уже собрал всю работу добавил код и загрузил на плату, как нужно запустить весь проект, чтобы камера начала захватывать лицо?

    • Ну нужно еще на компьютере запустить на выполнение код представленной программы на python

  3. здравствуйте, Traceback (most recent call last):
    File "C:/Users/Shoha/AppData/Local/Temp/arduino/sketches/recognition/py.py", line 15, in
    faces= face_cascade.detectMultiScale(gray,1.1,6) #detect the face (обнаруживаем лицо)
    cv2.error: OpenCV(4.7.0) D:\a\opencv-python\opencv-python\opencv\modules\objdetect\src\cascadedetect.cpp:1689: error: (-215:Assertion failed) !empty() in function 'cv::CascadeClassifier::detectMultiScale' выдает вот такую ошибку в коде python, как пофиксить не знаете?

  4. Здравствуйте, а какого вида соединительные провода используются в работе? МАМА-ПАПА?

    • Добрый день, ну это зависит от того какие у вас накладки на контакты платы Ардуино (обычно они под провод типа ПАПА, но возможны и другие вариации) и какие у вас коннекторы для подключения сервомотора

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

    • Добрый вечер. К сожалению не могу. Эту статью я только перевел, но ни я, ни мои студенты пока данный проект не собирали. Если у вас есть какой то конкретный вопрос по данному проекту, то могу попробовать на него ответить

  6. Здравствуйте.

    Можно ли вместо двух сервомоторов sg90, использовать один sg90, а второй шаговый двигатель 28byj-48 ?

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

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