SlideShare a Scribd company logo
AI x WebAR!
MediaPipeの顔認識を使ってみよう!
in 織りなすラボ
まずは素材のダウンロード
http://arfukuoka.lolipop.jp
/mediapipe/sample.zip
自己紹介
氏名:吉永崇(Takashi Yoshinaga)
所属:Steampunk Digital株式会社
専門:医療支援AR,運動計測,3D Video
コミュニティ:ARコンテンツ作成勉強会
Twitterと勉強会ページで情報を発信しています
@AR_Fukuoka Googleで「AR勉強会」で検索
#AR_Fukuoka
ハッシュタグ
本題に入ります
今日のゴール
AIを用いた顔の認識とテクスチャマッピングを組み合わせたARコンテンツ
https://youtu.be/GyaenzhPhys
使用ツール:Facemesh
GoogleのMediaPipeとTnsorflow.jsがコラボでパッケージを開発。
顔認識を実現するfacemeshと手の認識を実現するhandposeが
提供されている中で今回はfacemeshを使用。
これを使う
ハンズオン手順
 ビデオ画像の取得と表示
 facemeshで顔の認識
 認識結果をAR表示する準備
 顔の特徴点を表示
 顔をポリゴン化
 テクスチャの貼り付け
ハンズオン手順
 ビデオ画像の取得と表示
 facemeshで顔の認識
 認識結果をAR表示する準備
 顔の特徴点を表示
 顔をポリゴン化
 テクスチャの貼り付け
ハンズオン手順
 ビデオ画像の取得と表示
 facemeshで顔の認識
 認識結果をAR表示する準備
 顔の特徴点を表示
 顔をポリゴン化
 テクスチャの貼り付け
ハンズオン手順
 ビデオ画像の取得と表示
 facemeshで顔の認識
 認識結果をAR表示する準備
 顔の特徴点を表示
 顔をポリゴン化
 テクスチャの貼り付け
ハンズオン手順
 ビデオ画像の取得と表示
 facemeshで顔の認識
 認識結果をAR表示する準備
 顔の特徴点を表示
 顔をポリゴン化
 テクスチャの貼り付け
ハンズオン手順
 ビデオ画像の取得と表示
 facemeshで顔の認識
 認識結果をAR表示する準備
 顔の特徴点を表示
 顔をポリゴン化
 テクスチャの貼り付け
ハンズオン手順
 ビデオ画像の取得と表示
 facemeshで顔の認識
 認識結果をAR表示する準備
 顔の特徴点を表示
 顔をポリゴン化
 テクスチャの貼り付け
ハンズオン手順
 ビデオ画像の取得と表示
 facemeshで顔の認識
 認識結果をAR表示する準備
 顔の特徴点を表示
 顔をポリゴン化
 テクスチャの貼り付け
公式サンプルの
利用手順とほぼ同じ
認識結果の活用
今回の進め方
サンプルをコピペしながら
コードの意味を解説
テンプレートの取得
https://glitch.com/~arfukuoka
-template
テンプレートの取得
少し下にスクロール
テンプレートの取得
Remix Your Own
テンプレートの確認
index.html
テンプレートの確認
テンプレートの確認
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<!--TensorFlow関連の読み込み-->
<script src="https://unpkg.com/@tensorflow/tfjs-core@2.1.0/dist/tf-core.js"></script>
<script src="https://unpkg.com/@tensorflow/tfjs-converter@2.1.0/dist/tf-converter.js"></script>
<script src="https://unpkg.com/@tensorflow/tfjs-backend-webgl@2.1.0/dist/tf-backend-webgl.js">
</script>
<!--FaceMesh(顔認識)の読み込み-->
<script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/facemesh"></script>
<!--three.js:あとで顔のメッシュ表示の際に使用する-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js"></script>
</head>
<body>
<!—ここで描画領域を配置-->
</body>
</html> Lesson01
ハンズオン手順
 ビデオ画像の取得と表示
 facemeshで顔の認識
 認識結果をAR表示する準備
 顔の特徴点を表示
 顔をポリゴン化
 テクスチャの貼り付け
ビデオ描画領域を設定する
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<!--TensorFlow関連の読み込み-->
<script src="https://unpkg.com/@tensorflow/tfjs-core@2.1.0/dist/tf-core.js"></script>
<script src="https://unpkg.com/@tensorflow/tfjs-converter@2.1.0/dist/tf-converter.js"></script>
<script src="https://unpkg.com/@tensorflow/tfjs-backend-webgl@2.1.0/dist/tf-backend-webgl.js">
</script>
<!--FaceMesh(顔認識)の読み込み-->
<script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/facemesh"></script>
<!--three.js:あとで顔のメッシュ表示の際に使用する-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js"></script>
</head>
<body>
body内で描画領域をレイアウト
</body>
</html>
ビデオ描画領域を設定する
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<!--TensorFlow関連の読み込み-->
<script src="https://unpkg.com/@tensorflow/tfjs-core@2.1.0/dist/tf-core.js"></script>
<script src="https://unpkg.com/@tensorflow/tfjs-converter@2.1.0/dist/tf-converter.js"></script>
<script src="https://unpkg.com/@tensorflow/tfjs-backend-webgl@2.1.0/dist/tf-backend-webgl.js">
</script>
<!--FaceMesh(顔認識)の読み込み-->
<script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/facemesh"></script>
<!--three.js:あとで顔のメッシュ表示の際に使用する-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js"></script>
</head>
<body>
<video id="video" style="position: absolute;"></video>
</body>
</html>
あとでjavascriptから操作するためidをつけておく
Lesson02
ビデオを描画する
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>AR Fukuoka</title>
<!--TensorFlow関連の読み込み-->
<script src="https://unpkg.com/@tensorflow/tfjs-core@2.1.0/dist/tf-core.js"></script>
<script src="https://unpkg.com/@tensorflow/tfjs-converter@2.1.0/dist/tf-converter.js"></script>
<script src="https://unpkg.com/@tensorflow/tfjs-backend-webgl@2.1.0/dist/tf-backend-webgl.js">
</script>
<!--FaceMesh(顔認識)の読み込み-->
<script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/facemesh"></script>
<!--three.js:あとで顔のメッシュ表示の際に使用する-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js"></script>
<!—自前のスクリプトを記述-->
<script type="text/javascript">
</script>
</head>
<!—スペースの都合上、以下省略-->
Lesson03
ビデオを描画する
<script type="text/javascript">
//ビデオを扱う変数
var video;
//ページを読み込み終わったら実行
window.onload = function() {
//カメラ画像のサイズ設定(とりあえず640x480くらい)
let constraints = { video: { width: 640, height: 480 } };
//カメラデバイスの取得
navigator.mediaDevices.getUserMedia(constraints).then(
function(mediaStream) {
//body内のid=videoの要素を取得
video = document.getElementById("video");
//リアルタイム映像をvideo要素に対応づける
video.srcObject = mediaStream;
//準備が整ったら再生
video.onloadedmetadata = function(e) {
video.play();
};
}
);
}
</script>
Lesson04
動作確認
Show
動作確認
In a New Window
動作確認
カメラの映像が表示されればOK
ハンズオン手順
 ビデオ画像の取得と表示
 facemeshで顔の認識
 認識結果をAR表示する準備
 顔の特徴点を表示
 顔をポリゴン化
 テクスチャの貼り付け
顔の認識
//ビデオを扱う変数
var video;
//ページを読み込み終わったら実行
window.onload = function() {
//カメラ画像のサイズ設定
var constraints = { video: { width: 640, height: 480 } };
//カメラデバイスの取得
navigator.mediaDevices.getUserMedia(constraints).then(
function(mediaStream) {
//body内のid=videoの要素を取得
video = document.getElementById("video");
//リアルタイム映像をvideo要素に対応づける
video.srcObject = mediaStream;
//準備が整ったら再生
video.onloadedmetadata = function(e) {
video.play();
//顔認識を開始(このあと記述)
StartTracking();
};
}
);
};
Lesson05
顔の認識
//ビデオを扱う変数
var video;
//顔認識の学習モデル
var model;
//ページを読み込み終わったら実行
window.onload = function() {
//カメラ画像のサイズ設定
let constraints = { video: { width: 640, height: 480 } };
//カメラデバイスの取得
navigator.mediaDevices.getUserMedia(constraints).then(
//スペースの都合上省略
//カメラの準備が整ったらStartTrackingを呼び出す
);
}
//トラッキング開始準備の関数
async function StartTracking(){
//顔認識のための学習モデル読み込み
model = await facemesh.load();
//顔認識のループ(次のステップで使用)
FaceTrackingLoop();
} Lesson06
顔の認識
//ビデオを扱う変数
var video;
//顔認識の学習モデル
var model;
window.onload = function() {/*スペースの都合上省略*/ };
async function StartTracking(){
model = await facemesh.load();
FaceTrackingLoop();
}
//顔検出と描画のループ
async function FaceTrackingLoop() {
//顔の検出
let predictions = await model.estimateFaces(video);
//見つかった顔が1つ以上あれば
if (predictions.length > 0) {
//検出された顔の情報にアクセスして表示
console.log(predictions[0]);
}
requestAnimationFrame(FaceTrackingLoop);
} Lesson07
動作確認
カメラの映像は表示されるけど、
学習データの読み込みに時間がかかる
動作確認(FireFox)
①何のない箇所を右クリック
②要素を調査
動作確認(FireFox)
①コンソール
②検出結果
認識結果の内訳
faceInViewConfidence: 1, //顔らしさ(信頼度 0~1)
boundingBox: { // 顔を囲む矩形の角の座標
topLeft: [232.28, 145.26],
bottomRight: [449.75, 308.36],
},
mesh: [ // 顔の各特徴の座標[x,y,z] (認識用に192x192pxに縮小した画像上の座標)
[92.07, 119.49, -17.54], [91.97, 102.52, -30.54], ...
],
scaledMesh: [// 顔の各特徴の座標[x,y,z] (ビデオ画像の座標)
[322.32, 297.58, -17.54], [322.18, 263.95, -30.54], ...
],
annotations: { //顔のパーツと座標の組み合わせ
silhouette: [
[326.19, 124.72, -3.82], [351.06, 126.30, -3.00], ...
],
...
}
顔の特徴点は全部で468個
続いて、特徴点を描画しよう
ハンズオン手順
 ビデオ画像の取得と表示
 facemeshで顔の認識
 認識結果をAR表示する準備
 顔の特徴点を表示
 顔をポリゴン化
 テクスチャの貼り付け
文字の表示を止める
//ビデオを扱う変数
var video;
//顔認識の学習モデル
var model;
window.onload = function() {/*スペースの都合上省略*/ };
async function StartTracking(){
model = await facemesh.load();
FaceTrackingLoop();
};
//顔検出と描画のループ
async function FaceTrackingLoop() {
//顔の検出
let predictions = await model.estimateFaces(video);
//見つかった顔が1つ以上あれば
if (predictions.length > 0) {
//検出された顔の情報にアクセスして表示
console.log(predictions[0]);
}
requestAnimationFrame(FaceTrackingLoop);
}
//console.log(predictions[0]);
文字の表示は不要
グラフィックス表示領域(Canvas)の設定
<html>
<head>
<meta charset="utf-8" />
<!--TensorFlow関連の読み込み-->
<script src="https://unpkg.com/@tensorflow/tfjs-core@2.1.0/dist/tf-core.js"></script>
<script src="https://unpkg.com/@tensorflow/tfjs-converter@2.1.0/dist/tf-converter.js"></script>
<script src="https://unpkg.com/@tensorflow/tfjs-backend-webgl@2.1.0/dist/tf-backend-webgl.js">
</script>
<!--FaceMesh(顔認識)の読み込み-->
<script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/facemesh"></script>
<!--three.js:あとで顔のメッシュ表示の際に使用する-->
<script src=“https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js”></script>
<script type=“text/javascript”> /*本ハンズオンで記述中(省略)*/ </script>
</head>
<body>
<video id="video" style="position: absolute;"></video>
<canvas id="output" style=" position: absolute; "></canvas>
</body>
</html> javascriptで操作する時の名前はoutputとする
Lesson08
このあと・・・
公式サンプルではcanvasの描画機能を使用して顔の特徴点を描画
ただし今回は・・・
顔に画像を貼るテクスチャマッピングを実現し易いthree.jsを使用
でも・・・
three.jsは初期設定などが必要で初心者向きではない
初期設定用のスクリプトは勉強会用に事前に用意しました!
threejs-ex.jsに記述済み
three.js利用の手間を省くスクリプト
<html>
<head>
<meta charset="utf-8" />
<!--TensorFlow関連の読み込み-->
<script src="https://unpkg.com/@tensorflow/tfjs-core@2.1.0/dist/tf-core.js"></script>
<script src="https://unpkg.com/@tensorflow/tfjs-converter@2.1.0/dist/tf-converter.js"></script>
<script src="https://unpkg.com/@tensorflow/tfjs-backend-webgl@2.1.0/dist/tf-backend-webgl.js">
</script>
<!--FaceMesh(顔認識)の読み込み-->
<script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/facemesh"></script>
<!--three.js:あとで顔のメッシュ表示の際に使用する-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js"></script>
<!--勉強会用に用意したthree.jsの初期設定スクリプト-->
<script src="threejs-ex.js"></script>
<script type="text/javascript"> /*本ハンズオンで記述中(省略)*/ </script>
</head>
<body>
<video id="video" style="position: absolute;"></video>
<canvas id="output" style=" position: absolute; "></canvas>
</body>
</html> Lesson09
顔の特徴点を描画
<html>
<head>
<meta charset="utf-8" />
<!--TensorFlow関連の読み込み-->
<script src="https://unpkg.com/@tensorflow/tfjs-core@2.1.0/dist/tf-core.js"></script>
<script src="https://unpkg.com/@tensorflow/tfjs-converter@2.1.0/dist/tf-converter.js"></script>
<script src="https://unpkg.com/@tensorflow/tfjs-backend-webgl@2.1.0/dist/tf-backend-webgl.js">
</script>
<!--FaceMesh(顔認識)の読み込み-->
<script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/facemesh"></script>
<!--three.js:あとで顔のメッシュ表示の際に使用する-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js"></script>
<!--勉強会用に用意したthree.jsの初期設定スクリプト-->
<script src="threejs-ex.js"></script>
<script type="text/javascript"> /*こちらの編集に戻る*/ </script>
</head>
<body>
<video id="video" style="position: absolute;"></video>
<canvas id="output" style=" position: absolute; "></canvas>
</body>
</html>
ここを編集!
three.jsを使う準備
<script type="text/javascript">
var video;
window.onload = function() {
let constraints = { video: { width: 640, height: 480 } };
navigator.mediaDevices.getUserMedia(constraints).then(
function(mediaStream) {
video = document.getElementById("video");
video.srcObject = mediaStream;
video.onloadedmetadata = function(e) {
video.play();
//Three.jsでの描画に関するセッティング(このあと記述)
InitRendering();
StartTracking();
};
}
);
};
</script> Lesson10
three.jsを使う準備
window.onload = function() {
let constraints = { video: { width: 640, height: 480 } };
navigator.mediaDevices.getUserMedia(constraints).then(
//スペースの都合上省略
//InitRenderingとStartTrackingを呼び出してる。
);
}
//THREE.jsで描画するための準備
function InitRendering(){
//ビデオ表示領域のサイズを明確に設定
let videoWidth = video.videoWidth;
let videoHeight = video.videoHeight;
video.width = videoWidth;
video.height = videoHeight;
//描画領域のサイズを指定
let canvas = document.getElementById("output");
canvas.width = videoWidth;
canvas.height = videoHeight;
//描画に関する初期設定 (threejs-ex.js内)
InitThreejs(canvas);
}
async function StartTracking(){ /*トラッキング開始準備*/ } Lesson11
ハンズオン手順
 ビデオ画像の取得と表示
 facemeshで顔の認識
 認識結果をAR表示する準備
 顔の特徴点を表示
 顔をポリゴン化
 テクスチャの貼り付け
顔描画のための3Dデータ作成
var video;
var model; //顔認識のための学習モデル
var faceMesh; //顔の3Dデータ
window.onload = function() {
let constraints = { video: { width: 640, height: 480 } };
navigator.mediaDevices.getUserMedia(constraints).then(
function(mediaStream) {
video = document.getElementById("video");
video.srcObject = mediaStream;
video.onloadedmetadata = function(e) {
video.play();
InitRendering();
//顔の3Dモデルを作成 (このあと記述)
CreateFaceObject();
StartTracking();
};
}
);
}
Lesson12
顔描画のための3Dデータ作成
var video;
var model;
var faceMesh;
window.onload = function() {
/*諸々の初期化。スペースの都合上、省略*/
}
このあと、この辺りにCreateFaceObject関数を記述
function InitRendering(){
/*three.jsの初期化。さっきまで解説していたところ*/
}
async function StartTracking(){
/*学習モデルの読み込みと顔認識スタート*/
}
async function FaceTrackingLoop() {
/*顔を検出するループ*/
}
顔描画のための3Dデータ作成
function CreateFaceObject() {
//顔の形状をgeometryで管理
let geometry = new THREE.Geometry();
//頂点を登録(座標は今のところ適当)
for (let i = 0; i < 468; i++) {
geometry.vertices.push(new THREE.Vector3(0, 0, 0));
}
//色などの見た目情報をmateriaに登録
let material= new THREE.PointsMaterial( { color: 0x0000FF, size: 3 } );
//faceMeshに形状(geometry)と見た目(material)を登録。
faceMesh= new THREE.Points( geometry, material );
//three.jsに登録(threejs-ex.js内で処理)
AddToThreejs(faceMesh);
}
Lesson13
顔の特徴点をリアルタイムに描画
window.onload = function() {
/*諸々の初期化。スペースの都合上、省略*/
}
function CreateFaceObject() {
/*顔の3Dデータを作る*/
}
function InitRendering(){
/*three.jsの初期化*/
}
async function StartTracking(){
/*学習モデルの読み込みと顔認識スタート*/
}
async function FaceTrackingLoop() {
/*顔を検出するループ*/
}
顔の検出結果を3Dモデルに反映させる
顔の特徴点をリアルタイムに描画
async function FaceTrackingLoop() {
let predictions = await model.estimateFaces(video);
if (predictions.length > 0) {
//検出された顔の頂点配列にアクセス
let keypoints = predictions[0].scaledMesh;
//顔の3Dモデルの頂点等の情報にアクセス
let geometry=faceMesh.geometry;
for (let i = 0; i < keypoints.length; i++) {
let x = keypoints[i][0];
let y = keypoints[i][1];
geometry.vertices[i].set(x-video.width/2, -y+video.height/2, 1);
}
//情報の更新を許可
faceMesh.geometry.verticesNeedUpdate = true;
}
//上記の情報をThree.jsで描画
RenderThreejs();
requestAnimationFrame(FaceTrackingLoop);
}
Lesson14
動作確認
ハンズオン手順
 ビデオ画像の取得と表示
 facemeshで顔の認識
 認識結果をAR表示する準備
 顔の特徴点を表示
 顔をポリゴン化
 テクスチャの貼り付け
ポリゴン化しよう
顔の検出結果
 各頂点にはそれぞれ番号があらかじめ
割り振られている
 三角形を作るには結ぶ頂点の番号を
指定する
例) 67 69 109、10 108 151、・・・
 接続番号のリストはtriangulation.js
で提供
67
104
69
109 10
337
336
108 151
910766105
ポリゴン化しよう
三角形を表現するための3点の番号が配列に全部並ぶ => 要素数は三角形の数 × 3
ポリゴン化しよう
<html>
<head>
<meta charset="utf-8" />
<!--TensorFlow関連の読み込み-->
<script src="https://unpkg.com/@tensorflow/tfjs-core@2.1.0/dist/tf-core.js"></script>
<script src="https://unpkg.com/@tensorflow/tfjs-converter@2.1.0/dist/tf-converter.js"></script>
<script src="https://unpkg.com/@tensorflow/tfjs-backend-webgl@2.1.0/dist/tf-backend-webgl.js">
</script>
<!--FaceMesh(顔認識)の読み込み-->
<script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/facemesh"></script>
<!--three.js:あとで顔のメッシュ表示の際に使用する-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js"></script>
<!--勉強会用に用意したthree.jsの初期設定スクリプト-->
<script src="threejs-ex.js"></script>
<!—三角形の頂点の接続情報-->
<script src="triangulation.js"></script>
<script type="text/javascript"> /*本ハンズオンで記述中(省略)*/ </script>
</head>
<body> 省略 </body>
</html>
Lesson15
ポリゴン化しよう
window.onload = function() {
/*諸々の初期化。スペースの都合上、省略*/
}
function CreateFaceObject() {
/*顔の3Dデータを作る*/
}
function InitRendering(){
/*three.jsの初期化*/
}
async function StartTracking(){
/*学習モデルの読み込みと顔認識スタート*/
}
async function FaceTrackingLoop() {
/*顔を検出するループ*/
}
顔の3Dモデルをポリゴンとして設定
ポリゴン化しよう
function CreateFaceObject() {
let geometry = new THREE.Geometry();
//頂点を登録
for (let i = 0; i < 468; i++) {
geometry.vertices.push(new THREE.Vector3(0, 0, 0));
}
//頂点の接続情報
let index,p0,p1,p2;
for (let i = 0; i < TRIANGULATION.length / 3; i++) {
index= i * 3;
p0 = TRIANGULATION[index];
p1 = TRIANGULATION[index+1];
p2 = TRIANGULATION[index+2];
geometry.faces.push(new THREE.Face3(p0,p1,p2));
}
//色などの見た目情報をmaterial管理
let material= new THREE.PointsMaterial( { color: 0x0000FF, size: 3 } );
//faceMeshに形状(geometry)と見た目(material)を登録。
faceMesh= new THREE.Points( geometry, material );
AddToThreejs(faceMesh);
}
Lesson16
ポリゴン化しよう
let geometry = new THREE.Geometry();
for (let i = 0; i < 468; i++) {
geometry.vertices.push(new THREE.Vector3(0, 0, 0));
}
//頂点の接続情報
let index,p0,p1,p2;
for (let i = 0; i < TRIANGULATION.length / 3; i++) {
index= i * 3;
p0 = TRIANGULATION[index];
p1 = TRIANGULATION[index+1];
p2 = TRIANGULATION[index+2];
geometry.faces.push(new THREE.Face3(p0,p1,p2));
}
//色などの見た目情報をmaterial管理
let material= new THREE.PointsMaterial( { color: 0x0000FF, size: 3 } );
let material = new THREE.MeshBasicMaterial( {wireframe:true} );
//faceMeshに形状(geometry)と見た目(material)を登録。
faceMesh= new THREE.Points( geometry, material );
faceMesh= new THREE.Mesh( geometry, material );
//three.jsに登録
AddToThreejs(faceMesh);
let material= new THREE.PointsMaterial( { color: 0x0000FF, size: 3 } );
faceMesh= new THREE.Points( geometry, material );
Lesson17
動作確認
ハンズオン手順
 ビデオ画像の取得と表示
 facemeshで顔の認識
 認識結果をAR表示する準備
 顔の特徴点を表示
 顔をポリゴン化
 テクスチャの貼り付け
