Русский
Русский
English
Статистика
Реклама

Перевод Обнаружение эмоций на лице в реальном времени с помощью веб-камеры в браузере с использованием TensorFlow.js. Часть 3

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


Вы можете загрузить демоверсию этого проекта. Для обеспечения необходимой производительности может потребоваться включить в веб-браузере поддержку интерфейса WebGL. Вы также можете загрузить код и файлы для этой серии. Предполагается, что вы знакомы с JavaScript и HTML и имеете хотя бы базовое представление о нейронных сетях.

Добавление обнаружения эмоций на лице

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

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

const emotions = [ "angry", "disgust", "fear", "happy", "neutral", "sad", "surprise" ];let emotionModel = null;

Затем мы можем загрузить модель обнаружения эмоций внутри блока async:

(async () => {    ...    // Load Face Landmarks Detection    model = await faceLandmarksDetection.load(        faceLandmarksDetection.SupportedPackages.mediapipeFacemesh    );    // Load Emotion Detection    emotionModel = await tf.loadLayersModel( 'web/model/facemo.json' );    ...})();

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

async function predictEmotion( points ) {    let result = tf.tidy( () => {        const xs = tf.stack( [ tf.tensor1d( points ) ] );        return emotionModel.predict( xs );    });    let prediction = await result.data();    result.dispose();    // Get the index of the maximum value    let id = prediction.indexOf( Math.max( ...prediction ) );    return emotions[ id ];}

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

async function trackFace() {    ...    let points = null;    faces.forEach( face => {        ...        // Add just the nose, cheeks, eyes, eyebrows & mouth        const features = [            "noseTip",            "leftCheek",            "rightCheek",            "leftEyeLower1", "leftEyeUpper1",            "rightEyeLower1", "rightEyeUpper1",            "leftEyebrowLower", //"leftEyebrowUpper",            "rightEyebrowLower", //"rightEyebrowUpper",            "lipsLowerInner", //"lipsLowerOuter",            "lipsUpperInner", //"lipsUpperOuter",        ];        points = [];        features.forEach( feature => {            face.annotations[ feature ].forEach( x => {                points.push( ( x[ 0 ] - x1 ) / bWidth );                points.push( ( x[ 1 ] - y1 ) / bHeight );            });        });    });    if( points ) {        let emotion = await predictEmotion( points );        setText( `Detected: ${emotion}` );    }    else {        setText( "No Face" );    }    requestAnimationFrame( trackFace );}

Это всё, что нужно для достижения нужной цели. Теперь, когда вы открываете веб-страницу, она должна обнаружить ваше лицо и распознать эмоции. Экспериментируйте и получайте удовольствие!

Вот полный код, нужный для завершения этого проекта
<html>    <head>        <title>Real-Time Facial Emotion Detection</title>        <script src="http://personeltest.ru/aways/cdn.jsdelivr.net/npm/@tensorflow/tfjs@2.4.0/dist/tf.min.js"></script>        <script src="http://personeltest.ru/aways/cdn.jsdelivr.net/npm/@tensorflow-models/face-landmarks-detection@0.0.1/dist/face-landmarks-detection.js"></script>    </head>    <body>        <canvas id="output"></canvas>        <video id="webcam" playsinline style="            visibility: hidden;            width: auto;            height: auto;            ">        </video>        <h1 id="status">Loading...</h1>        <script>        function setText( text ) {            document.getElementById( "status" ).innerText = text;        }        function drawLine( ctx, x1, y1, x2, y2 ) {            ctx.beginPath();            ctx.moveTo( x1, y1 );            ctx.lineTo( x2, y2 );            ctx.stroke();        }        async function setupWebcam() {            return new Promise( ( resolve, reject ) => {                const webcamElement = document.getElementById( "webcam" );                const navigatorAny = navigator;                navigator.getUserMedia = navigator.getUserMedia ||                navigatorAny.webkitGetUserMedia || navigatorAny.mozGetUserMedia ||                navigatorAny.msGetUserMedia;                if( navigator.getUserMedia ) {                    navigator.getUserMedia( { video: true },                        stream => {                            webcamElement.srcObject = stream;                            webcamElement.addEventListener( "loadeddata", resolve, false );                        },                    error => reject());                }                else {                    reject();                }            });        }        const emotions = [ "angry", "disgust", "fear", "happy", "neutral", "sad", "surprise" ];        let emotionModel = null;        let output = null;        let model = null;        async function predictEmotion( points ) {            let result = tf.tidy( () => {                const xs = tf.stack( [ tf.tensor1d( points ) ] );                return emotionModel.predict( xs );            });            let prediction = await result.data();            result.dispose();            // Get the index of the maximum value            let id = prediction.indexOf( Math.max( ...prediction ) );            return emotions[ id ];        }        async function trackFace() {            const video = document.querySelector( "video" );            const faces = await model.estimateFaces( {                input: video,                returnTensors: false,                flipHorizontal: false,            });            output.drawImage(                video,                0, 0, video.width, video.height,                0, 0, video.width, video.height            );            let points = null;            faces.forEach( face => {                // Draw the bounding box                const x1 = face.boundingBox.topLeft[ 0 ];                const y1 = face.boundingBox.topLeft[ 1 ];                const x2 = face.boundingBox.bottomRight[ 0 ];                const y2 = face.boundingBox.bottomRight[ 1 ];                const bWidth = x2 - x1;                const bHeight = y2 - y1;                drawLine( output, x1, y1, x2, y1 );                drawLine( output, x2, y1, x2, y2 );                drawLine( output, x1, y2, x2, y2 );                drawLine( output, x1, y1, x1, y2 );                // Add just the nose, cheeks, eyes, eyebrows & mouth                const features = [                    "noseTip",                    "leftCheek",                    "rightCheek",                    "leftEyeLower1", "leftEyeUpper1",                    "rightEyeLower1", "rightEyeUpper1",                    "leftEyebrowLower", //"leftEyebrowUpper",                    "rightEyebrowLower", //"rightEyebrowUpper",                    "lipsLowerInner", //"lipsLowerOuter",                    "lipsUpperInner", //"lipsUpperOuter",                ];                points = [];                features.forEach( feature => {                    face.annotations[ feature ].forEach( x => {                        points.push( ( x[ 0 ] - x1 ) / bWidth );                        points.push( ( x[ 1 ] - y1 ) / bHeight );                    });                });            });            if( points ) {                let emotion = await predictEmotion( points );                setText( `Detected: ${emotion}` );            }            else {                setText( "No Face" );            }            requestAnimationFrame( trackFace );        }        (async () => {            await setupWebcam();            const video = document.getElementById( "webcam" );            video.play();            let videoWidth = video.videoWidth;            let videoHeight = video.videoHeight;            video.width = videoWidth;            video.height = videoHeight;            let canvas = document.getElementById( "output" );            canvas.width = video.width;            canvas.height = video.height;            output = canvas.getContext( "2d" );            output.translate( canvas.width, 0 );            output.scale( -1, 1 ); // Mirror cam            output.fillStyle = "#fdffb6";            output.strokeStyle = "#fdffb6";            output.lineWidth = 2;            // Load Face Landmarks Detection            model = await faceLandmarksDetection.load(                faceLandmarksDetection.SupportedPackages.mediapipeFacemesh            );            // Load Emotion Detection            emotionModel = await tf.loadLayersModel( 'web/model/facemo.json' );            setText( "Loaded!" );            trackFace();        })();        </script>    </body></html>

Что дальше? Когда мы сможем носить виртуальные очки?

Взяв код из первых двух статей этой серии, мы смогли создать детектор эмоций на лице в реальном времени, используя лишь немного кода на JavaScript. Только представьте, что ещё можно сделать с помощью библиотеки TensorFlow.js! В следующей статье мы вернёмся к нашей цели создать фильтр для лица в стиле Snapchat, используя то, что мы уже узнали об отслеживании лиц и добавлении 3D-визуализации посредством ThreeJS. Оставайтесь с нами! До встречи завтра, в это же время!

Отслеживание лиц в реальном времени в браузере с использованием TensorFlow.js. Часть 2

Узнайте подробности, как получить Level Up по навыкам и зарплате или востребованную профессию с нуля, пройдя онлайн-курсы SkillFactory со скидкой 40% и промокодомHABR, который даст еще +10% скидки на обучение.

Источник: habr.com
К списку статей
Опубликовано: 03.03.2021 22:15:39
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Блог компании skillfactory

Javascript

Программирование

Html

Tensorflow

Skillfactory

Глубокое обучение

Распознавание лиц

Лайфхаки

Tensorflow-js

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru