Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Воган Ли - Python для хакеров (Библиотека программиста) - 2023.pdf
Скачиваний:
8
Добавлен:
07.04.2024
Размер:
14.76 Mб
Скачать

Обнаружение лиц в видеопотоке      283

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

Рис. 9.14. И это не мог нормально сделать!

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

Обнаружение лиц в видеопотоке

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

284      Глава 9. Как различить своих и чужих

Листинг 9.5. Обнаружение лиц в видеопотоке video_face_detect.py

import cv2 as cv

path = "C:/Python372/Lib/site-packages/cv2/data/"

face_cascade = cv.CascadeClassifier(path + 'haarcascade_frontalface_alt.xml')

cap = cv.VideoCapture(0)

while True:

_, frame = cap.read()

face_rects = face_cascade.detectMultiScale(frame, scaleFactor=1.2,

minNeighbors=3)

for (x, y, w, h) in face_rects:

cv.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)

cv.imshow('frame', frame)

if cv.waitKey(1) & 0xFF == ord('q'): break

cap.release()

cv.destroyAllWindows()

После импорта OpenCV настраиваем путь на каскадный классификатор Хаара, как делали это в блоке листинга 9.1. Я здесь использую файл haarcascade_frontalface_alt.xml, поскольку он обладает более высокой точностью (меньше ложноположительных результатов), чем файл haarcascade_frontalface_alt.xml, который мы использовали в предыдущем проекте. Далее инстанцируем объект класса VideoCapture по имени cap (от capture). Передаем этому конструктору индекс видеоустройства, которое планируется использовать . Если у вас всего одна камера, например встроенная в ноутбук, то ее индекс должен быть 0.

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

Для загрузки кадров вызываем метод read() объекта cap. Он возвращает кортеж, состоящий из булева кода возврата и NumPy-объекта ndarray, представляющего текущий кадр. Код возврата используется, чтобы проверить, закончились ли кадры при считывании из файла. Но так как здесь мы считываем не из файла, то присваиваем его нижнему подчеркиванию, указывая на незначительность этой переменной.

Обнаружение лиц в видеопотоке      285

Далее повторно используем код предыдущего проекта, который находит прямо­ угольники лиц и рисует их в кадре. Отображаем кадр с помощью метода OpenCV imshow(). В случае обнаружения лица программа должна рисовать в этом кадре прямоугольник.

Завершаем цикл нажатием клавиши Q , чтобы выйти. Начинаем с вызова метода OpenCV waitKey(), которому передаем значение, равное 1 мс. Этот метод приостанавливает программу при ожидании нажатия клавиши, но ненадолго, чтобы не прерывать видеопоток.

Встроенная в Python функция ord() получает в качестве аргумента строку и возвращает переданный аргумент в форме кодовой точки Юникода, в данном случае q нижнего регистра. Таблицу сопоставления символов с числами можете найти на http://www.asciitable.com/. Чтобы этот код выполнялся в любой операционной системе, включите побитовый оператор AND, &, с шестнадцатеричным числом FF(0xFF), которое представляет значение 255. Использование & 0xFF гарантирует считывание только 8 последних бит переменной.

Когда цикл завершается, вызываем метод release() объекта cap. Это освобождает камеру для других приложений. Завершаем программу, закрывая окно отображения.

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

frame = cv.resize(frame, None, fx=0.5, fy=0.5, interpolation=cv.INTER_AREA)

Аргументы fx и fy определяют масштабирование для измерений x и y экрана. Использование значения 0.5 приведет к уменьшению изначального размера окна вдвое.

Программа будет хорошо отслеживать ваше лицо, но только до тех пор, пока вы не станете совершать нестандартные действия, например не наклоните голову набок. Этого вполне достаточно, чтобы сбить с толку алгоритм обнаружения, из-за чего прямоугольник исчезнет (рис. 9.15).

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

286      Глава 9. Как различить своих и чужих

Рис. 9.15. Обнаружение лиц с использованием видеокадров

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

Небольшой наклон каскадные классификаторы Хаара обработать способны (рис. 9.16), поэтому перед каждой передачей изображение можно поворачивать примерно на 5 градусов, что даст неплохой шанс на получение положительного результата.

Рис. 9.16. Поворот изображения помогает обнаружению