ml5.js предоставляет высокоуровневый интерфейс для работы с машинным обучением в браузере на JavaScript. Одним из популярных модулей является Face API, позволяющий распознавать лица, определять ключевые точки и анализировать эмоции. Когда возникает задача работы с несколькими лицами одновременно, важно понимать особенности детекции, ограничения и методы оптимизации.
Для одновременного обнаружения нескольких лиц используется метод
detect объекта FaceApi. В ml5.js по умолчанию Face API
ориентирован на работу с одним лицом, но можно передать флаг или
использовать модели, поддерживающие множественную детекцию:
const faceapi = ml5.faceApi(video, options, modelReady);
const options = {
withLandmarks: true,
withDescriptors: true,
withExpressions: true,
minConfidence: 0.5
};
function modelReady() {
faceapi.detect(gotFaces);
}
function gotFaces(error, result) {
if (error) {
console.error(error);
return;
}
console.log(result); // Массив объектов с информацией о каждом лице
faceapi.detect(gotFaces); // Продолжение детекции
}
Ключевой момент: результат detect — это
массив объектов, где каждый объект содержит:
alignedRect — координаты рамки лица;landmarks — ключевые точки лица (глаза, нос, рот);expressions — вероятности эмоций;descriptor — вектор признаков лица (для распознавания
идентичности).Для динамических сцен, где лица перемещаются в кадре, полезно использовать массив для хранения предыдущих идентификаторов лиц. Так можно:
Пример простой структуры:
let trackedFaces = [];
function updateFaces(detectedFaces) {
detectedFaces.forEach(face => {
// Проверка, есть ли лицо в trackedFaces
let existing = trackedFaces.find(f => distance(f.descriptor, face.descriptor) < 0.6);
if (existing) {
existing.box = face.alignedRect._box;
existing.expressions = face.expressions;
} else {
trackedFaces.push(face);
}
});
}
Функция distance вычисляет схожесть дескрипторов для
идентификации одного и того же лица.
Для отображения нескольких лиц одновременно важно корректно работать с координатами и ключевыми точками:
function drawFaces(faces) {
faces.forEach(face => {
const { _x, _y, _width, _height } = face.alignedRect._box;
stroke(0, 255, 0);
noFill();
rect(_x, _y, _width, _height);
// Рисуем глаза и рот
face.landmarks.positions.forEach(pt => {
ellipse(pt._x, pt._y, 5, 5);
});
// Показываем эмоции
textSize(12);
text(face.expressions.dominant, _x, _y - 10);
});
}
Важно: при работе с видео и несколькими лицами
рекомендуется уменьшать размер кадра для обработки или
использовать requestAnimationFrame для оптимизации частоты
вызова detect, чтобы избежать падения FPS.
detect через определённый интервал, например 200–300 мс,
чтобы снизить нагрузку.ml5.js, будучи высокоуровневой библиотекой, накладывает некоторые ограничения:
Для сложных случаев может потребоваться комбинирование ml5.js с TensorFlow.js или использование специализированных моделей детекции лиц (например, BlazeFace), но ml5.js отлично подходит для быстрого прототипирования и образовательных целей.
Важный аспект — реакция на события появления или исчезновения лица:
function detectFacesLoop() {
faceapi.detect((error, results) => {
if (error) return console.error(error);
updateFaces(results);
drawFaces(trackedFaces);
requestAnimationFrame(detectFacesLoop);
});
}
Использование циклической детекции через requestAnimationFrame обеспечивает плавную визуализацию и непрерывное отслеживание нескольких лиц одновременно.
Эта структура работы с множественными лицами позволяет создавать интерактивные приложения, где каждый человек в кадре может анализироваться отдельно и использоваться для дальнейших вычислений или визуализации.