BLOGブログ
【Tech Blog】Web AR の実現例とライブラリについて①
文責:藤木 直希
- AR
- OSS
当社では様々なプラットフォームを利用した xR の調査・検証を行っており、その中でブラウザから実行できる Web AR の調査や Web ARを活用した課題解決も行っています。
ニュース記事で Web AR を活用した事例「『 Virtua Fighter 』なりきりキャラクター」をお知らせしていますが、「 Web AR で出来ること」「代表的なライブラリでの実装例」などを複数回に分けて紹介していきたいと思います。
Web ARで出来ること
まず初めに、Web AR の技術自体は目新しい技術ではなく、古くから多くの OSS ライブラリがあり、出来ることは様々です。
しかし、端末スペックの向上やブラウザ側の対応により、Web 上で実現できる体験は日々進化・拡大しています。
また、コロナ禍におけるプロモーション方法の変化などもあり、端末を利用してすぐにその場で体験できる Web AR は需要が高まってきています。
※OSS:Open Source Software の略で、ソースコードを使用、調査、再利用、変更、拡張、および再配布が可能なソフトフェアの総称
Web AR ではカメラ上に何かを表示するだけではなく、色々な OSS を組み合わせることによって、様々な体験を作ることが出来ます。
例としては下記のようなものが挙げられます。
- 位置情報
- AR マーカー・画像認識
- フェイストラッキング
- ハンドトラッキング
ここでは Web AR の一つの要素として、『 Virtua Fighter 』なりきりキャラクター」 でも活用したフェイストラッキングについて、代表的なライブラリでの実装例などを紹介していきたいと思います。
「『 Virtua Fighter 』なりきりキャラクター」についてはこちらのニュースの記事をご確認ください。
フェイストラッキング
フェイストラッキングには face-api.js、jeelizFaceFilter などの有名な OSS ライブラリがあります。
フェイストラッキングの特徴としては、画像や動画に映る顔の位置座標を取得できることですが、利用するライブラリによって認識精度や同時に認識できる人数などは様々です。
またライブラリによっては学習データを元に表情や年齢・性別などを予測して取得する事が可能なものもあります。
face-api.js による顔認識
face-api.js による顔認識の特徴としては下記があります。
- 認識の精度が非常に良い
- 顔の位置、顔パーツの位置/輪郭を取得が出来る
- 喜怒哀楽などの表情を取得が出来る
- 性別、年齢を予測して取得することが出来る
face-api.js を利用したシンプルな実装コードは下記のようになります。
<html>
<head>
<meta charset="UTF-8">
<script src="face-api.js/face-api.min.js"></script>
<style>
#video-main, #overlay{
position: absolute;
top: 0px;
left: 0px;
}
</style>
</head>
<body>
<video width="640" height="480" id="video-main" preload="auto" loop playsinline autoplay muted></video>
<canvas id="overlay" width="640" height="480"></canvas>
<script src="main.js"></script>
</body>
</html
スクリプト内ではまず、カメラの表示を画面に表示するためvideo要素にstreamを設定します。
var video = document.getElementById('video-main');
video.addEventListener('loadedmetadata', () =>{
video.play();
});
navigator.mediaDevices.getUserMedia({
video: {
width : { ideal : 640 },
height : { ideal : 480 },
},
audio: false,
}).then((stream) => {
video.srcObject = stream;
}).catch((error) => {
console.error(error);
});
その後、顔認識の学習モデルを読み込み、カメラの映像を表示している video 要素に対して判定します。
main();
async function main() {
// モデルの読み込み
await faceapi.nets.tinyFaceDetector.load('face-api.js/weights');
await faceapi.loadFaceLandmarkModel('face-api.js/weights')
run();
}
var canvas = document.getElementById('overlay');
async function run() {
if(!video.currentTime || video.paused || video.ended) {
return setTimeout(() => run(video))
}
let inputSize = 512
let scoreThreshold = 0.5
const options = new faceapi.TinyFaceDetectorOptions({inputSize, scoreThreshold})
const detection = await faceapi.detectSingleFace(video, options).withFaceLandmarks();
if (detection) {
// 描画するcanvasの用意
const dims = faceapi.matchDimensions(canvas, video)
const resizedResults = faceapi.resizeResults(detection, dims)
// canvasに取得した情報を描画
faceapi.draw.drawDetections(canvas, resizedResults)
faceapi.draw.drawFaceLandmarks(canvas, resizedResults)
}
setTimeout(() => run(video))
}
faceapi.detectSingleFace(video, options).withFaceLandmarks();により、目や口などの顔のパーツの座標が取得できます。
上記の例ではface-api.jsのメソッドで直接canvasに描画していますが、これらの座標情報を使い、口や目の位置に画像や3Dモデルを表示することが可能となります。
jeelizFaceFilter での顔認識
jeelizFaceFilter も同じく顔認識の OSS ライブラリとなっていますが、jeelizFaceFilter では three.js ベースの機能を提供しており、ライブラリ側で行ってくれる処理が face-api.js に比べ多いため、顔の位置に合わせて 3D モデルなどを表示する場合はコードの実装量が少なく簡単に実現することが出来ます。
特徴としては下記となります。
- 顔の位置や傾きに応じて 3D モデルを表示することが出来る
- 口の開閉が取得することが出来る
- 詳細な顔のパーツ位置や輪郭は取得できない
three.js ベースの実装コード例は下記のようになります。
<script src="dist/jeelizFaceFilter.js"></script>
<script src="libs/three/v112/three.js"></script>
<script src="helpers/JeelizThreeHelper.js"></script>
ライブラリを読み込み、 JEEFACEFILTERAPI.init() を実行します。
face-api.js では setTimeout() により繰り返し判定を行い canvas に描画するという処理を実装していましたが、jeelizFaceFilter では canvas の id を指定するだけでライブラリ側が判定処理などを行ってくれています。
start();
var threeStuffs,threeCamera;
function start() {
JEEFACEFILTERAPI.init({
canvasId: 'overlay',
NNCPath: 'neuralNets/NN_DEFAULT.json',
videoElement: document.getElementById('video-main'),
callbackReady: function(errCode, spec) {
if (errCode) {
console.error(errCode);
return;
}
// three.jsのシーンを取得
threeStuffs = JeelizThreeHelper.init(spec, null);
threeCamera = JeelizThreeHelper.create_camera();
// ライトを追加
const light = new THREE.DirectionalLight(0xFFFFFF, 1);
light.position.set(0, 1, 1);
threeStuffs.scene.add(light);
// 3Dオブジェクトを作成
const geo = new THREE.BoxGeometry(1, 1, 1);
const mat = new THREE.MeshLambertMaterial({ color: 0xFFFFFF });
const mesh = new THREE.Mesh(geo, mat);
// 3Dオブジェクトを追加
threeStuffs.faceObject.add(mesh);
},
callbackTrack: function(detectState) {
JeelizThreeHelper.render(detectState, threeCamera);
}
});
}
ThreeStuffs.faceObject は顔の位置や傾きなどに応じて移動・回転するため、faceObjectに追加するだけで3Dオブジェクトが顔の位置・角度に追従して表示されます。
通常、顔の傾きから表示されているオブジェクトへ傾きを反映するといった実装を行う場合は多くの実装が必要となりますが、jeelizFaceFilterによって簡単に実現することが出来ました。
まとめ
Web AR の代表的なライブラリを元に、フェイストラッキングを紹介させていただきました。
Web AR の多くはカメラ内の情報や GPS などの外部の情報を取得し、それらを組み合わせることによって実現しており、技術も日々進化し出来る事が拡大しています。
当社ではこういった技術の組み合わせや、今まで培ったゲーミフィケーション要素と掛け合わせる事によって新しいアイデアを生み出していける事が強みであり、今後も xR 技術を追求し、様々な形で面白いものを生み出し課題解決に役立てていきたいと思います。
プロモーションの相談や新しいアイデア、こんな事はできないか?と言った質問もぜひお問い合わせください。
最後まで読んでいただきありがとうございます。
この記事の内容について詳しく聞きたい方は、以下よりお気軽にお問い合わせください。
※記載されている会社名、製品名は、各社の登録商標または商標です。
- 文責:藤木 直希 エクスペリエンスデザイン部 エンジニア
-
セガ エックスディーで
xR系のR&Dやプロダクトの開発など、様々な開発・推進に取り組んでいます。