Отслеживание лиц с помощью 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. Соединительные провода.

Реклама: ООО "АЛИБАБА.КОМ (РУ)" ИНН: 7703380158

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

  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

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

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

Комментарии

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

  1. Здравствуйте, возникла проблема с сервоприводами, после запуска программы, они некоторое время двигаются, а после перестают, подключал по такой схеме, в чем может быть причина?
    Пин SG90 (1й) Пин SG90 (2й) Arduino Uno
    Коричневый Коричневый GND
    Красный Красный 5V
    Оранжевый Оранжевый 9 (для 1-го) и 10 (для 2-го)

    • Добрый вечер.
      Скорее всего, проблема в том, что сервоприводы через некоторое время перестают двигаться, вероятно, связана с питанием. На вашей схеме оба сервопривода запитаны от встроенного регулятора 5V платы Arduino Uno, который может обеспечить ток до 500 мА (при питании платы через USB — всего около 400-500 мА). Два сервопривода SG90 при работе могут потреблять пиковый ток до 500–700 мА (каждый до 250–300 мА под нагрузкой). В итоге:
      При старте сервы двигаются, напряжение проседает, но ещё терпимо.
      Через несколько секунд/минут встроенный регулятор перегревается и уходит в защиту (отключается), либо напряжение падает ниже рабочего уровня — сервы останавливаются (а плата может сброситься или работать нестабильно).

      Как это исправить
      1. Подать отдельное питание на сервоприводы (рекомендуется)
      Подключите питание сервоприводов не от 5V пина Arduino, а от внешнего источника 5–6 В, способного отдать 1 А и более. Схема:
      «+» серв (красный провод) → к «+» внешнего источника (например, 4×AA батарейки — 4,8–6 В, или стабилизатор 5В/1А от 7–12 В).
      «-» серв (коричневый провод) → к GND внешнего источника И к GND Arduino (объединить «земли»).
      Сигнальный провод (оранжевый) → к пинам 9 и 10 Arduino как и раньше.
      Важно: Общая земля (GND) внешнего источника и Arduino обязательна, иначе сигнал не будет работать.

      2. Установить большой конденсатор рядом с сервами
      Если нет возможности внешнего питания прямо сейчас, попробуйте поставить электролитический конденсатор 470–1000 мкФ (на 6,3 В или выше) параллельно выводам 5V и GND на плате, ближе к сервоприводам. Это сгладит пиковые броски тока, но не решит проблему перегрева регулятора при длительной работе.

      3. Временно отключить один сервомотор
      Отключите один из сервоприводов и проверьте — будет ли второй работать стабильно. Так вы точно убедитесь, что причина в питании.

      Другие возможные причины (менее вероятны)
      1. Потеря связи по COM-порту — код на Python отправляет координаты, но плата перестаёт их получать (ошибка в порте, залипание буфера). Проверьте, горят ли светодиоды RX/TX на Arduino при движении серв.
      2. Ошибка в коде Python/Arduino — возможно, после некоторого времени программа на компьютере «засыпает» или перестаёт отправлять данные, если лицо не обнаруживается. Добавьте в Python-скрипт print(x, y) в цикл, чтобы видеть, отправляются ли координаты.
      3.Неисправные сервоприводы — SG90 могут выходить из строя при недопустимой нагрузке (заклинивание). Попробуйте подключить каждый серв отдельно к Arduino с простым скетчем (например, поворот от 0 до 180 градусов каждую секунду) — работают ли они стабильно?

      Итог
      С большой вероятностью проблема в перегрузке регулятора 5V на Arduino. Сделайте отдельное питание для сервоприводов с общей землёй, и они должны работать постоянно, не останавливаясь.
      Если после этого сервы всё равно останавливаются через некоторое время — проверьте, не перегреваются ли они сами (это может быть из-за чрезмерной механической нагрузки или дефекта).

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

  2. Здравствуйте! Эта плата ардуино подойдет?
    Ссылка: 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, насколько я знаю, эту частоту можно изменить с помощью настройки таймеров. У меня на сайте такой информации нет, но в сети она есть, найти несложно.

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

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

  4. здравствуйте, 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, как пофиксить не знаете?

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

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

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

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

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

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

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

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