[JavaScript, Программирование, HTML, TensorFlow] Отслеживание лиц в реальном времени в браузере с использованием TensorFlow.js. Часть 1 (перевод)
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Такие приложения, как Snapchat, предлагают удивительное разнообразие фильтров для лиц и объективов, которые позволяют накладывать интересные эффекты на фотографии и видео. Если вы когда-либо дарили себе виртуальные собачьи уши или праздничную шляпу, вы знаете, насколько это может быть весело! Задумывались ли вы о возможности создания таких фильтров с нуля? Что ж, теперь у вас есть возможность научиться всему, используя только веб-браузер! В этой серии статей мы узнаем, как создавать в браузере фильтры в стиле Snapchat, обучать модель искусственного интеллекта (ИИ) понимать выражения лиц и добиваться ещё большего, используя библиотеку Tensorflow.js и отслеживание лиц. Вы можете загрузить демоверсию этого проекта. Для обеспечения необходимой производительности может потребоваться включить в веб-браузере поддержку интерфейса WebGL. Вы также можете загрузить код и файлы для этой серии. Предполагается, что вы знакомы с JavaScript и HTML и имеете хотя бы базовое представление о нейронных сетях. Первый шаг к созданию фильтра для лиц с нуля – это обнаружение и локализация лиц на изображениях. Поэтому мы можем начать отсюда.Лица можно отслеживать с помощью библиотеки TensorFlow.js и модели обнаружения ориентиров лиц, которая за пару миллисекунд может дать нам 486 различных ключевых точек в пространстве для каждого лица на изображении или в видеокадре. Особенно замечательно то, что эта модель может работать в рамках веб-страницы, поэтому вы также сможете отслеживать лица на мобильных устройствах, используя тот же код.Давайте настроим проект, чтобы загрузить модель и запустить отслеживание лиц в видеопотоке с веб-камеры.Отправная точкаВот начальный шаблон веб-страницы, который мы будем использовать для отслеживания лиц.Этот шаблон содержит:
- библиотеки TensorFlow.js, необходимые для этого проекта;
- индекс эталонной сетки для лица, заданный в файле triangles.js (включён в код проекта);
- элемент canvas для визуализированных выходных данных;
- скрытый элемент video для веб-камеры;
- текстовый элемент статуса и служебная функция setText;
- служебные функции drawLine и drawTriangle для элементов canvas.
<html>
<head>
<title>Real-Time Face Tracking 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="web/triangles.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();
}
function drawTriangle( ctx, x1, y1, x2, y2, x3, y3 ) {
ctx.beginPath();
ctx.moveTo( x1, y1 );
ctx.lineTo( x2, y2 );
ctx.lineTo( x3, y3 );
ctx.lineTo( x1, y1 );
ctx.stroke();
}
(async () => {
// TODO: Add code here
})();
</script>
</body>
</html>
Использование API веб-камеры в HTML5 с TensorFlow.jsВ JavaScript довольно просто запустить веб-камеру, если у вас есть для неё фрагмент кода. Вот служебная функция запуска веб-камеры и запроса доступа у пользователя:
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();
}
});
}
Мы можем вызвать функцию setupWebcam в блоке async в нижней части нашего кода и заставить её воспроизводить видео веб-камеры после загрузки.
(async () => {
await setupWebcam();
const video = document.getElementById( "webcam" );
video.play();
})();
Затем давайте настроим выходной элемент canvas и подготовимся к рисованию линий и треугольников для ограничивающего прямоугольника и каркаса лица.Контекст canvas будет использоваться для вывода результатов отслеживания лиц, поэтому мы можем сохранить их глобально за пределами блока async. Обратите внимание, что мы зеркально отразили изображение веб-камеры по горизонтали, чтобы поведение было более естественным, как в настоящем зеркале.
let output = null;
(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;
})();
Давайте отследим некоторые лицаТеперь мы готовы! Всё, что нам нужно, – это загрузить модель обнаружения ориентиров лица TensorFlow и применить её к кадрам нашей веб-камеры, чтобы показать результаты.Во-первых, нам нужна глобальная переменная model для сохранения загруженной модели:
let model = null;
Затем мы можем загрузить модель в конец блока async и задать текст статуса, чтобы указать на готовность нашего приложения для отслеживания лиц:
// Load Face Landmarks Detection
model = await faceLandmarksDetection.load(
faceLandmarksDetection.SupportedPackages.mediapipeFacemesh
);
setText( "Loaded!" );
Теперь давайте создадим функцию trackFace, которая принимает видеокадры веб-камеры, применяет модель отслеживания лиц, копирует изображение веб-камеры в выходной элемент canvas, а затем рисует ограничивающий прямоугольник вокруг лица и треугольники сетки каркаса поверх лица.
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
);
faces.forEach( face => {
setText( `Face Tracking Confidence: ${face.faceInViewConfidence.toFixed( 3 )}` );
// 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 );
// Draw the face mesh
const keypoints = face.scaledMesh;
for( let i = 0; i < FaceTriangles.length / 3; i++ ) {
let pointA = keypoints[ FaceTriangles[ i * 3 ] ];
let pointB = keypoints[ FaceTriangles[ i * 3 + 1 ] ];
let pointC = keypoints[ FaceTriangles[ i * 3 + 2 ] ];
drawTriangle( output, pointA[ 0 ], pointA[ 1 ], pointB[ 0 ], pointB[ 1 ], pointC[ 0 ], pointC[ 1 ] );
}
});
requestAnimationFrame( trackFace );
}
Наконец, мы можем запустить первый кадр для отслеживания, вызвав эту функцию в конце нашего блока async:
(async () => {
...
trackFace();
})();
Финишная прямаяПолный код должен выглядеть так:
<html>
<head>
<title>Real-Time Face Tracking 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="web/triangles.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();
}
function drawTriangle( ctx, x1, y1, x2, y2, x3, y3 ) {
ctx.beginPath();
ctx.moveTo( x1, y1 );
ctx.lineTo( x2, y2 );
ctx.lineTo( x3, y3 );
ctx.lineTo( x1, y1 );
ctx.stroke();
}
let output = null;
let model = null;
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();
}
});
}
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
);
faces.forEach( face => {
setText( `Face Tracking Confidence: ${face.faceInViewConfidence.toFixed( 3 )}` );
// 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 );
// Draw the face mesh
const keypoints = face.scaledMesh;
for( let i = 0; i < FaceTriangles.length / 3; i++ ) {
let pointA = keypoints[ FaceTriangles[ i * 3 ] ];
let pointB = keypoints[ FaceTriangles[ i * 3 + 1 ] ];
let pointC = keypoints[ FaceTriangles[ i * 3 + 2 ] ];
drawTriangle( output, pointA[ 0 ], pointA[ 1 ], pointB[ 0 ], pointB[ 1 ], pointC[ 0 ], pointC[ 1 ] );
}
});
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 с видео с веб-камеры, мы смогли отслеживать лица в режиме реального времени прямо в браузере. Наш код отслеживания лиц также работает с изображениями, а ключевые моменты могли бы сказать нам больше, чем мы могли бы ожидать. Может быть, нам следует попробовать применить этот код к набору данных лиц, например FER+ Facial Expression Recognition (распознавание выражений лиц)?В следующей статье этой серии мы используем глубокое обучение на отслеженных лицах из набора данных FER+ и попытаемся точно определить эмоции человека по точкам лица в браузере с помощью TensorFlow.js. До встречи завтра, в это же время.
Узнайте подробности, как получить 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
===========Похожие новости:
- [JavaScript, Программирование] Почему вы можете обойтись без Babel (перевод)
- [Python, Машинное обучение, Искусственный интеллект, TensorFlow] Нейродайджест: главное из области машинного обучения за февраль 2021
- [Программирование, Assembler] Как писать на ассемблере в 2021 году
- [Программирование, Совершенный код] Trace, Info, Warning, Error, Fatal — кто все эти люди..?
- [Программирование, Клиентская оптимизация, Разработка игр, Софт] Как я сократил время загрузки GTA Online на 70% (перевод)
- [Python, Алгоритмы, Карьера в IT-индустрии, Natural Language Processing] Как улучшить резюме с помощью алгоритмов обработки текстов на естественных языках (перевод)
- [Python, Программирование] Пишем телеграм-бота, который будет переводить интернет статьи в mp3-файлы
- [Совершенный код, UML Design, ООП, Параллельное программирование] Как построить четкие модели классов и получить реальные преимущества от UML. Часть 4 (перевод)
- [Законодательство в IT, IT-компании] Facebook согласилась выплатить $650 млн жителям Иллинойса за использование технологии распознавания лиц без их согласия
- [Промышленное программирование] Мобильная Установка Доказательства Актуальности Контроля Измерений. Часть 2. «Нам срочно нужна связь!»
Теги для поиска: #_javascript, #_programmirovanie (Программирование), #_html, #_tensorflow, #_skillfactory, #_html, #_javascript, #_raspoznavanie_lits (распознавание лиц), #_tensorflow, #_lajfhaki (лайфхаки), #_programmirovanie (программирование), #_blog_kompanii_skillfactory (
Блог компании SkillFactory
), #_javascript, #_programmirovanie (
Программирование
), #_html, #_tensorflow
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 25-Ноя 07:17
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Такие приложения, как Snapchat, предлагают удивительное разнообразие фильтров для лиц и объективов, которые позволяют накладывать интересные эффекты на фотографии и видео. Если вы когда-либо дарили себе виртуальные собачьи уши или праздничную шляпу, вы знаете, насколько это может быть весело! Задумывались ли вы о возможности создания таких фильтров с нуля? Что ж, теперь у вас есть возможность научиться всему, используя только веб-браузер! В этой серии статей мы узнаем, как создавать в браузере фильтры в стиле Snapchat, обучать модель искусственного интеллекта (ИИ) понимать выражения лиц и добиваться ещё большего, используя библиотеку Tensorflow.js и отслеживание лиц. Вы можете загрузить демоверсию этого проекта. Для обеспечения необходимой производительности может потребоваться включить в веб-браузере поддержку интерфейса WebGL. Вы также можете загрузить код и файлы для этой серии. Предполагается, что вы знакомы с JavaScript и HTML и имеете хотя бы базовое представление о нейронных сетях. Первый шаг к созданию фильтра для лиц с нуля – это обнаружение и локализация лиц на изображениях. Поэтому мы можем начать отсюда.Лица можно отслеживать с помощью библиотеки TensorFlow.js и модели обнаружения ориентиров лиц, которая за пару миллисекунд может дать нам 486 различных ключевых точек в пространстве для каждого лица на изображении или в видеокадре. Особенно замечательно то, что эта модель может работать в рамках веб-страницы, поэтому вы также сможете отслеживать лица на мобильных устройствах, используя тот же код.Давайте настроим проект, чтобы загрузить модель и запустить отслеживание лиц в видеопотоке с веб-камеры.Отправная точкаВот начальный шаблон веб-страницы, который мы будем использовать для отслеживания лиц.Этот шаблон содержит:
<html>
<head> <title>Real-Time Face Tracking 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="web/triangles.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(); } function drawTriangle( ctx, x1, y1, x2, y2, x3, y3 ) { ctx.beginPath(); ctx.moveTo( x1, y1 ); ctx.lineTo( x2, y2 ); ctx.lineTo( x3, y3 ); ctx.lineTo( x1, y1 ); ctx.stroke(); } (async () => { // TODO: Add code here })(); </script> </body> </html> 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(); } }); } (async () => {
await setupWebcam(); const video = document.getElementById( "webcam" ); video.play(); })(); let output = null;
(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; })(); let model = null;
// Load Face Landmarks Detection
model = await faceLandmarksDetection.load( faceLandmarksDetection.SupportedPackages.mediapipeFacemesh ); setText( "Loaded!" ); 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 ); faces.forEach( face => { setText( `Face Tracking Confidence: ${face.faceInViewConfidence.toFixed( 3 )}` ); // 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 ); // Draw the face mesh const keypoints = face.scaledMesh; for( let i = 0; i < FaceTriangles.length / 3; i++ ) { let pointA = keypoints[ FaceTriangles[ i * 3 ] ]; let pointB = keypoints[ FaceTriangles[ i * 3 + 1 ] ]; let pointC = keypoints[ FaceTriangles[ i * 3 + 2 ] ]; drawTriangle( output, pointA[ 0 ], pointA[ 1 ], pointB[ 0 ], pointB[ 1 ], pointC[ 0 ], pointC[ 1 ] ); } }); requestAnimationFrame( trackFace ); } (async () => {
... trackFace(); })(); <html>
<head> <title>Real-Time Face Tracking 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="web/triangles.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(); } function drawTriangle( ctx, x1, y1, x2, y2, x3, y3 ) { ctx.beginPath(); ctx.moveTo( x1, y1 ); ctx.lineTo( x2, y2 ); ctx.lineTo( x3, y3 ); ctx.lineTo( x1, y1 ); ctx.stroke(); } let output = null; let model = null; 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(); } }); } 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 ); faces.forEach( face => { setText( `Face Tracking Confidence: ${face.faceInViewConfidence.toFixed( 3 )}` ); // 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 ); // Draw the face mesh const keypoints = face.scaledMesh; for( let i = 0; i < FaceTriangles.length / 3; i++ ) { let pointA = keypoints[ FaceTriangles[ i * 3 ] ]; let pointB = keypoints[ FaceTriangles[ i * 3 + 1 ] ]; let pointC = keypoints[ FaceTriangles[ i * 3 + 2 ] ]; drawTriangle( output, pointA[ 0 ], pointA[ 1 ], pointB[ 0 ], pointB[ 1 ], pointC[ 0 ], pointC[ 1 ] ); } }); 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> Узнайте подробности, как получить Level Up по навыкам и зарплате или востребованную профессию с нуля, пройдя онлайн-курсы SkillFactory со скидкой 40% и промокодом HABR, который даст еще +10% скидки на обучение. Другие профессии и курсыПРОФЕССИИ
=========== Источник: habr.com =========== =========== Автор оригинала: Raphael Mun ===========Похожие новости:
Блог компании SkillFactory ), #_javascript, #_programmirovanie ( Программирование ), #_html, #_tensorflow |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 25-Ноя 07:17
Часовой пояс: UTC + 5