顔に画像を貼ろう
 AIが認識した顔の特徴点とテクスチャ画像中の座標を対応づける
 画像中の座標はピクセル(x,y)ではなく全体に対する割合(u,v)で指定する
→ これにより様々なサイズの画像を貼り付けられる!
 特徴点に対応するuv座標のリストはuv-coords.jsにて提供
認識結果 テクスチャ
UV座標のリスト
顔の特徴点に対応するUV座標がUV_COORDSという配列に羅列されている
0番目のuv
3番目のuv
テクスチャ画像を貼り付けよう
<html>
<head>
<meta charset="utf-8" />
<!--TensorFlow関連の読み込み-->
<script src="https://unpkg.com/@tensorflow/tfjs-core@2.1.0/dist/tf-core.js"></script>
<script src="https://unpkg.com/@tensorflow/tfjs-converter@2.1.0/dist/tf-converter.js"></script>
<script src="https://unpkg.com/@tensorflow/tfjs-backend-webgl@2.1.0/dist/tf-backend-webgl.js">
</script>
<!--FaceMesh(顔認識)の読み込み-->
<script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/facemesh"></script>
<!--three.js:あとで顔のメッシュ表示の際に使用する-->
<script src=“https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js”></script>
<!--勉強会用に用意したthree.jsの初期設定スクリプト-->
<script src="threejs-ex.js"></script>
<!—三角形の頂点の接続情報-->
<script src="triangulation.js"></script>
<!—三角形の頂点の接続情報-->
<script src="uv-coords.js"></script>
<script type=“text/javascript”> /*本ハンズオンで記述中(省略)*/ </script>
</head>
以下省略 Lesson18
テクスチャ画像を貼り付けよう
<html>
<head>
<meta charset="utf-8" />
<!--TensorFlow関連の読み込み-->
<script src="https://unpkg.com/@tensorflow/tfjs-core@2.1.0/dist/tf-core.js"></script>
<script src="https://unpkg.com/@tensorflow/tfjs-converter@2.1.0/dist/tf-converter.js"></script>
<script src="https://unpkg.com/@tensorflow/tfjs-backend-webgl@2.1.0/dist/tf-backend-webgl.js">
</script>
<!--FaceMesh(顔認識)の読み込み-->
<script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/facemesh"></script>
<!--three.js:あとで顔のメッシュ表示の際に使用する-->
<script src=“https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js”></script>
<!--勉強会用に用意したthree.jsの初期設定スクリプト-->
<script src="threejs-ex.js"></script>
<!—三角形の頂点の接続情報-->
<script src="triangulation.js"></script>
<!—三角形の頂点の接続情報-->
<script src="uv-coords.js"></script>
<script type=“text/javascript”> /*こちらの編集に戻る*/ </script>
</head>
以下省略 ここを編集!
テクスチャ画像を貼り付けよう
window.onload = function() {
/*諸々の初期化。スペースの都合上、省略*/
}
function CreateFaceObject() {
/*顔の3Dデータを作る*/
}
function InitRendering(){
/*three.jsの初期化*/
}
async function StartTracking(){
/*学習モデルの読み込みと顔認識スタート*/
}
async function FaceTrackingLoop() {
/*顔を検出するループ*/
}
顔の3Dモデルに画像を貼り付ける
テクスチャ画像を貼り付けよう
let geometry = new THREE.Geometry();
for (let i = 0; i < 468; i++) {
geometry.vertices.push(new THREE.Vector3(0, 0, 0));
}
//頂点の接続情報とテクスチャ座標対応づけ
let index,p0,p1,p2;
for (let i = 0; i < TRIANGULATION.length / 3; i++) {
index= i * 3;
p0 = TRIANGULATION[index];
p1 = TRIANGULATION[index+1];
p2 = TRIANGULATION[index+2];
geometry.faces.push(new THREE.Face3(p0,p1,p2));
}
//色などの見た目情報をmaterial管理
let material = new THREE.MeshBasicMaterial( {wireframe:true} );
//faceMeshに形状(geometry)と見た目(material)を登録。
faceMesh= new THREE.Mesh( geometry, material );
//three.jsに登録(threejs-ex.js内で処理)
AddToThreejs(faceMesh);
テクスチャ画像を貼り付けよう
let geometry = new THREE.Geometry();
for (let i = 0; i < 468; i++) {
geometry.vertices.push(new THREE.Vector3(0, 0, 0));
}
//頂点の接続情報とテクスチャ座標対応づけ
let index,p0,p1,p2;
for (let i = 0; i < TRIANGULATION.length / 3; i++) {
index= i * 3;
p0 = TRIANGULATION[index];
p1 = TRIANGULATION[index+1];
p2 = TRIANGULATION[index+2];
geometry.faces.push(new THREE.Face3(p0,p1,p2));
}
//色などの見た目情報をmaterial管理
let material = new THREE.MeshBasicMaterial( {wireframe:true} );
//faceMeshに形状(geometry)と見た目(material)を登録。
faceMesh= new THREE.Mesh( geometry, material );
//three.jsに登録(threejs-ex.js内で処理)
AddToThreejs(faceMesh);
ここを編集!
テクスチャ画像を貼り付けよう
let index,p0,p1,p2;
for (let i = 0; i < TRIANGULATION.length / 3; i++) {
index= i * 3;
p0 = TRIANGULATION[index];
p1 = TRIANGULATION[index+1];
p2 = TRIANGULATION[index+2];
geometry.faces.push(new THREE.Face3(p0,p1,p2));
//UV座標を指定
geometry.faceVertexUvs[0].push([
new THREE.Vector2(UV_COORDS[p0][0],1-UV_COORDS[p0][1]),
new THREE.Vector2(UV_COORDS[p1][0],1-UV_COORDS[p1][1]),
new THREE.Vector2(UV_COORDS[p2][0],1-UV_COORDS[p2][1])]);
}
let texture = new THREE.TextureLoader().load("画像のURL");
//色などの見た目情報をmaterial管理
let material = new THREE.MeshBasicMaterial( {wireframe:true} );
let material = new THREE.MeshBasicMaterial( {map: texture, alphaTest:0.1} );
let material = new THREE.MeshBasicMaterial( {wireframe:true} );
Lesson19
貼り付ける画像をアップロード
assets
貼り付ける画像をアップロード
Upload an Asset
貼り付ける画像をアップロード
mesh_map.jpg
選択
貼り付ける画像をアップロード
画像をクリック
貼り付ける画像をアップロード
copy
貼り付ける画像をアップロード
空白をクリック
テクスチャ画像を貼り付けよう
function CreateFaceObject() {
let geometry = new THREE.Geometry();
//頂点を登録
for (let i = 0; i < 468; i++) {
geometry.vertices.push(new THREE.Vector3(0, 0, 0));
}
//頂点の接続情報
let index,p0,p1,p2;
for (let i = 0; i < TRIANGULATION.length / 3; i++) {
index= i * 3;
p0 = TRIANGULATION[index];
p1 = TRIANGULATION[index+1];
p2 = TRIANGULATION[index+2];
geometry.faces.push(new THREE.Face3(p0,p1,p2));
//UV座標を指定
geometry.faceVertexUvs[0].push([
new THREE.Vector2(UV_COORDS[p0][0],1-UV_COORDS[p0][1]),
new THREE.Vector2(UV_COORDS[p1][0],1-UV_COORDS[p1][1]),
new THREE.Vector2(UV_COORDS[p2][0],1-UV_COORDS[p2][1])]);
}
let texture = new THREE.TextureLoader().load( "画像のURLをここに貼り付ける" );
//色などの見た目情報をmaterial管理
let material = new THREE.MeshBasicMaterial( {map: texture, alphaTest:0.1} );
faceMesh= new THREE.Mesh( geometry, material );
AddToThreejs(faceMesh);
}
動作確認
完成
おまけ
画像アップロードに対応
Uploadボタンを追加
<html>
<head>
<meta charset="utf-8" />
<!--TensorFlow関連の読み込み-->
<script src="https://unpkg.com/@tensorflow/tfjs-core@2.1.0/dist/tf-core.js"></script>
<script src="https://unpkg.com/@tensorflow/tfjs-converter@2.1.0/dist/tf-converter.js"></script>
<script src="https://unpkg.com/@tensorflow/tfjs-backend-webgl@2.1.0/dist/tf-backend-webgl.js">
</script>
<!--FaceMesh(顔認識)の読み込み-->
<script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/facemesh"></script>
<!--three.js:あとで顔のメッシュ表示の際に使用する-->
<script src=“https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js”></script>
<script type=“text/javascript”> /*本ハンズオンで記述中(省略)*/ </script>
</head>
<body>
<input type="file" id="file"><br>
<video id="video" style="position: absolute;"></video>
<canvas id="output" style=" position: absolute; "></canvas>
</body>
</html>
javascriptで操作する時の名前はfileとする
Lesson20
Upload機能の記述
window.onload = function() {
/*諸々の初期化。スペースの都合上、省略*/
}
function CreateFaceObject() {
/*顔の3Dデータを作る*/
}
function InitRendering(){
/*three.jsの初期化*/
}
async function StartTracking(){
/*学習モデルの読み込みと顔認識スタート*/
}
async function FaceTrackingLoop() {
/*顔を検出するループ*/
}
window.onloadに記述
Upload機能の記述
window.onload = function() {
let file = document.getElementById('file');
// ファイルが指定された時にloadLocalImage()を実行
file.addEventListener('change', loadLocalImage, false);
let constraints = { video: { width: 640, height: 480 } };
navigator.mediaDevices.getUserMedia(constraints).then(
function(mediaStream) {
video = document.getElementById("video");
video.srcObject = mediaStream;
video.onloadedmetadata = function(e) {
video.play();
InitRendering();
CreateFaceObject();
StartTracking();
};
}
);
} Lesson21
Upload機能の記述
window.onload = function() {
/*諸々の初期化。スペースの都合上、省略*/
}
このあとこの辺りに loadLocalImage関数を追加(コピペ)
function CreateFaceObject() {
/*顔の3Dデータを作る*/
}
function InitRendering(){
/*three.jsの初期化*/
}
async function StartTracking(){
/*学習モデルの読み込みと顔認識スタート*/
}
Upload機能の記述
function loadLocalImage(e) {
// ファイル情報を取得
let fileData = e.target.files[0];
// 画像ファイル以外は処理を止める
if(!fileData.type.match('image.*')) {
alert('画像を選択してください’); return;
}
// FileReaderオブジェクトを使ってファイル読み込み
let reader = new FileReader();
reader.onload = function() {
//画像をテクスチャとして読み込む
var tex= new THREE.TextureLoader().load(reader.result);
faceMesh.material.map=tex;
}
// ファイル読み込みを実行
reader.readAsDataURL(fileData);
} Lesson22
完成!
https://facemesh-arfukuoka.glitch.me
AI x WebAR MediaPipeの顔認識を使ってみよう! in 織りなすラボ

More Related Content

PPTX
AI x WebAR! MediaPipeの顔認識を使ってみよう!
PPTX
A-Frameで始めるWebXRとハンドトラッキング (HoloLens2/Oculus Quest対応)
PPTX
AI x OpenCV x WebAR: Selfie Segmentationを使ってみよう
PPTX
MRTKをNreal Lightに対応させてみた
PPTX
AI x WebAR: MediaPipeのハンドトラッキングを使ってみよう
PPTX
AI x WebXR: フェイストラッキングを用いた擬似3D表現を解説!
PDF
猫でも分かるUE4のポストプロセスを使った演出・絵作り
PDF
レシピの作り方入門
AI x WebAR! MediaPipeの顔認識を使ってみよう!
A-Frameで始めるWebXRとハンドトラッキング (HoloLens2/Oculus Quest対応)
AI x OpenCV x WebAR: Selfie Segmentationを使ってみよう
MRTKをNreal Lightに対応させてみた
AI x WebAR: MediaPipeのハンドトラッキングを使ってみよう
AI x WebXR: フェイストラッキングを用いた擬似3D表現を解説!
猫でも分かるUE4のポストプロセスを使った演出・絵作り
レシピの作り方入門

What's hot (20)

PDF
MetaHumanサンプル解体新書 UNREAL FEST EXTREME 2021 SUMMER
PPTX
CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~
PDF
【Unite Tokyo 2019】SRPで一から描画フローを作ってみた! ~Unity描画フローからの脱却~
PPTX
Unityプロファイラについて
PDF
Immersal を活用した AR クラウドなシステム開発とハンズオン!
PDF
アーティスト向けNSightの手引き
PDF
アナザーエデンにおける非同期オートセーブを用いた通信待ちストレスのないゲーム体験の実現
PPTX
なぜなにリアルタイムレンダリング
PDF
Real-time Web Application with Socket.IO, Node.js, and Redis
PPTX
マテリアルとマテリアルインスタンスの仕組みと問題点の共有 (Epic Games Japan: 篠山範明) #UE4DD
PDF
Web開発者が始める .NET MAUI Blazor App
PDF
【Unite Tokyo 2019】Unity Test Runnerを活用して内部品質を向上しよう
PPTX
Azure Spatial Anchorsを活用したHoloLens & Androidシェアリングアプリ
PPTX
MVPパターンによる設計アプローチ「あなたのアプリ報連相できてますか」
PDF
エキスパートPythonプログラミング改訂3版の読みどころ
PDF
Unity開発で使える設計の話+Zenjectの紹介
PPTX
Flutter Intro
PDF
Dockerの期待と現実~Docker都市伝説はなぜ生まれるのか~
PDF
【Unite 2018 Tokyo】『CARAVAN STORIES』のアセットバンドル事例
MetaHumanサンプル解体新書 UNREAL FEST EXTREME 2021 SUMMER
CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~
【Unite Tokyo 2019】SRPで一から描画フローを作ってみた! ~Unity描画フローからの脱却~
Unityプロファイラについて
Immersal を活用した AR クラウドなシステム開発とハンズオン!
アーティスト向けNSightの手引き
アナザーエデンにおける非同期オートセーブを用いた通信待ちストレスのないゲーム体験の実現
なぜなにリアルタイムレンダリング
Real-time Web Application with Socket.IO, Node.js, and Redis
マテリアルとマテリアルインスタンスの仕組みと問題点の共有 (Epic Games Japan: 篠山範明) #UE4DD
Web開発者が始める .NET MAUI Blazor App
【Unite Tokyo 2019】Unity Test Runnerを活用して内部品質を向上しよう
Azure Spatial Anchorsを活用したHoloLens & Androidシェアリングアプリ
MVPパターンによる設計アプローチ「あなたのアプリ報連相できてますか」
エキスパートPythonプログラミング改訂3版の読みどころ
Unity開発で使える設計の話+Zenjectの紹介
Flutter Intro
Dockerの期待と現実~Docker都市伝説はなぜ生まれるのか~
【Unite 2018 Tokyo】『CARAVAN STORIES』のアセットバンドル事例
Ad

Similar to AI x WebAR MediaPipeの顔認識を使ってみよう! in 織りなすラボ (20)

PDF
Face Recognition with OpenCV and scikit-learn
PDF
OpenCVとARCoreで作るスタンプAR in 宮崎
PPTX
OpenCVでつくろうARスタンプアプリ in 熊本
PPTX
HoloLens2とMeta QuestではじめるWebXR
PDF
20120623 cv勉強会 shirasy
PPTX
OSC2020 Fukuoka: インストールいらず、WebAR入門
KEY
東の方からきました@鹿駆動勉強会
PDF
AV 画像認識とその周辺 - UT Startup Gym 講演資料
PPTX
[Glitch版] 0から始めようWebAR/VR入門ハンズオン with 織りなすラボ
PDF
PWA+WebARをECサイトで使ってみたい
PPTX
[Netlify版] 0から始めようWebAR/VR入門ハンズオン with 織りなすラボ
PPTX
エンジニアカフェ1周年イベント:WebAR/VR開発入門
PDF
OpenCVで作るスタンプAR
PDF
【DL輪読会】Monocular real time volumetric performance capture
PDF
顔認識の未来について語ろう! (CVPR 2018 完全読破チャレンジ報告会)
PPTX
AR-Frame x AR.js入門
PPTX
「マンガテレビ」の作り方
PDF
JavascriptでFaceTrackerを使う
PDF
LIFULL HOME'S「かざして検索」リリースの裏側
PDF
OpenCV/ARCore/Unityで作る塗り絵AR
Face Recognition with OpenCV and scikit-learn
OpenCVとARCoreで作るスタンプAR in 宮崎
OpenCVでつくろうARスタンプアプリ in 熊本
HoloLens2とMeta QuestではじめるWebXR
20120623 cv勉強会 shirasy
OSC2020 Fukuoka: インストールいらず、WebAR入門
東の方からきました@鹿駆動勉強会
AV 画像認識とその周辺 - UT Startup Gym 講演資料
[Glitch版] 0から始めようWebAR/VR入門ハンズオン with 織りなすラボ
PWA+WebARをECサイトで使ってみたい
[Netlify版] 0から始めようWebAR/VR入門ハンズオン with 織りなすラボ
エンジニアカフェ1周年イベント:WebAR/VR開発入門
OpenCVで作るスタンプAR
【DL輪読会】Monocular real time volumetric performance capture
顔認識の未来について語ろう! (CVPR 2018 完全読破チャレンジ報告会)
AR-Frame x AR.js入門
「マンガテレビ」の作り方
JavascriptでFaceTrackerを使う
LIFULL HOME'S「かざして検索」リリースの裏側
OpenCV/ARCore/Unityで作る塗り絵AR
Ad

More from Takashi Yoshinaga (18)

PPTX
【準備編】OculusQuest/HoloLens2対応WebXR開発
PPTX
ARコンテンツ作成勉強会( #AR_Fukuoka )紹介
PPTX
iPad LiDARで エンジニアカフェを3Dスキャン
PPTX
Web技術ではじめようAR/VRアプリ開発
PPTX
Nreal Lightハンズオン
PPTX
【準備編!】HoloLens 2/Oculus Quest対応WebXRハンズオン
PPTX
Holo-SDKハンズオン:はじめようヘッドトラッキングを用いた3D表現
PPTX
FUKUOKA Engineers Day 2021 発表資料:AR Fukuoka & HoloBox紹介
PPTX
Voxon Photonics VX1 で遊んでみた
PPTX
コロナ禍中のコミュニティ活動
PPTX
Project HoloBox
PPTX
AR Fukuoka紹介2020
PPTX
iPad LiDARで作ってみた in AR Fukuoka 忘年会2020
PPTX
MRTKで始めるAR開発 (HoloLens 1 and 2, ARCore, ARkit)
PPTX
Oculus Quest 1&2 開発のはじめの一歩 with A-Frame WebVR
PPTX
Spatial Copy & Paste @HoloLensゆるっとLT会
PPTX
ノンプログラミングで始めるAR (HoloLens 2 / ARCore / ARKit) 開発 with MRTK
PPTX
0から始めようWebAR/VR入門ハンズオン
【準備編】OculusQuest/HoloLens2対応WebXR開発
ARコンテンツ作成勉強会( #AR_Fukuoka )紹介
iPad LiDARで エンジニアカフェを3Dスキャン
Web技術ではじめようAR/VRアプリ開発
Nreal Lightハンズオン
【準備編!】HoloLens 2/Oculus Quest対応WebXRハンズオン
Holo-SDKハンズオン:はじめようヘッドトラッキングを用いた3D表現
FUKUOKA Engineers Day 2021 発表資料:AR Fukuoka & HoloBox紹介
Voxon Photonics VX1 で遊んでみた
コロナ禍中のコミュニティ活動
Project HoloBox
AR Fukuoka紹介2020
iPad LiDARで作ってみた in AR Fukuoka 忘年会2020
MRTKで始めるAR開発 (HoloLens 1 and 2, ARCore, ARkit)
Oculus Quest 1&2 開発のはじめの一歩 with A-Frame WebVR
Spatial Copy & Paste @HoloLensゆるっとLT会
ノンプログラミングで始めるAR (HoloLens 2 / ARCore / ARKit) 開発 with MRTK
0から始めようWebAR/VR入門ハンズオン

AI x WebAR MediaPipeの顔認識を使ってみよう! in 織りなすラボ