Как обнаружить и извлечь лица из изображения с OpenCV и Python

_Автор выбрал Open Internet / Free Speech Fund для получения пожертвования в рамках https://do.co/w4do-cta [Писать для DOnations] программа.

Вступление

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

Https://docs.opencv.org/3.4.3/d7/d8b/tutorial_py_face_detection.html[Haar Cascade] - это метод обнаружения объекта, используемый для поиска интересующего объекта на изображениях. Алгоритм обучается на большом количестве положительных и отрицательных образцов, где положительные образцы представляют собой изображения, которые содержат интересующий объект. Отрицательные образцы - это изображения, которые могут содержать что угодно, кроме нужного объекта. После обучения классификатор может затем найти интересующий объект на любых новых изображениях.

В этом руководстве вы будете использовать предварительно обученную модель Haar Cascade из OpenCV и https: //www.python.org/[Python] для обнаружения и извлечения лиц из изображения. OpenCV - это библиотека программирования с открытым исходным кодом, которая используется для обработки изображений.

Предпосылки

  • Https://www.digitalocean.com/community/tutorial_series/how-to-install-and-set-up-a-local-programming-environment-for-python-3[local среда разработки Python 3], включая https : //pypi.org/project/pip/ [+ pip +], инструмент для установки пакетов Python, и https://docs.python.org/3/library/venv.html [+ venv +], для создания виртуальных сред.

Шаг 1 - Настройка локальной среды

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

Создайте каталог для проекта с помощью команды + mkdir +:

mkdir

Перейдите во вновь созданный каталог:

cd

Далее вы создадите виртуальную среду для этого проекта. Виртуальные среды изолируют разные проекты, поэтому различные зависимости не вызывают сбоев. Создайте виртуальную среду с именем + face_scrapper + для использования с этим проектом:

python3 -m venv

Активировать изолированную среду:

source /bin/activate

Теперь вы увидите, что вашему приглашению предшествует имя вашей виртуальной среды:

Теперь, когда вы активировали свою виртуальную среду, вы будете использовать + nano + или ваш любимый текстовый редактор, чтобы создать файл + needs.txt +. Этот файл указывает необходимые зависимости Python:

nano requirements.txt

Далее вам нужно установить три зависимости для завершения этого урока:

  • + numpy +: numpy - это библиотека Python, которая добавляет поддержку больших многомерных массивов. Он также включает в себя большой набор математических функций для работы с массивами.

  • + opencv-utils +: расширенная библиотека для OpenCV, включающая вспомогательные функции.

  • + opencv-python +: это основной модуль OpenCV, который использует Python.

Добавьте в файл следующие зависимости:

requirements.txt

numpy
opencv-utils
opencv-python

Сохраните и закройте файл.

Установите зависимости, передав файл + needs.txt + менеджеру пакетов Python + pip +. Флаг + -r + указывает местоположение файла + needs.txt +.

pip install -r requirements.txt

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

Шаг 2 - Написание и запуск скрипта детектора лиц

В этом разделе вы напишите код, который будет принимать изображение в качестве входных данных и возвращать две вещи:

  • Количество лиц, найденных на входном изображении.

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

Начните с создания нового файла для хранения вашего кода:

nano app.py

В этом новом файле начните писать свой код, сначала импортировав необходимые библиотеки. Здесь вы импортируете два модуля: + cv2 + и + sys +. Модуль + cv2 + импортирует библиотеку + OpenCV + в программу, а + sys + импортирует обычные функции Python, такие как + argv +, которые будет использовать ваш код.

app.py

import cv2
import sys

Далее вы укажете, что входное изображение будет передано в качестве аргумента скрипту во время выполнения. Способ Pythonic для чтения первого аргумента состоит в присвоении переменной, возвращаемой функцией + sys.argv [1] +:

app.py

...
imagePath = sys.argv[1]

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

app.py

...
image = cv2.imread(imagePath)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

Функция + .imread () + берет входное изображение, которое передается скрипту в качестве аргумента, и преобразует его в объект OpenCV. Затем функция OpenCV + .cvtColor () + преобразует объект входного изображения в объект в градациях серого.

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

app.py

...
faceCascade = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_frontalface_default.xml")
faces = faceCascade.detectMultiScale(
       gray,
       scaleFactor=1.3,
       minNeighbors=3,
       minSize=(30, 30)
)

print("Found {0} Faces!".format(len(faces)))

Этот код создаст объект + faceCascade +, который загрузит файл Haar Cascade с помощью метода + cv2.CascadeClassifier +. Это позволяет Python и вашему коду использовать каскад Хаара.

Затем код применяет метод OpenCV + .detectMultiScale () + к объекту + faceCascade +. Это создает список прямоугольников_ для всех обнаруженных лиц на изображении. Список прямоугольников представляет собой набор положений пикселей на изображении в виде + Rect (x, y, w, h) +.

Вот сводка других параметров, которые использует ваш код:

  • + серый +: указывает на использование объекта изображения в оттенках серого OpenCV, который вы загрузили ранее.

  • + scaleFactor +: этот параметр указывает скорость уменьшения размера изображения при каждом масштабе изображения. Ваша модель имеет фиксированный масштаб во время обучения, поэтому входные изображения можно уменьшить для лучшего обнаружения. Этот процесс останавливается после достижения порогового предела, определенного + maxSize + и + minSize +.

  • + minNeighbors +: этот параметр указывает, сколько соседей или обнаружений должен иметь каждый прямоугольник-кандидат для его сохранения. Более высокое значение может привести к меньшему количеству ложных срабатываний, но слишком высокое значение может исключить истинные положительные результаты.

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

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

Далее вы будете использовать метод OpenCV + .rectangle () +, чтобы нарисовать прямоугольник вокруг обнаруженных лиц:

app.py

...
for (x, y, w, h) in faces:
   cv2.rectangle(image, (x, y), (x+w, y+h), (0, 255, 0), 2)

Этот код использует for loop для итерации по списку местоположений пикселей, возвращаемых методом + faceCascade.detectMultiScale + для каждого обнаруженного объекта. Метод + rectangle + будет принимать четыре аргумента:

  • + image + говорит коду рисовать прямоугольники на исходном входном изображении.

  • + (x, y), (x + w, y + h) + - четыре положения пикселя для обнаруженного объекта. + rectangle + будет использовать их для поиска и рисования прямоугольников вокруг обнаруженных объектов на входном изображении.

  • + (0, 255, 0) + - цвет фигуры. Этот аргумент передается как кортеж для BGR. Например, вы бы использовали + (255, 0, 0) + для синего цвета. Мы используем зеленый в этом случае.

  • + 2 + - толщина линии, измеренная в пикселях.

Теперь, когда вы добавили код для рисования прямоугольников, используйте метод OpenCV + .imwrite () +, чтобы записать новое изображение в вашу локальную файловую систему как +face_detected.jpg +. Этот метод вернет + true +, если запись была успешной, и + false +, если не удалось записать новое изображение.

app.py

...
status = cv2.imwrite('faces_detected.jpg', image)

Наконец, добавьте этот код, чтобы напечатать возвращаемый статус + true или` + false` функции + .imwrite () + на консоль. Это даст вам знать, была ли запись успешной после запуска скрипта.

app.py

...
print ("Image faces_detected.jpg written to filesystem: ",status)

Готовый файл будет выглядеть так:

app.py

import cv2
import sys

imagePath = sys.argv[1]

image = cv2.imread(imagePath)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

faceCascade = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_frontalface_default.xml")
faces = faceCascade.detectMultiScale(
   gray,
   scaleFactor=1.3,
   minNeighbors=3,
   minSize=(30, 30)
)

print("[INFO] Found {0} Faces!".format(len(faces)))

for (x, y, w, h) in faces:
   cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)

status = cv2.imwrite('faces_detected.jpg', image)
print("[INFO] Image faces_detected.jpg written to filesystem: ", status)

Убедившись, что все введено правильно, сохраните и закройте файл.

Ваш код завершен, и вы готовы запустить скрипт.

Шаг 3 - Запуск скрипта

На этом этапе вы будете использовать изображение для проверки вашего скрипта. Когда вы найдете изображение, которое хотите использовать для тестирования, сохраните его в том же каталоге, что и ваш скрипт + app.py +. Этот урок будет использовать следующее изображение:

изображение: https: //assets.digitalocean.com/articles/CART-63965/people_with_phones.png [Входное изображение четырех человек, смотрящих на телефоны]

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

curl -O https://assets.digitalocean.com/articles/CART-63965/people_with_phones.png

Если у вас есть изображение для проверки сценария, запустите сценарий и укажите путь к изображению в качестве аргумента:

python app.py

Как только скрипт завершит работу, вы получите вывод, подобный этому:

Output[INFO] Found 4 Faces!
[INFO] Image faces_detected.jpg written to filesystem:

Выходные данные + true + сообщают вам, что обновленное изображение было успешно записано в файловую систему. Откройте изображение на вашем локальном компьютере, чтобы увидеть изменения в новом файле:

изображение: https: //assets.digitalocean.com/articles/CART-63965/people_with_phones_detection.png [Вывод изображения с обнаруженными лицами]

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

Шаг 4 - Извлечение лиц и сохранение их локально (необязательно)

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

Начните с открытия файла + app.py + в текстовом редакторе:

nano app.py

Затем добавьте выделенные строки под строкой + cv2.rectangle +:

app.py

...
for (x, y, w, h) in faces:
   cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)



...

Объект + roi_color + отображает местоположения пикселей из списка + face + на исходном входном изображении. Переменные + x +, + y +, + h + и + w + являются позициями пикселей для каждого из объектов, обнаруженных с помощью метода + faceCascade.detectMultiScale +. Затем код печатает вывод о том, что объект был найден и будет сохранен локально.

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

Обновленный скрипт + app.py + будет выглядеть так:

app.py

import cv2
import sys

imagePath = sys.argv[1]

image = cv2.imread(imagePath)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

faceCascade = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_frontalface_default.xml")
faces = faceCascade.detectMultiScale(
   gray,
   scaleFactor=1.3,
   minNeighbors=3,
   minSize=(30, 30)
)

print("[INFO] Found {0} Faces.".format(len(faces)))

for (x, y, w, h) in faces:
   cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
   roi_color = image[y:y + h, x:x + w]
   print("[INFO] Object found. Saving locally.")
   cv2.imwrite(str(w) + str(h) + '_faces.jpg', roi_color)

status = cv2.imwrite('faces_detected.jpg', image)
print("[INFO] Image faces_detected.jpg written to filesystem: ", status)

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

Теперь, когда вы обновили код, вы готовы запустить скрипт еще раз:

python app.py

Вы увидите похожий результат, как только ваш скрипт завершит обработку изображения:

Output[INFO] Found 4 Faces.
[INFO] Object found. Saving locally.
[INFO] Object found. Saving locally.
[INFO] Object found. Saving locally.
[INFO] Object found. Saving locally.
[INFO] Image faces_detected.jpg written to file-system:

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

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

изображение: https: //assets.digitalocean.com/articles/CART-63965/directory.png [Список каталогов]

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

изображение: https: //assets.digitalocean.com/articles/CART-63965/extracted_faces.png [извлеченные лица]

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

Заключение

В этом руководстве вы написали сценарий, который использует OpenCV и Python для обнаружения, подсчета и извлечения лиц из входного изображения. Вы можете обновить этот скрипт для обнаружения различных объектов, используя другой предварительно обученный каскад Хаара из библиотеки OpenCV, или вы можете узнать, как https://docs.opencv.org/3.3.0/dc/d88/tutorial_traincascade.html [тренируйся сам] Хаар Каскад.

Related