Задумывались ли вы когда-нибудь над тем, что камера вашего смартфона может быстро распознать ваше лицо с помощью специальных квадратиков? Каким образом она распознает лица, и какой принцип лежит в основе этого процесса?
В этой статье мы разберемся в особенностях распознавания лиц и создадим собственное приложение для этой цели.
Что такое распознавание лиц?
Распознавание лиц — это компьютерная технология на основе искусственного интеллекта (ИИ), используемая для поиска и идентификации человеческих лиц на цифровых изображениях. Это означает, что система может идентифицировать человеческое лицо, присутствующее на изображении или видео.
Как работает распознавание лиц?
Приложения для обнаружения лиц используют методы и алгоритмы машинного обучения, применяемые с целью распознавания человеческих лиц на больших изображениях. Такие изображения могут содержать множество объектов, не являющихся лицами, например пейзажи, здания и другие части тела человека (ноги, плечи и руки).
Процесс распознавания лица состоит из нескольких этапов. Сначала происходит получение изображения и преобразование его из RGB (красно-зелено-синего) в оттенки серого, так как в оттенках серого легче обнаружить объекты.
Следующим шагом является использование алгоритма признаков Хаара, который в системе обнаружения объектов Виолы-Джонса используется для распознавания лиц. Этот алгоритм применяется при определении расположения человеческого лица в кадре или на изображении.
Все человеческие лица обладают некоторыми универсальными свойствами: область глаз темнее, чем участок соседних пикселей, а область носа светлее, чем область глаз. Этот алгоритм также используется для выделения признаков объекта на изображении. Техника определения краев, линий и центра используется для обнаружения глаз, носа, рта и т. д. Все это нужно для выявления существенных признаков объекта на изображении и извлечения этих признаков для распознавания лица человека.
На следующем этапе задаются координаты x, y, w и h. Это позволяет создать прямоугольную рамку на изображении, чтобы показать местоположение лица или, другими словами, интересующую нас область. После этого алгоритм будет делать прямоугольную рамку в любом месте, где обнаружит лицо.
На этом мы заканчиваем теоретическую часть и переходим к созданию собственной версии приложения для распознавания лиц с помощью live-веб-камеры в браузере.
Предоставление доступа к веб-камере
Для начала нужно предоставить доступ к веб-камере в браузере. Прежде всего, создадим базовый файл index.html
, в котором доступ к веб-камере будет предоставляться с помощью тега video
.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Facial Detection App</title>
</head>
<body>
<h1>Facial Detection</h1>
<video id="video" autoplay></video>
</body>
<script src="script.js"></script>
</html>
Теперь создадим еще один файл под названием script.js
, в котором напишем код Javascript и включим его в index.html
.
let video = document.getElementById("video");
const accessCamera = () => {
navigator.mediaDevices
.getUserMedia({
audio: false,
video: { width: 500, height: 400 },
})
.then((stream) => {
video.srcObject = stream;
});
};
accessCamera();
Здесь мы обращаемся к элементу тега video
и сохраняем его в переменной video
. Функция accessCamera
вызывает API getUserMedia
, и мы указываем размеры видео (здесь установлена ширина 500 px и высота 400 px, но вы можете подобрать размеры по своему желанию).
Функция getUserMedia
возвращает промис с объектом MediaStream
, который мы присваиваем свойству srcObject
элемента видео. Наконец, мы вызываем функцию accessCamera
.
Теперь для запуска мы можем либо использовать расширение live server, либо напрямую открыть файл index.html
. Браузер запросит разрешение на доступ к камере. Разрешите доступ — и вы увидите на экране видеопоток с веб-камеры.
Выполнение распознавания лица
Для выполнения распознавания человеческого лица мы будем использовать модель Blazeface из модели Simple Face Detection на tensorflow.js. Blazeface — это легкая модель, используемая для обнаружения лиц на изображениях.
Из Blazeface мы возьмем следующие теги сценария и добавим их в файл index.html
:
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs"</script>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/blazeface"></script>
Вернемся в файл script.js
, где создадим переменную с именем model
, в которую будет загружена модель Blazeface.
let model;
model = blazeface.load();
Теперь создадим функцию detectFaces
, которая будет выполнять распознавание лиц и выдавать необходимый результат.
const detectFaces = async () => {
const prediction = await model.estimateFaces(video, false);
};
Поскольку blazeface.load()
— асинхронная функция, ей требуется некоторое время для загрузки. Но нам нужно вызывать и detectFaces
, поэтому, чтобы избежать путаницы, мы сначала дождемся загрузки видеопотока с веб-камеры. После этого мы дождемся загрузки модели, а затем вызовем detectFaces
. При загрузке видеопотока будем использовать слушатель событий loadeddata
.
Теперь файл script.js
должен выглядеть примерно так:
let video = document.getElementById("video");
let model;
const accessCamera = () => {
navigator.mediaDevices
.getUserMedia({
video: { width: 500, height: 400 },
audio: false,
})
.then((stream) => {
video.srcObject = stream;
});
};
const detectFaces = async () => {
const prediction = await model.estimateFaces(video, false);
};
accessCamera();
// Это событие будет выполнено, когда видео загрузится
video.addEventListener("loadeddata", async () => {
model = await blazeface.load();
detectFaces();
});
В прогнозе будут перечислены объекты, каждый из которых соответствует обнаруженному лицу. Внутри этих объектов мы обнаружим левую верхнюю и правую нижнюю координаты, а также шесть ориентиров лица, соответствующих глазам, ушам, носу и рту.
Теперь используем эти координаты для отображения результатов в прямоугольном поле. Сначала нужно выполнить итеративный проход по массиву прогнозов и нарисовать прямоугольник или точки для ориентиров лица. Для этого мы будем использовать HTML canvas, а ширина и высота будут такими же, как у видеопотока. Поскольку отображать содержимое тега video
больше не нужно, установим его свойство display
на none
.
Вот какой будет окончательная версия файла index.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Facial Detection App</title>
</head>
<body>
<h1>Facial Detection</h1>
<video id="video" autoplay style="display: none"></video>
<canvas id="canvas" width="500px" height="400px"></canvas>
</body>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs"></script>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/blazeface"></script>
<script src="script.js"></script>
</html>
Далее нам нужно создать переменную для объекта canvas, а также 2D-контекст. После этого нарисуем в canvas текущий видеопоток, а затем прямоугольник для обнаружения лица, что можно сделать с помощью функций drawImage
и rect
для HTML canvas.
Поскольку функция detectFaces
вызывается только один раз, нужно постоянно вызывать ее, чтобы увидеть результат в видео. Мы будем использовать метод setInterval
и вызывать функцию каждые 40 миллисекунд, чтобы получить на выходе около 24 кадров в секунду.
Вот окончательный код script.js
:
let video = document.getElementById("video");
let model;
// Объявление переменной canvas и настройка контекста
let canvas = document.getElementById("canvas");
let ctx = canvas.getContext("2d");
const accessCamera = () => {
navigator.mediaDevices
.getUserMedia({
video: { width: 500, height: 400 },
audio: false,
})
.then((stream) => {
video.srcObject = stream;
});
};
const detectFaces = async () => {
const prediction = await model.estimateFaces(video, false);
// Использование canvas для рисования видео
ctx.drawImage(video, 0, 0, 500, 400);
prediction.forEach((predictions) => {
// Рисование прямоугольника, который будет определять лицо
ctx.beginPath();
ctx.lineWidth = "4";
ctx.strokeStyle = "yellow";
ctx.rect(
predictions.topLeft[0],
predictions.topLeft[1],
predictions.bottomRight[0] - predictions.topLeft[0],
predictions.bottomRight[1] - predictions.topLeft[1]
);
// Последние два аргумента обозначают ширину и высоту,
// но поскольку модели blazeface возвращают только координаты,
// мы должны вычесть их, чтобы получить ширину и высоту
ctx.stroke();
});
};
accessCamera();
video.addEventListener("loadeddata", async () => {
model = await blazeface.load();
// Вызов функции detectFaces каждые 40 миллисекунд
setInterval(detectFaces, 40);
});
Здесь вы найдете live-демо-версию, чтобы посмотреть конечный результат. Первая загрузка может занять несколько секунд.
Заключение
Вот и все, что требуется для создания приложения для распознавания лиц. В статье мы использовали tensorflow.js — отличный инструмент для запуска ML-моделей в браузерах и множества других полезных предварительно обученных моделей.
Читайте также:
- Автоматизация Doom с глубоким Q-обучением: реализация в Tensorflow
- 7 критериев выбора подходящего фреймворка для глубокого обучения
- Распознавание лиц с помощью CoreML и ARKit
Читайте нас в Telegram, VK и Дзен
Перевод статьи Shivam Sinha: Building a Facial Detection App with Tensorflow.js