オンライン飲み会などで、Webカメラでアクション出来ると面白いかもしれないと思い試しに作成。今回は単純に目をハートにしているだけですが、p5jsを応用すれば色々なエフェクトでアクションが出来て面白いと思う。
WebカメラからfaceAPIで目の位置を特定し、目をハートにしてみました。
画像なので少し分かり辛いかもしれませんが、動くと目の位置に合わせてハートが付いてきてくれます。
#実装あれこれ
利用したライブラリ関係
・ml5.js
・faceapi.js
・p5.js ※今回は使えてない。
#コード
ml5_p5_faceapi.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>MEGAハート</title>
</head>
<body>
<h1>MEGAハート</h1>
<!-- CDNの読み込み -->
<script src="https://unpkg.com/ml5@latest/dist/ml5.min.js"></script>
<!-- <script src="https://cdn.jsdelivr.net/npm/p5@0.10.2/lib/p5.js"></script> -->
<script>
let faceapi;
let video;
let width = 640;
let height = 480;
let ctx;
let img;
// ficeapiのオプション設定
const detection_options = {
withLandmarks: true,
withDescriptors: false,
}
// メイン処理
async function make(){
img = new Image();
img.src = './heart.png';
video = await getVideo();
let canvas = createCanvas(width, height);
ctx = canvas.getContext('2d');
// faceapiモデルのオブジェクト生成
faceapi = await ml5.faceApi(video, detection_options, modelReady)
}
// DOMの読み込み
window.addEventListener('DOMContentLoaded', function() {
make();
});
// faceapiモデルの読み込み
function modelReady() {
console.log('ready!')
faceapi.detect(gotResults)
}
// faceAPI呼び出し関数
function gotResults(err, result) {
if (err) {
console.log(err)
return
}
// 自分の映像の情報を取得
let detections = result;
// 描画キャンパスを初期化
ctx.fillStyle = "#000000"
ctx.fillRect(0,0, width, height);
ctx.drawImage(video, 0,0, width, height);
// 自分の映像に描画する処理
if (detections) {
if(detections.length > 0){
drawLandmarks(detections)
}
}
// faceapiの再呼び出し
faceapi.detect(gotResults)
}
// faceapiで取得した目の位置を特定する処理
function drawLandmarks(detections){
for(let i = 0; i < detections.length; i++){
const leftEye = detections[i].parts.leftEye;
const rightEye = detections[i].parts.rightEye;
// 目に画像を描画
ctx.drawImage(img, leftEye[0].x -10, leftEye[0].y -25, 50, 50);
ctx.drawImage(img, rightEye[0].x -10, rightEye[0].y -25, 50, 50);
}
}
// Helper Functions
async function getVideo(){
// 要素の取得、設定の作成など
const videoElement = document.createElement('video');
videoElement.setAttribute("style", "display: none;");
videoElement.width = width;
videoElement.height = height;
document.body.appendChild(videoElement);
// Webカメラのキャプチャを作成
const capture = await navigator.mediaDevices.getUserMedia({ video: true })
videoElement.srcObject = capture;
videoElement.play();
return videoElement
}
// キャンパスの作成
function createCanvas(w, h){
const canvas = document.createElement("canvas");
canvas.width = w;
canvas.height = h;
document.body.appendChild(canvas);
return canvas;
}
</script>
</body>
</html>
#課題
・ボタンやアクションでハートだけじゃなく、色々なエフェクトを入れてみたかった。
・目の位置を取得しているが、少し無理やり画像の位置を決めてるので、少しズレたりする。
・首を傾けてもハート画像は傾かないので上手いことコントロールしたい。
今回使えてませんが、p5jsは極めれば、色々な描画が出来るようなので面白そう。中々奥が深いので今回はここまで。