[JavaScript, Программирование, HTML, TensorFlow] Отслеживание лиц в реальном времени в браузере с использованием TensorFlow.js. Часть 6 (перевод)
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Активация экранной магии вашим лицом в браузереВот и финал этой серии статей (ссылки на предыдущие части — в конце этого материала), в которой мы создавали в браузере фильтры в стиле Snapchat, обучая модель ИИ понимать выражения лиц и добились ещё большего, используя библиотеку Tensorflow.js и отслеживание лиц.
Было бы здорово закончить, реализовав обнаружение движения на лицах? Позвольте показать, как по ключевым точкам лица определять, когда мы открываем рот и моргаем глазами, чтобы активировать события, происходящие на экране.Вы можете загрузить демоверсию этого проекта. Для обеспечения необходимой производительности может потребоваться включить в веб-браузере поддержку интерфейса WebGL. Вы также можете загрузить код и файлы для этой серии. Предполагается, что вы знакомы с JavaScript и HTML и имеете хотя бы базовое представление о нейронных сетях. Обнаружение моргания глаз и открывания ртаМы собираемся использовать ключевые точки лица, предоставляемые кодом отслеживания лиц, который мы разработали в первой статье этой серии, а также отслеживание лица в реальном времени, чтобы обнаружить моргание глаз и открывание рта.Аннотированные точки лица дают достаточно информации, чтобы определить, когда глаза закрыты и когда открыт рот. Хитрость заключается в том, чтобы масштабировать положения с учетом относительного размера в анфас.Для этого мы можем обратиться к удобному расстоянию между глазами, чтобы аппроксимировать относительную шкалу в функции trackFace:
async function trackFace() {
...
faces.forEach( face => {
const eyeDist = Math.sqrt(
( face.annotations.leftEyeUpper1[ 3 ][ 0 ] - face.annotations.rightEyeUpper1[ 3 ][ 0 ] ) ** 2 +
( face.annotations.leftEyeUpper1[ 3 ][ 1 ] - face.annotations.rightEyeUpper1[ 3 ][ 1 ] ) ** 2 +
( face.annotations.leftEyeUpper1[ 3 ][ 2 ] - face.annotations.rightEyeUpper1[ 3 ][ 2 ] ) ** 2
);
const faceScale = eyeDist / 80;
});
requestAnimationFrame( trackFace );
}
Затем мы можем вычислить расстояние между верхней и нижней частью как левого, так и правого глаза и использовать значение faceScale для оценки момента пересечения порога. Мы можем использовать аналогичный расчёт для обнаружения открывания рта.Взгляните:
async function trackFace() {
...
let areEyesClosed = false, isMouthOpen = false;
faces.forEach( face => {
...
// Check for eyes closed
const leftEyesDist = Math.sqrt(
( face.annotations.leftEyeLower1[ 4 ][ 0 ] - face.annotations.leftEyeUpper1[ 4 ][ 0 ] ) ** 2 +
( face.annotations.leftEyeLower1[ 4 ][ 1 ] - face.annotations.leftEyeUpper1[ 4 ][ 1 ] ) ** 2 +
( face.annotations.leftEyeLower1[ 4 ][ 2 ] - face.annotations.leftEyeUpper1[ 4 ][ 2 ] ) ** 2
);
const rightEyesDist = Math.sqrt(
( face.annotations.rightEyeLower1[ 4 ][ 0 ] - face.annotations.rightEyeUpper1[ 4 ][ 0 ] ) ** 2 +
( face.annotations.rightEyeLower1[ 4 ][ 1 ] - face.annotations.rightEyeUpper1[ 4 ][ 1 ] ) ** 2 +
( face.annotations.rightEyeLower1[ 4 ][ 2 ] - face.annotations.rightEyeUpper1[ 4 ][ 2 ] ) ** 2
);
if( leftEyesDist / faceScale < 23.5 ) {
areEyesClosed = true;
}
if( rightEyesDist / faceScale < 23.5 ) {
areEyesClosed = true;
}
// Check for mouth open
const lipsDist = Math.sqrt(
( face.annotations.lipsLowerInner[ 5 ][ 0 ] - face.annotations.lipsUpperInner[ 5 ][ 0 ] ) ** 2 +
( face.annotations.lipsLowerInner[ 5 ][ 1 ] - face.annotations.lipsUpperInner[ 5 ][ 1 ] ) ** 2 +
( face.annotations.lipsLowerInner[ 5 ][ 2 ] - face.annotations.lipsUpperInner[ 5 ][ 2 ] ) ** 2
);
// Scale to the relative face size
if( lipsDist / faceScale > 20 ) {
isMouthOpen = true;
}
});
setText( `Eyes: ${areEyesClosed} Mouth: ${isMouthOpen}` );
requestAnimationFrame( trackFace );
}
Теперь мы готовы к обнаружению некоторых движений на лицах.Время вечеринки с конфеттиНа каждом празднике требуется конфетти, верно? Мы собираемся соединить виртуальное конфетти с моргающими глазами и открывающимся ртом, чтобы получилась настоящая вечеринка.Для этого мы будем использовать библиотеку JavaScript с открытым исходным кодом, которая называется Party-JS. Включите её в верхней части своей страницы следующим образом:
<script src="https://cdn.jsdelivr.net/npm/party-js@1.0.0/party.min.js"></script>
Давайте зададим глобальную переменную, по состоянию которой будем отслеживать запуск конфетти.
let didParty = false;
И последнее, но не менее важное: мы можем включать анимацию вечеринки, когда мы моргаем или открываем рот.
async function trackFace() {
...
if( !didParty && ( areEyesClosed || isMouthOpen ) ) {
party.screen();
}
didParty = areEyesClosed || isMouthOpen;
requestAnimationFrame( trackFace );
}
А теперь время для вечеринки! Используя возможности отслеживания лиц и конфетти, вы запускаете вечеринку на экране по движению своих губ.
Этот проект не закончен без полного кода, на который вы могли бы взглянуть. Поэтому вот он:Простыня с кодом
<html>
<head>
<title>Tracking Faces in the Browser with TensorFlow.js</title>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@2.4.0/dist/tf.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/face-landmarks-detection@0.0.1/dist/face-landmarks-detection.js"></script>
<script src="https://cdn.jsdelivr.net/npm/party-js@1.0.0/party.min.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;
}
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();
}
});
}
let output = null;
let model = null;
let didParty = false;
async function trackFace() {
const video = document.getElementById( "webcam" );
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 areEyesClosed = false, isMouthOpen = false;
faces.forEach( face => {
const eyeDist = Math.sqrt(
( face.annotations.leftEyeUpper1[ 3 ][ 0 ] - face.annotations.rightEyeUpper1[ 3 ][ 0 ] ) ** 2 +
( face.annotations.leftEyeUpper1[ 3 ][ 1 ] - face.annotations.rightEyeUpper1[ 3 ][ 1 ] ) ** 2 +
( face.annotations.leftEyeUpper1[ 3 ][ 2 ] - face.annotations.rightEyeUpper1[ 3 ][ 2 ] ) ** 2
);
const faceScale = eyeDist / 80;
// Check for eyes closed
const leftEyesDist = Math.sqrt(
( face.annotations.leftEyeLower1[ 4 ][ 0 ] - face.annotations.leftEyeUpper1[ 4 ][ 0 ] ) ** 2 +
( face.annotations.leftEyeLower1[ 4 ][ 1 ] - face.annotations.leftEyeUpper1[ 4 ][ 1 ] ) ** 2 +
( face.annotations.leftEyeLower1[ 4 ][ 2 ] - face.annotations.leftEyeUpper1[ 4 ][ 2 ] ) ** 2
);
const rightEyesDist = Math.sqrt(
( face.annotations.rightEyeLower1[ 4 ][ 0 ] - face.annotations.rightEyeUpper1[ 4 ][ 0 ] ) ** 2 +
( face.annotations.rightEyeLower1[ 4 ][ 1 ] - face.annotations.rightEyeUpper1[ 4 ][ 1 ] ) ** 2 +
( face.annotations.rightEyeLower1[ 4 ][ 2 ] - face.annotations.rightEyeUpper1[ 4 ][ 2 ] ) ** 2
);
if( leftEyesDist / faceScale < 23.5 ) {
areEyesClosed = true;
}
if( rightEyesDist / faceScale < 23.5 ) {
areEyesClosed = true;
}
// Check for mouth open
const lipsDist = Math.sqrt(
( face.annotations.lipsLowerInner[ 5 ][ 0 ] - face.annotations.lipsUpperInner[ 5 ][ 0 ] ) ** 2 +
( face.annotations.lipsLowerInner[ 5 ][ 1 ] - face.annotations.lipsUpperInner[ 5 ][ 1 ] ) ** 2 +
( face.annotations.lipsLowerInner[ 5 ][ 2 ] - face.annotations.lipsUpperInner[ 5 ][ 2 ] ) ** 2
);
// Scale to the relative face size
if( lipsDist / faceScale > 20 ) {
isMouthOpen = true;
}
});
if( !didParty && ( areEyesClosed || isMouthOpen ) ) {
party.screen();
}
didParty = areEyesClosed || isMouthOpen;
setText( `Eyes: ${areEyesClosed} Mouth: ${isMouthOpen}` );
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
);
setText( "Loaded!" );
trackFace();
})();
</script>
</body>
</html>
Что дальше?Собственно, на этом пока всё. В этой серии статей мы научились применять ИИ к лицам, чтобы отслеживать их в режиме реального времени, а также определять эмоции на лице и движения рта и глаз. Мы даже создали с нуля собственную игру с дополненной реальностью и виртуальными очками, и всё это работает в веб-браузере.Хотя мы выбрали для применения забавные примеры, для этой технологии также существует множество приложений в бизнесе. Представьте продавца очков, который хочет позволить посетителям своего веб-сайта выбирать очки, примеряя их. Нетрудно представить, как вы будете использовать знания, приобретённые в этой серии статей, для создания нужных функциональных возможностей. Надеюсь, теперь у вас есть инструменты для создания более полезных решений с использованием ИИ и TensorFlow.js.Попробуйте реализовать конфетти в проекте виртуальных очков. Проверьте, сможете ли вы применить обнаружение эмоций к фотоальбому. И если эти серии статей вдохновят вас на создание ещё более крутых проектов, поделитесь ими в комментариях! Мы будем рады узнать о ваших проектах.Удачи и удовольствия от программирования!
- Отслеживание лиц в реальном времени в браузере. Часть 1
- Отслеживание лиц в реальном времени в браузере. Часть 2
- Отслеживание лиц в реальном времени в браузере. Часть 3
- Отслеживание лиц в реальном времени в браузере. Часть 4
- Отслеживание лиц в реальном времени в браузере. Часть 5
Узнайте подробности, как получить Level Up по навыкам и зарплате или востребованную профессию с нуля, пройдя онлайн-курсы SkillFactory со скидкой 40% и промокодом HABR, который даст еще +10% скидки на обучение.
Другие профессии и курсыПРОФЕССИИ
- Профессия Java-разработчик
- Профессия QA-инженер на JAVA
- Профессия Frontend-разработчик
- Профессия Этичный хакер
- Профессия C++ разработчик
- Профессия Разработчик игр на Unity
- Профессия Веб-разработчик
- Профессия iOS-разработчик с нуля
- Профессия Android-разработчик с нуля
КУРСЫ
- Курс по Machine Learning
- Курс "Математика и Machine Learning для Data Science"
- Курс "Machine Learning и Deep Learning"
- Курс "Python для веб-разработки"
- Курс "Алгоритмы и структуры данных"
- Курс по аналитике данных
- Курс по DevOps
===========
Источник:
habr.com
===========
===========
Автор оригинала: Raphael Mun
===========Похожие новости:
- [Разработка веб-сайтов, Программирование, ООП] Можно ли пингвина наследовать от птицы?
- [Программирование, Бизнес-модели, Криптовалюты] Продажа твиттов без NFT и СМС
- [PHP, Работа с видео, Программирование, HTML, Софт] Самый простой (для знающих Linux) и дешевый способ разместить IP-камеру на сайте для небольшой аудитории
- [Программирование, Геоинформационные сервисы, Математика, Визуализация данных, Научно-популярное] Вычислительная геология и визуализация
- [Assembler, Программирование микроконтроллеров, Разработка под Arduino, DIY или Сделай сам, Электроника для начинающих] Приемопередатчик HC-12 и датчик температуры DS18b20 на AVR-ассемблере
- [JavaScript, Программирование, Совершенный код, ReactJS, TypeScript] HowToCode — Адаптация системного подхода к разработке для React и TypeScript
- [JavaScript, Программирование, HTML, TensorFlow] Отслеживание лиц в реальном времени в браузере с использованием TensorFlow.js. Часть 5 (перевод)
- [Open source, Программирование, Системное программирование, Компиляторы, Rust] Планирование редакции Rust 2021 (перевод)
- [Информационная безопасность, Программирование, C++] С++: безопасность для новичков
- [Разработка веб-сайтов, JavaScript, Программирование, ReactJS] 20 основных частей любого крупномасштабного React-приложения (перевод)
Теги для поиска: #_javascript, #_programmirovanie (Программирование), #_html, #_tensorflow, #_skillfactory, #_programmirovanie (программирование), #_glubokoe_obuchenie (глубокое обучение), #_lajfhaki (лайфхаки), #_blog_kompanii_skillfactory (
Блог компании SkillFactory
), #_javascript, #_programmirovanie (
Программирование
), #_html, #_tensorflow
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 09:00
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Активация экранной магии вашим лицом в браузереВот и финал этой серии статей (ссылки на предыдущие части — в конце этого материала), в которой мы создавали в браузере фильтры в стиле Snapchat, обучая модель ИИ понимать выражения лиц и добились ещё большего, используя библиотеку Tensorflow.js и отслеживание лиц. Было бы здорово закончить, реализовав обнаружение движения на лицах? Позвольте показать, как по ключевым точкам лица определять, когда мы открываем рот и моргаем глазами, чтобы активировать события, происходящие на экране.Вы можете загрузить демоверсию этого проекта. Для обеспечения необходимой производительности может потребоваться включить в веб-браузере поддержку интерфейса WebGL. Вы также можете загрузить код и файлы для этой серии. Предполагается, что вы знакомы с JavaScript и HTML и имеете хотя бы базовое представление о нейронных сетях. Обнаружение моргания глаз и открывания ртаМы собираемся использовать ключевые точки лица, предоставляемые кодом отслеживания лиц, который мы разработали в первой статье этой серии, а также отслеживание лица в реальном времени, чтобы обнаружить моргание глаз и открывание рта.Аннотированные точки лица дают достаточно информации, чтобы определить, когда глаза закрыты и когда открыт рот. Хитрость заключается в том, чтобы масштабировать положения с учетом относительного размера в анфас.Для этого мы можем обратиться к удобному расстоянию между глазами, чтобы аппроксимировать относительную шкалу в функции trackFace: async function trackFace() {
... faces.forEach( face => { const eyeDist = Math.sqrt( ( face.annotations.leftEyeUpper1[ 3 ][ 0 ] - face.annotations.rightEyeUpper1[ 3 ][ 0 ] ) ** 2 + ( face.annotations.leftEyeUpper1[ 3 ][ 1 ] - face.annotations.rightEyeUpper1[ 3 ][ 1 ] ) ** 2 + ( face.annotations.leftEyeUpper1[ 3 ][ 2 ] - face.annotations.rightEyeUpper1[ 3 ][ 2 ] ) ** 2 ); const faceScale = eyeDist / 80; }); requestAnimationFrame( trackFace ); } async function trackFace() {
... let areEyesClosed = false, isMouthOpen = false; faces.forEach( face => { ... // Check for eyes closed const leftEyesDist = Math.sqrt( ( face.annotations.leftEyeLower1[ 4 ][ 0 ] - face.annotations.leftEyeUpper1[ 4 ][ 0 ] ) ** 2 + ( face.annotations.leftEyeLower1[ 4 ][ 1 ] - face.annotations.leftEyeUpper1[ 4 ][ 1 ] ) ** 2 + ( face.annotations.leftEyeLower1[ 4 ][ 2 ] - face.annotations.leftEyeUpper1[ 4 ][ 2 ] ) ** 2 ); const rightEyesDist = Math.sqrt( ( face.annotations.rightEyeLower1[ 4 ][ 0 ] - face.annotations.rightEyeUpper1[ 4 ][ 0 ] ) ** 2 + ( face.annotations.rightEyeLower1[ 4 ][ 1 ] - face.annotations.rightEyeUpper1[ 4 ][ 1 ] ) ** 2 + ( face.annotations.rightEyeLower1[ 4 ][ 2 ] - face.annotations.rightEyeUpper1[ 4 ][ 2 ] ) ** 2 ); if( leftEyesDist / faceScale < 23.5 ) { areEyesClosed = true; } if( rightEyesDist / faceScale < 23.5 ) { areEyesClosed = true; } // Check for mouth open const lipsDist = Math.sqrt( ( face.annotations.lipsLowerInner[ 5 ][ 0 ] - face.annotations.lipsUpperInner[ 5 ][ 0 ] ) ** 2 + ( face.annotations.lipsLowerInner[ 5 ][ 1 ] - face.annotations.lipsUpperInner[ 5 ][ 1 ] ) ** 2 + ( face.annotations.lipsLowerInner[ 5 ][ 2 ] - face.annotations.lipsUpperInner[ 5 ][ 2 ] ) ** 2 ); // Scale to the relative face size if( lipsDist / faceScale > 20 ) { isMouthOpen = true; } }); setText( `Eyes: ${areEyesClosed} Mouth: ${isMouthOpen}` ); requestAnimationFrame( trackFace ); } <script src="https://cdn.jsdelivr.net/npm/party-js@1.0.0/party.min.js"></script>
let didParty = false;
async function trackFace() {
... if( !didParty && ( areEyesClosed || isMouthOpen ) ) { party.screen(); } didParty = areEyesClosed || isMouthOpen; requestAnimationFrame( trackFace ); } Этот проект не закончен без полного кода, на который вы могли бы взглянуть. Поэтому вот он:Простыня с кодом <html>
<head> <title>Tracking Faces in the Browser with TensorFlow.js</title> <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@2.4.0/dist/tf.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/face-landmarks-detection@0.0.1/dist/face-landmarks-detection.js"></script> <script src="https://cdn.jsdelivr.net/npm/party-js@1.0.0/party.min.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; } 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(); } }); } let output = null; let model = null; let didParty = false; async function trackFace() { const video = document.getElementById( "webcam" ); 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 areEyesClosed = false, isMouthOpen = false; faces.forEach( face => { const eyeDist = Math.sqrt( ( face.annotations.leftEyeUpper1[ 3 ][ 0 ] - face.annotations.rightEyeUpper1[ 3 ][ 0 ] ) ** 2 + ( face.annotations.leftEyeUpper1[ 3 ][ 1 ] - face.annotations.rightEyeUpper1[ 3 ][ 1 ] ) ** 2 + ( face.annotations.leftEyeUpper1[ 3 ][ 2 ] - face.annotations.rightEyeUpper1[ 3 ][ 2 ] ) ** 2 ); const faceScale = eyeDist / 80; // Check for eyes closed const leftEyesDist = Math.sqrt( ( face.annotations.leftEyeLower1[ 4 ][ 0 ] - face.annotations.leftEyeUpper1[ 4 ][ 0 ] ) ** 2 + ( face.annotations.leftEyeLower1[ 4 ][ 1 ] - face.annotations.leftEyeUpper1[ 4 ][ 1 ] ) ** 2 + ( face.annotations.leftEyeLower1[ 4 ][ 2 ] - face.annotations.leftEyeUpper1[ 4 ][ 2 ] ) ** 2 ); const rightEyesDist = Math.sqrt( ( face.annotations.rightEyeLower1[ 4 ][ 0 ] - face.annotations.rightEyeUpper1[ 4 ][ 0 ] ) ** 2 + ( face.annotations.rightEyeLower1[ 4 ][ 1 ] - face.annotations.rightEyeUpper1[ 4 ][ 1 ] ) ** 2 + ( face.annotations.rightEyeLower1[ 4 ][ 2 ] - face.annotations.rightEyeUpper1[ 4 ][ 2 ] ) ** 2 ); if( leftEyesDist / faceScale < 23.5 ) { areEyesClosed = true; } if( rightEyesDist / faceScale < 23.5 ) { areEyesClosed = true; } // Check for mouth open const lipsDist = Math.sqrt( ( face.annotations.lipsLowerInner[ 5 ][ 0 ] - face.annotations.lipsUpperInner[ 5 ][ 0 ] ) ** 2 + ( face.annotations.lipsLowerInner[ 5 ][ 1 ] - face.annotations.lipsUpperInner[ 5 ][ 1 ] ) ** 2 + ( face.annotations.lipsLowerInner[ 5 ][ 2 ] - face.annotations.lipsUpperInner[ 5 ][ 2 ] ) ** 2 ); // Scale to the relative face size if( lipsDist / faceScale > 20 ) { isMouthOpen = true; } }); if( !didParty && ( areEyesClosed || isMouthOpen ) ) { party.screen(); } didParty = areEyesClosed || isMouthOpen; setText( `Eyes: ${areEyesClosed} Mouth: ${isMouthOpen}` ); 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 ); setText( "Loaded!" ); trackFace(); })(); </script> </body> </html>
=========== Источник: habr.com =========== =========== Автор оригинала: Raphael Mun ===========Похожие новости:
Блог компании SkillFactory ), #_javascript, #_programmirovanie ( Программирование ), #_html, #_tensorflow |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 09:00
Часовой пояс: UTC + 5