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

Создание нейронной сети

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

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

Основные библиотеки для этого проекта — NumPy, OpenCV и Tensorflow 2.0. Все используемые модули будут объяснены, когда мы доберемся до этой части.

Алгоритм обнаружения лицевой маски будет построен на сверточной нейронной сети. Сверточные нейронные сети или CNN берут обучающие данные и применяют «фильтры», чтобы обнаруживать различные закономерности в изображениях, которые можно использовать для создания прогнозов на их основе. Для нашей модели мы будем использовать общедоступный набор данных от Kaggle.

Набор данных можно найти по адресу: https://www.kaggle.com/ashishjangra27/face-mask-12k-images-dataset.

Прежде чем мы начнем писать больше кода, давайте проанализируем набор данных. Имеется 10 000 обучающих изображений, 5 000 с масками и 5 000 без масок. Крайне важно, чтобы при работе с CNN было достаточно обучающих данных, и 10 000 более чем достаточно. Есть еще 992 тестовых изображения и 800 проверочных изображений.

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

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

Наш алгоритм будет иметь бинарные предсказания: либо 0, указывающий на отсутствие маски лица, либо 1, указывающий на наличие маски лица. Следовательно, список категорий CAT будет состоять из двух категорий: «Без маски» и «С маской».

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

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

Мы также использовали обработку ошибок, чтобы игнорировать изображения, которые могут вызывать проблемы при вводе. По сути, метод OpenCV .imread() принимает изображения и выводит размеры изображений в пикселях. Все наши изображения будут сохранены в списке под названием data. Мы также собираемся использовать метод .shuffle() из случайной библиотеки, чтобы изменить порядок (чтобы сначала не было строго изображений "Без маски", а затем Изображения «с маской». Это может создать проблему при обучении сети). После перетасовки мы разделим список данных на два независимых списка, X и y. X будет содержать переменные функции или, в данном случае, размеры изображения, а y будет содержать целевую переменную.

Наконец, мы преобразуем наш список X в массив и сделаем его 4-мерным. Это соглашение при использовании CNN. -1 в качестве первого аргумента метода .reshape() означает все изображения (поэтому вместо -1 вы также можете передать len(x)). Хорошей практикой является нормализация данных. Поскольку мы знаем, что максимальное значение для данных пикселей равно 255, а минимальное значение равно 0, мы можем разделить все наши данные на 255, чтобы нормализовать их по шкале от 0 до 1. Последние две строки кода состоят из сохранения наши данные X и данные y, чтобы мы могли импортировать их, когда захотим, без необходимости повторной предварительной обработки данных.

Теперь пришло время построить модель.

Наша сверточная сеть будет использовать 5 слоев: Dense, Dropout, Conv2D, MaxPool2D и Flatten.

Слой Conv2D создает матрицы фильтров на основе предоставленного аргумента (в этом случае в каждом слое Conv2D будут использоваться фильтры 3x3). По сути, он будет анализировать изображения блоками 3x3 и выводить сумму произведения Адамара. На следующем изображении показано, как работает слой Conv2D. Начальные значения фильтров генерируются случайным образом, но обновляются после обратного распространения.

После этого слой MaxPool2D выводит наибольшее значение из свернутых данных изображения. После того, как анализ изображения завершен, слой Flatten преобразует данные в одно измерение, чтобы с ними можно было работать дальше. Слои Dense & Dropout используются для дальнейших операций, и конечным результатом является один нейрон, который выводит либо 0, что означает «Без маски», либо 1, что означает «С маской».

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

Output
992/992 [==============================] - 1s 1ms/sample - loss: 0.0278 - accuracy: 0.9869

Как мы видим, точность нашей модели составляет 98,7%, а анализ каждого изображения занимает 1 миллисекунду. Теперь давайте оценим модель на основе данных проверки.

Output
800/800 [==============================] - 1s 1ms/sample - loss: 0.0282 - accuracy: 0.9875

Как мы видим, точность составляет 98,8%.

Используйте model.save(‘model’), чтобы сохранить модель CNN.

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

Подача видео

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

Как и раньше, мы начнем с импорта всех библиотек.

Модуль load_model() загрузит сохраненную модель. Так как мы обучали нашу нейронную сеть на изображениях 80x80, мы будем делать то же самое с изображениями, извлеченными из живых кадров.

Мы будем использовать каскадный файл Haar Frontal Facing для обнаружения лица. Файл Haar Cascade предоставляет программе функции, которые помогут идентифицировать лицо. Мы будем использовать это, чтобы идентифицировать лицо, взять изображение строго лица и отправить его в CNN, чтобы определить, есть ли на лице маска или нет. Файл каскада Хаара для обнаружения лиц спереди можно загрузить с: http://alereimondo.no-ip.org/OpenCV/34/

Программа потребует ввести IP-адрес, относящийся к мобильному телефону, мы рассмотрим, как получить IP-адрес и какое приложение использовать на телефоне, позже. Аргументом метода CascadeClassifier() является каталог файла Haar Cascade на вашем компьютере.

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

Аргументом метода waitKey() является количество миллисекунд до обновления экрана. Уменьшение этого числа делает программу более плавной, но требует больше вычислительной мощности.

После запуска программы нажмите клавишу Escape, чтобы выйти.

Чтобы вывести отснятый материал с телефона, загрузите приложение IP Webcam. После загрузки откройте приложение и прокрутите вниз до раздела Управление службами. Чуть ниже находится параметр Запустить сервер. Нажав на нее, вы запустите камеру вашего телефона. Кадры, которые вы видите на экране вашего телефона, — это кадры, которые будут отправлены на CNN. На экране вы должны увидеть IP-адрес IPv4. Скопируйте этот адрес.