Распознавание лиц на Raspberry PI

МЕНЮ


Главная страница
Поиск
Регистрация на сайте
Помощь проекту
Архив новостей

ТЕМЫ


Новости ИИРазработка ИИВнедрение ИИРабота разума и сознаниеМодель мозгаРобототехника, БПЛАТрансгуманизмОбработка текстаТеория эволюцииДополненная реальностьЖелезоКиберугрозыНаучный мирИТ индустрияРазработка ПОТеория информацииМатематикаЦифровая экономика

Авторизация



RSS


RSS новости


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

С каждым годом расширяется область применения таких систем. Например, пользователи могут приобрести у Google систему Nest — Nest Cam IQ Indoor, стоимостью 349 долларов с интеграцией в умный дом и возможностью распознавания лиц по подписке (за 10 долларов в месяц). И отечественных аналогов для частного пользования немало. Различные СКУД (системы контроля и управления доступом) от Ростелекома, HikVision, VisionLabs и других фирм. Описание зачастую мутное, опыт работы в реальных условиях можно найти на YouTube по запросу «Умный домофон не пускает мужчину домой».

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

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

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

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

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

Обычно в качестве базы для локальной системы распознавания лиц используется компьютер или ноутбук с мощным графическим ускорителем. Предпочтительны видеокарты Nvidia из-за архитектуры CUDA, позволяющей существенно увеличить вычислительную производительность системы.

Вопреки расхожему мнению, алгоритмы распознавания лиц могут работать и на системах с небольшой вычислительной мощностью. Как например одноплатный микрокомпьютер Raspberry PI 4B с производительностью старого андройд смартфона. Именно такой микрокомпьютер с 4гб оперативной памяти и 4-ядерным процессором частотой 1.5 ГГц был использован в данном проекте.

В качестве алгоритма распознавания лиц была использована библиотека face-recognition для python. Эта библиотека работает с моделью распознавания лиц от dlib. Устанавливается достаточно просто (cv2 для отображения картинки с камеры):

pip install face-recognition, opencv-python

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

import face_recognition import numpy as np import cv2   # векторные представления лиц, имена, user_id в БД known_face_encodings, known_face_names, known_face_uids = [], [], []  def run_rec():     video_capture = cv2.VideoCapture(0, cv2.CAP_DSHOW)     while video_capture.isOpened():         # чтение кадра с камеры         ret, frame = video_capture.read()         # уменьшение разрешения (для быстродействия)         divideint = 2         small_frame = cv2.resize(frame, (0, 0),     fx=1 / divideint, fy=1 / divideint)         # уменьшение размерности матрицы изображения, аналог [:, :, ::-1]          rgb_small_frame = cv2.cvtColor(small_frame, cv2.COLOR_BGR2RGB)         # обрабатывается каждый 3й кадр (для быстродействия)         if process_this_frame % 3 == 0:             # расположение лиц             face_locations = face_recognition.face_locations(rgb_small_frame)             # преобразование лиц в векторы             face_encodings = face_recognition.face_encodings(rgb_small_frame,    face_locations)             # сравнение обнаруженных лиц с лицами в базе             for face_encoding in face_encodings:                 name = "Unknown"                 # вычисление векторного расстояния (мера схожести векторов)                 # known_face_encodings -                  face_distances = face_recognition.face_distance(known_face_encodings, face_encoding)                 # определение индекса максимально похожего лица                 best_match_index = np.argmin(face_distances)                 # проверка на степень похожести                  # похожи если векторное расстояние расстояние меньше 0.6                 if face_distances[best_match_index] < 0.6:                     # имя обнаруженного лица для пользователя                     name = known_face_names[best_match_index]                     # user_id лица для внутреннего использования                     uid = known_face_uids[best_match_index] 

Тестирование системы производилось на базе данных ORL, содержащей изображения лиц с небольшими изменениями освещения, масштаба, пространственных поворотов, положения и различными эмоциями. База представляет собой 400 фотографий 40 разных людей. Все фото представлены в градации серого.

Обычно эта база используется для обучения алгоритмов распознавания лиц, но я решил проверить качество работы и быстродействие алгоритма на основе face-recognition. В результате, алгоритм, работающий на Raspberry PI 4B смог обнаружить 376 лиц за 7 секунд.

import os import glob import face_recognition import time   start = time.time() faces_folder_path = './orl_faces' cnt = 0  for f in glob.glob(os.path.join(faces_folder_path, "*.jpg")):     print("Processing file: {}".format(f))     #загрузка фото     img = face_recognition.load_image_file(f)     #обнаружение лица на фотро     face_locations = face_recognition.face_locations(img)     #подсчет     # face_locations - список элементов (лиц)     # в списке столько элементов, сколько лиц на фото     print("Number of myfaces detected: {}".format(len(face_locations)))     if len(face_locations) != 0:          cnt += 1  print(f'total myfaces detected {cnt}') print(f'total seconds spent {int(time.time() - start)}') 

Так, например, компьютер на процессоре Intel Core I5 смог обнаружить те-же 376 лиц примерно за 2 секунды.

Но показатели этого теста можно рассматривать только в контексте скорости обнаружения лица в кадре. Неотъемлемой частью алгоритма распознавания лиц является сравнение лица в кадре с лицами в базе системы. Для этого необходимо преобразовать картинку в векторное представление и сравнить со всеми лицами в базе. К тому же, необходимо было организовать подключение к базе данных с постоянным обновлением данных в ней. Для управления базой данных была использована СУБД SQLite. Она отличается от других СУБД простотой настройки и удобством использования в малопроизводительных платформах, как Raspberry PI. Через постоянные обращения к базе и определяется принадлежность лица в объективе камеры системы к лицам, добавленным в систему как авторизованные пользователи; осуществляется логирование посещений. Эти части алгоритма (векторное преобразование, обращение к базе, сравнение обнаруженного лица с лицами в базе) и представляют собой самую ресурсоемкую его часть. Обращение к базе:

def get_db():     conn = sqlite3.connect("face_db.sqlite3")     cursor = conn.cursor()     cursor.execute("SELECT * FROM FRS")     facecount = cursor.fetchall()      known_face_encodings = []     known_face_names = []     known_face_uids = []     face_in_home = []      for i in range(len(facecount)):         a = pickle.loads(facecount[i][5])         known_face_encodings.append(a)         known_face_names.append(facecount[i][1])         known_face_uids.append(facecount[i][0])         face_in_home.append(facecount[i][10])      return known_face_encodings,  known_face_names,  known_face_uids,  face_in_home, conn 

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

import numpy as np import cv2  # запуск камеры video_capture = cv2.video_capture(0, cx2.CAP_DSHOW)  # изменение размеров и имени окна для показа изображения video_capture.set(3, 800) video_capture.set(4, 448) сv2.namedWindow('Video', cv2.WINDOW_NORMAL) cv2.resizeWindow('Video', 800, 448)  # расположение краев прямоугольника, обозначающего лицо в кадре; имя for (top, right, bottom, left), name in zip(face_locations, face_names):      # рисуем прямоугольник вокруг лица     cv2.rectangle(frame, (left, top), (right, bottom), (107, 168, 0), 2)      # рисует плашку под текст с именем пользователя     cv2.rectangle(frame, (left, bottom - 23), (right, bottom), (107, 168, 0), cv2.FILLED)     cv2.putText(frame, name, (left + 6, bottom - 6), cv2.FONT_ITALIC, 0.5, (0, 0, 0), 1)          # отображение состояния системы     cv2.rectangle(frame, (8, 5), (228, 64), (255, 255, 255), cv2.FILLED)     cv2.putText(frame, 'RECOGNITION IN PROGRESS', (10, 20), cv2.FONT_HERSHEY_PLAIN, 1, (0, 0, 0), 2)     cv2.putText(frame, 'Model: face-recognition', (10, 40), cv2.FONT_HERSHEY_PLAIN, 1, (0, 0, 0), 2) 

В реальных условиях, при работе с потоковым видео, при наличии лица в кадре, данный алгоритм показывал скорость в 1-2 обработанных кадра в секунду (обнаружение лица, сравнение с лицами – эталонами):

Без показа видео количество обработанных кадров поднялось до около-стабильных 2 FPS. Небольшое изменение, но очень важное в такой системе, реализуемой на одноплатном микрокомпьютере.

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

Бот находится на стадии MVP, но уже имеет достаточно разных функций для обеспечения автономной и относительно стабильной работы системы. В числе функций:

— включение/выключение функции распознавания лиц (для снижения нагрузки);

— создание и занесение в базу лиц через отправку фотографий чат-бота;

— проверка журнала посещения (только для пользователей, вручную добавленных в базу);

— получение фотографии с камеры системы распознавания в любой момент;

— ограничение доступа к функциям чат-бота неавторизованным пользователям.

Работа функций в чат-боте:

Включение, проверка состояния
Добавление лиц в базу
Проверка логов посещения
Получение фото с камеры

В заключении хочется сказать, что функционал системы по большому счету ограничен только воображением. И конечно же, навыками программирования. Несмотря на то, что мощность Raspberry ограничена, у неё очень много возможностей, вплоть до управления системой умного дома. Да, проект на данный момент далек от завершающей стадии, но уже можно с уверенностью сказать – домашняя система распознавания лиц возможна и на одноплатном микрокомпьютере.


Источник: newtechaudit.ru

Комментарии: