Share This
Связаться со мной
Крути в низ
Categories
//Распознавание лиц при помощи Python и OpenCV

Распознавание лиц при помощи Python и OpenCV

19.09.2021Category : Python

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

Содержание

  1. Обнаружение лиц
  2. Распознавание лиц
  3. Что такое OpenCV?
  4. Распознавание лиц с использованием Python
    1. Извлечение признаков лица
    2. Распознавание лиц во время прямой трансляции веб-камеры
    3. Распознавание лиц на изображениях

Что такое обнаружение лиц?

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

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

Существует много алгоритмов обнаружения лиц. Одним из старейших является алгоритм Виолы-Джонса. Он был предложен в 2001 году и применяется по сей день. Чуть позже мы тоже им воспользуемся. После прочтения данной статьи вы можете изучить его более подробно.

Обнаружение лиц обычно является первым шагом для решения более сложных задач, таких как распознавание лиц или верификация пользователя по лицу. Но оно может иметь и другие полезные применения.

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

Что такое распознавание лиц?

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

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

Итак, давайте разберемся, как мы распознаем лица при помощи глубокого обучения. Для начала мы производим преобразование, или, иными словами, эмбеддинг (embedding), изображения лица в числовой вектор. Это также называется глубоким метрическим обучением.

Для облегчения понимания давайте разобьем весь процесс на три простых шага:

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

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

Извлечение признаков

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

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

Теперь давайте разберемся, как это помогает в распознавании лиц разных людей.

raspoznavanie lic pri pomoshhi python i opencv d540194 - Распознавание лиц при помощи Python и OpenCV

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

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

raspoznavanie lic pri pomoshhi python i opencv b37a0de - Распознавание лиц при помощи Python и OpenCV

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

raspoznavanie lic pri pomoshhi python i opencv 80f21ab - Распознавание лиц при помощи Python и OpenCV

Здесь мы не будем заниматься обучением подобной сети. Это требует значительных вычислительных мощностей и большого объема размеченных данных. Вместо этого мы используем уже предобученную Дэвисом Кингом нейронную сеть. Она обучалась приблизительно на 3000000 изображений. Эта сеть выдает вектор длиной 128 чисел, который и определяет основные черты лица.

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

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

raspoznavanie lic pri pomoshhi python i opencv e57dfac - Распознавание лиц при помощи Python и OpenCV

Марк Лутц «Изучаем Python»

Скачивайте книгу у нас в телеграм

Скачать ×

Сравнение лиц

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

raspoznavanie lic pri pomoshhi python i opencv e90b3c1 - Распознавание лиц при помощи Python и OpenCV

Итак, мы передали в сеть две фотографии, одна Владимира Путина, другая Джорджа Буша. Для изображений Буша у нас были вектора (эмбеддинги), а для Путина ничего не было. Таким образом, когда мы сравнили эмбеддинг нового изображения Буша, он был близок с уже имеющимися векторам,и и мы распознали его. А вот изображений Путина в нашей базе не было, поэтому распознать его не удалось.

Что такое OpenCV?

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

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

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

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

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

OpenCV — это библиотека с открытым программным кодом. Она поддерживает различные языки программирования, например R и Python. Работать она может на многих платформах, в частности — на Windows, Linux и MacOS.

Основные преимущества OpenCV:

  • имеет открытый программный код и абсолютно бесплатна
  • написана на C/C++ и в сравнении с другими библиотеками работает быстрее
  • не требует много памяти и хорошо работает при небольшом объеме RAM
  • поддерживает большинство операционных систем, в том числе Windows, Linux и MacOS.

Установка

Здесь мы будем рассматривать установку OpenCV только для Python. Мы можем установить ее при помощи менеджеров pip или conda (в случае, если у нас установлен пакет Anaconda).

1. При помощи pip

При помощи pip процесс установки может быть выполнен с использованием следующей команды:

pip install opencv-python

2. Anaconda

Если вы используете Anaconda, то выполните следующую команду в окружении Anaconda:

conda install -c conda-forge opencv

Распознавание лиц с использованием Python

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

  • OpenCV
  • dlib
  • Face_recognition

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

Библиотека dlib, поддерживая Дэвисом Кингом, содержит реализацию глубокого метрического обучения. Мы ее будем использовать для конструирования векторов (эмбеддингов) изображений, играющих ключевую роль в процессе распознавания лиц.

Библиотека face_recognition, созданная Адамом Гейтгеем, включает в себя функции распознавания лиц dlib и является по сути надстройкой над ней. С ней очень легко работать, и мы будем ее использовать в нашем коде. Имейте ввиду, что ее нужно устанавливать после библиотеки dlib.

Для установки OpenCV наберите в командной строке:

pip install opencv-python

Мы перепробовали множество способов установки dlib под WIndows и простейший способ это сделать — при помощи Anaconda. Поэтому для начала установите Anaconda (вот здесь подробно рассказано, как это делается). Затем введите в терминале следующую команду:

conda install -c conda-forge dlib

Далее, для установки библиотеки face_recognition наберите в командной строке следующее:

pip install face_recognition

Теперь, когда все необходимые модули установлены, приступим к написанию кода. Нам нужно будет создать три файла.

Первый файл будет принимать датасет с изображениями и выдавать эмбеддинг для каждого лица. Эти эмбеддинги будут записываться во второй файл. В третьем файле мы будем сравнивать лица с уже существующими изображениями. А затем мы сделаем тоже самое в стриме с веб-камеры.

Извлечение признаков лица

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

Затем разместите датасет в вашей рабочей директории, то есть там, где выбудете создавать собственные файлы.

А вот сам код:

from imutils import paths import face_recognition import pickle import cv2 import os   # в директории Images хранятся папки со всеми изображениями  imagePaths = list(paths.list_images('Images')) knownEncodings = [] knownNames = [] # перебираем все папки с изображениями for (i, imagePath) in enumerate(imagePaths):     # извлекаем имя человека из названия папки     name = imagePath.split(os.path.sep)[-2]     # загружаем изображение и конвертируем его из BGR (OpenCV ordering)     # в dlib ordering (RGB)     image = cv2.imread(imagePath)     rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)     #используем библиотеку Face_recognition для обнаружения лиц     boxes = face_recognition.face_locations(rgb,model='hog')     # вычисляем эмбеддинги для каждого лица     encodings = face_recognition.face_encodings(rgb, boxes)     # loop over the encodings     for encoding in encodings:         knownEncodings.append(encoding)         knownNames.append(name) # сохраним эмбеддинги вместе с их именами в формате словаря data = {"encodings": knownEncodings, "names": knownNames} # для сохранения данных в файл используем метод pickle f = open("face_enc", "wb") f.write(pickle.dumps(data)) f.close()

Сейчас мы сохранили все эмбеддинги в файл под названием face_enc. Теперь мы можем их использовать для распознавания лиц на изображениях или во время видеострима с веб-камеры.

Распознавание лиц во время прямой трансляции веб-камеры

Вот код для распознавания лиц из прямой трансляции веб-камеры:

import face_recognition import imutils import pickle import time import cv2 import os   # find path of xml file containing haarcascade file  cascPathface = os.path.dirname(  cv2.__file__) + "/data/haarcascade_frontalface_alt2.xml" # load the harcaascade in the cascade classifier faceCascade = cv2.CascadeClassifier(cascPathface) # load the known faces and embeddings saved in last file data = pickle.loads(open('face_enc', "rb").read())   print("Streaming started") video_capture = cv2.VideoCapture(0) # loop over frames from the video file stream while True:     # grab the frame from the threaded video stream     ret, frame = video_capture.read()     gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)     faces = faceCascade.detectMultiScale(gray,                                          scaleFactor=1.1,                                          minNeighbors=5,                                          minSize=(60, 60),                                          flags=cv2.CASCADE_SCALE_IMAGE)       # convert the input frame from BGR to RGB      rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)     # the facial embeddings for face in input     encodings = face_recognition.face_encodings(rgb)     names = []     # loop over the facial embeddings incase     # we have multiple embeddings for multiple fcaes     for encoding in encodings:        # Compare encodings with encodings in data["encodings"]        # Matches contain array with boolean values and True for the embeddings it matches closely        # and False for rest         matches = face_recognition.compare_faces(data["encodings"],          encoding)         # set name =inknown if no encoding matches         name = "Unknown"         # check to see if we have found a match         if True in matches:             #Find positions at which we get True and store them             matchedIdxs = [i for (i, b) in enumerate(matches) if b]             counts = {}             # loop over the matched indexes and maintain a count for             # each recognized face face             for i in matchedIdxs:                 # Check the names at respective indexes we stored in matchedIdxs                 name = data["names"][i]                 # increase count for the name we got                 counts[name] = counts.get(name, 0) + 1             # set name which has highest count             name = max(counts, key=counts.get)             # update the list of names         names.append(name)         # loop over the recognized faces         for ((x, y, w, h), name) in zip(faces, names):             # rescale the face coordinates             # draw the predicted face name on the image             cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)             cv2.putText(frame, name, (x, y), cv2.FONT_HERSHEY_SIMPLEX,              0.75, (0, 255, 0), 2)     cv2.imshow("Frame", frame)     if cv2.waitKey(1) & 0xFF == ord('q'):         break video_capture.release() cv2.destroyAllWindows()

В данном примере для обнаружения лиц использовался метод cv2.CascadeClassifier() из библиотеки OpenCV. Но вы с таким же успехом можете пользоваться и методом face_recognition.face_locations(), как мы уже делали в предыдущем примере.

Распознавание лиц на изображениях

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

import face_recognition import imutils import pickle import time import cv2 import os   # find path of xml file containing haarcascade file cascPathface = os.path.dirname(  cv2.__file__) + "/data/haarcascade_frontalface_alt2.xml" # load the harcaascade in the cascade classifier faceCascade = cv2.CascadeClassifier(cascPathface) # load the known faces and embeddings saved in last file data = pickle.loads(open('face_enc', "rb").read()) # Find path to the image you want to detect face and pass it here image = cv2.imread(Path-to-img) rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # convert image to Greyscale for haarcascade gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) faces = faceCascade.detectMultiScale(gray,                                      scaleFactor=1.1,                                      minNeighbors=5,                                      minSize=(60, 60),                                      flags=cv2.CASCADE_SCALE_IMAGE)   # the facial embeddings for face in input encodings = face_recognition.face_encodings(rgb) names = [] # loop over the facial embeddings incase # we have multiple embeddings for multiple fcaes for encoding in encodings:     # Compare encodings with encodings in data["encodings"]     # Matches contain array with boolean values and True for the embeddings it matches closely     # and False for rest     matches = face_recognition.compare_faces(data["encodings"],     encoding)     # set name =inknown if no encoding matches     name = "Unknown"     # check to see if we have found a match     if True in matches:         # Find positions at which we get True and store them         matchedIdxs = [i for (i, b) in enumerate(matches) if b]         counts = {}         # loop over the matched indexes and maintain a count for         # each recognized face face         for i in matchedIdxs:             # Check the names at respective indexes we stored in matchedIdxs             name = data["names"][i]             # increase count for the name we got             counts[name] = counts.get(name, 0) + 1             # set name which has highest count             name = max(counts, key=counts.get)             # update the list of names         names.append(name)         # loop over the recognized faces         for ((x, y, w, h), name) in zip(faces, names):             # rescale the face coordinates             # draw the predicted face name on the image             cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)             cv2.putText(image, name, (x, y), cv2.FONT_HERSHEY_SIMPLEX,              0.75, (0, 255, 0), 2)     cv2.imshow("Frame", image)     cv2.waitKey(0)

Результат:

raspoznavanie lic pri pomoshhi python i opencv f8223ee - Распознавание лиц при помощи Python и OpenCVraspoznavanie lic pri pomoshhi python i opencv af5dcd9 - Распознавание лиц при помощи Python и OpenCV

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

Перевод статьи «Face Recognition with Python and OpenCV»

raspoznavanie lic pri pomoshhi python i opencv 807b327 - Распознавание лиц при помощи Python и OpenCV

Марк Лутц «Изучаем Python»

Скачивайте книгу у нас в телеграм

Скачать ×

  • 0 views
  • 0 Comment

Leave a Reply

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

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

Свежие комментарии

    Рубрики

    About Author 01.

    blank
    Roman Spiridonov

    Моя специальность - Back-end Developer, Software Engineer Python. Мне 39 лет, я работаю в области информационных технологий более 5 лет. Опыт программирования на Python более 3 лет. На Django более 2 лет.

    Categories 05.

    © Speccy 2020 / All rights reserved

    Связаться со мной
    Close